Announcement: packaging 26.1/26.2 released!

Announcing packaging 26.1/2

I’m pleased to announce that packaging 26.1 and 26.2 have been released! Today’s release of pip 26.1 uses several of our new features. These are the last releases to support Python 3.8 (we are a smidge behind in dropping Python versions!). This release pair adds up to 2x faster performance, on top of the 3-5x in the last release (26.0). Some behavior has been adjusted to better match standards.

New PEPs supported and modules include:

  • PEP 783: PyEmscripten wheels (packaging 26.2 fixes this)
  • PEP 803: Free-threading stable ABI tag (used in pip 26.1)
  • PEP 723: packaging.dependency_groups (used in pip 26.1)
  • packaging.direct_url (used in pip 26.1)
  • packaging.errors

Other new features:

  • SpecifierSet
    • .is_unsatisfiable - the first feature of a new range-based implementation
    • .filter(key=…) - simpler and faster than using contains twice (used in pip 26.1)
  • Expanded lock file support including .select() - powering pip 26.1’s -r pylock.toml feature
  • Main classes are have a stable (and faster) pickle format, and we support older pickles for now, too (packaging 26.2)
  • Markers support & and | (more features coming after a standards issue is resolved in a future version)
  • Version
    • .from_parts() (and __replace__ now normalizes)
  • Utils
    • parse_wheel_filename has validation option (new module coming in a future version)

Advanced internals and developer features:

  • Improved tab completion in REPL
  • Integrated benchmarking suite (based on the one used in How we made Python's packaging library 3x faster - for 26.0)
  • Property based tests
  • Downstream tests (pip, setup tools, build, pyproject-metadata, and packaging_legacy included for now)

See all the changes in Changelog - Packaging

Thanks to everyone that made this release(s) possible!

(26.2 fixed a bad config variable in the pyemscripten support, and added the stable pickle implementation, as 26.1 couldn’t be used on pickles from earlier versions)

7 Likes

If anyone finds SpecifierSet.is_unsatisfiable useful it’d be great to hear back, it was a lengthy exercise identifying and understanding all the edge cases.

And for those who love a PEP 440 challenge, try and figure out why this specifier set is satisfiable:

>>> SpecifierSet(">1.0a1,<1.0a2").is_unsatisfiable()
False
1 Like