Skip to content

Add a --pre flag to pyodide skeleton pypi - #439

Merged
agriyakhetarpal merged 1 commit into
pyodide:mainfrom
Thanatos9404:skeleton-prerelease-update
Oct 16, 2026
Merged

agriyakhetarpal merged 1 commit into
pyodide:mainfrom
Thanatos9404:skeleton-prerelease-update

Conversation

@Thanatos9404

Copy link
Copy Markdown
Contributor

Description

Fixes #373

Following the discussion on #373, this adds an explicit --pre flag to pyodide skeleton pypi, in the spirit of pip's --pre.

Without the flag nothing changes: the version comes from PyPI's info.version, which is the latest stable release whenever there is one. That is why a recipe on SciPy 1.18.0rc1 could not be updated while 1.17.1 was the latest stable release.

With --pre, the newest release in the project's releases (by PEP 440 ordering) is used instead when it is newer than info.version, so it can be an alpha, beta, release candidate or dev release. Releases that have no files or whose files are all yanked are skipped, as are versions that packaging cannot parse. When a newer release is picked, its metadata is fetched from /pypi/<name>/<version>/json, so the URL and sha256 come from that release. The flag works when creating a recipe and with --update, and has no effect when --version is given.

For the cases in the issue:

  • 1.2.3 with 1.2.4rc0 on PyPI: stays at 1.2.3 without --pre, goes to 1.2.4rc0 with it.
  • 1.2.4rc0 with 1.2.4rc1 and 1.2.4rc2 on PyPI: --pre goes to 1.2.4rc2.
  • 1.2.4rc0 once 1.2.5 is out: goes to 1.2.5, with or without --pre.
  • 1.2.4rc0 with 1.2.4rc2 yanked: --pre goes to 1.2.4rc1.
  • 1.2.4rc0 with both 1.2.4 and 1.3.0rc1 on PyPI: --pre goes to 1.3.0rc1, the newest release, as pip's --pre would. This differs from the second rule in the issue, which would stop at 1.2.4. Since the flag is explicit, I went with the pip behaviour (without --pre it goes to 1.2.4), but I can switch to preferring a newer stable release if you'd rather have that.

When the recipe is on a pre-release and --pre is not given, the "Local version ... is newer than PyPI version ..." error now ends with "Use --pre to include pre-releases." I can drop that if you would rather keep the message as it was.

Checklist

  • Add a CHANGELOG entry
  • Add / update tests
  • Add new / update outdated documentation (the --pre help text; the skeleton commands are not in the generated CLI reference)

New tests in tests/recipe/test_skeleton.py: test_update_package_pre (8 cases: the ones above plus PEP 440 ordering such as rc10 after rc9, alpha/beta/dev releases, and a recipe already on the newest release), test_update_package_pre_keeps_newer_info_version (--pre never picks a release older than info.version, and makes no second request when info.version is the newest), test_update_package_without_pre_skips_prereleases, test_update_package_prerelease_without_pre_suggests_pre, test_update_package_pre_explicit_version, test_make_package_pre and test_find_latest_version_skips_unusable_releases. In tests/test_cli.py, next to test_skeleton_pypi: test_skeleton_pypi_pre (3 cases). They use a stand-in for _get_metadata, like the existing update_package tests. On main, 18 of the 19 fail; test_update_package_without_pre_skips_prereleases passes there too and is there to keep the default behaviour.

I also ran pyodide skeleton pypi tornado --update against PyPI (prettier stubbed out). tornado's info.version is 6.5.10, and 6.6a1, 6.6b1 and 6.6rc1 are out:

  • a recipe on 6.6a1 still fails without --pre (now with the hint); with --pre it is updated to 6.6rc1, with the 6.6rc1 sdist URL and sha256;
  • a recipe on 6.5.9 is updated to 6.5.10 without --pre and to 6.6rc1 with it;
  • --pre --version 6.6b1 updates to 6.6b1.

Checks run locally:

  • pytest pyodide_build -m "not integration" on Python 3.13 (Ubuntu under WSL): 19 more tests pass than on main, and the same tests fail on both. Those are the skeleton tests that run npx prettier and three recipe build tests, which fail here because of my setup, and test_build_constraint (assert '84.0.0' == '74.1.3'), because uv does not apply the constraint to build requirements (see Pass uv environment variables to build requirement installs #438).
  • ruff check, ruff format (0.15.20, as pinned in pre-commit) and codespell on the changed files, and mypy 2.1.0 on the two changed modules: clean.

pyodide skeleton pypi --update compared the recipe version only with
PyPI's info.version, which is the latest stable release whenever one
exists. A recipe on a pre-release, such as SciPy 1.18.0rc1 while 1.17.1
was the latest stable release, could not be updated to a newer
pre-release and failed with "Local version ... is newer than PyPI
version ...".

Add a --pre flag, as in pip, to include pre-release and development
versions when looking for the latest version. The newest release in the
project's releases, skipping releases that have no files or whose files
are all yanked, is used when it is newer than info.version. The flag
applies when creating and when updating a recipe, and has no effect
when --version is given. Without --pre nothing changes, except that the
error above now suggests --pre when the recipe is on a pre-release.

Fixes pyodide#373
@Thanatos9404
Thanatos9404 force-pushed the skeleton-prerelease-update branch from f9f751e to 95a654a Compare October 16, 2026 09:58

@agriyakhetarpal agriyakhetarpal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relying on the pip semantics seems sensible to me. I found a few edge cases:

  • if we update to a pre-release and then it gets yanked on PyPI
  • if we have a local release that's at a later version than whatever release or pre-release is available on PyPI

but neither of those two are common enough cases for us to care about. The hint would be only slightly incorrect, which is fine.

Approving, thanks @Thanatos9404!

@agriyakhetarpal
agriyakhetarpal merged commit 45caaca into pyodide:main Oct 16, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

skeleton: allow updating non-stable releases for a package

2 participants