Jim Crist-Harif

TIL: How to mark a package as broken on PyPI & Conda-Forge

Posted on February 10, 2023

It finally happened: I released a critically broken package (msgspec 0.13.0) to PyPI and Conda-Forge. Mistakes happen, and a patch release was pushed up within 24 hours, but I still wanted to prevent users from accidentally installing the broken package.

In these situations, neither PyPI nor conda-forge recommend (or support) deleting the release. Rather they have their own mechanisms for marking a release as "broken" so users will only end up with that version if they've pinned specifically to that version.

PyPI

For PyPI you'll want to "yank" the release. This may be done through the admin page on PyPI for your project. Click the "Option" dropdown next to the faulty release, then click "Yank".

Yanking a release removes that release from PyPI's UI. pip and other tools will also avoid installing yanked releases unless the user has explicitly pinned to that version.

# won't get the yanked release
$ pip install msgspec

# will get the yanked release, since they've pinned to that version
$ pip install msgspec=0.13.0

Conda-Forge

For Conda-Forge the process is a bit more involved, but has the same end effect. Following the instructions from the official conda-forge docs:

import requests

package = "msgspec"
version = "0.13.0"

resp = requests.get(f"https://api.anaconda.org/release/conda-forge/{package}/{version}")
for dist in resp.json()["distributions"]:
    print(dist["basename"])
linux-64/msgspec-0.13.0-py310h1fa729e_0.conda
linux-64/msgspec-0.13.0-py311h2582759_0.conda
linux-64/msgspec-0.13.0-py38h1de0b5d_0.conda
linux-64/msgspec-0.13.0-py39h72bdee0_0.conda
linux-aarch64/msgspec-0.13.0-py310hb89b984_0.conda
linux-aarch64/msgspec-0.13.0-py311h1d6c08a_0.conda
linux-aarch64/msgspec-0.13.0-py38hda48048_0.conda
linux-aarch64/msgspec-0.13.0-py39h24fc6b6_0.conda
linux-ppc64le/msgspec-0.13.0-py310h82c586f_0.conda
linux-ppc64le/msgspec-0.13.0-py311h57b9580_0.conda
linux-ppc64le/msgspec-0.13.0-py38h0c7bae7_0.conda
linux-ppc64le/msgspec-0.13.0-py39h38a9e30_0.conda
osx-64/msgspec-0.13.0-py310h90acd4f_0.conda
osx-64/msgspec-0.13.0-py311h5547dcb_0.conda
osx-64/msgspec-0.13.0-py38hef030d1_0.conda
osx-64/msgspec-0.13.0-py39ha30fb19_0.conda
osx-arm64/msgspec-0.13.0-py310h8e9501a_0.conda
osx-arm64/msgspec-0.13.0-py311he2be06e_0.conda
osx-arm64/msgspec-0.13.0-py38hb991d35_0.conda
osx-arm64/msgspec-0.13.0-py39h02fc5c5_0.conda
win-64/msgspec-0.13.0-py310h8d17308_0.conda
win-64/msgspec-0.13.0-py311ha68e1ae_0.conda
win-64/msgspec-0.13.0-py38h91455d4_0.conda
win-64/msgspec-0.13.0-py39ha55989b_0.conda