Reusable core utilities for Python packaging interoperability specifications. Implements PEP 440 version handling, specifiers, markers, requirements, tags, metadata, and lockfiles. Used internally by pip, setuptools, and most build tools. Uses calendar-based versioning (YY.N). Current version is 26.0 (2026).
Install & Compatibility
Where this runs
tested against v26.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.925 runs
installs and imports cleanly · install 0.0s · import 0.026s · 18.5MB
glibcpy 3.10–3.925 runs
installs and imports cleanly · install 1.6s · import 0.023s · 19MB
17MB installed
● package 17MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Version
✓ from packaging.version import Version
✗ from packaging.version import LegacyVersion
LegacyVersion was removed in 22.0. Version() now raises InvalidVersion for non-PEP 440 strings instead of returning a LegacyVersion.
parse
✓ from packaging.version import Version, parse
✗ v = parse('1.0'); type(v) == LegacyVersion
In <22.0, parse() could return LegacyVersion for invalid versions. Since 22.0, parse() raises InvalidVersion for non-PEP 440 strings — it no longer silently returns a LegacyVersion.
SpecifierSet
✓ from packaging.specifiers import SpecifierSet
✗ from packaging.version import SpecifierSet
Specifier support was moved out of packaging.version into packaging.specifiers in an early breaking release. Always import from packaging.specifiers.
Requirement
✓ from packaging.requirements import Requirement
canonicalize_name
✓ from packaging.utils import canonicalize_name
Returns NormalizedName (a NewType of str). Useful for reliable package name comparison. Pass validate=True to also reject invalid distribution names.
Marker
✓ from packaging.markers import Marker
Core usage of packaging 26.x: version parsing, specifier matching, requirement parsing, and name canonicalization.
from packaging.version import Version
from packaging.specifiers import SpecifierSet
from packaging.requirements import Requirement
from packaging.utils import canonicalize_name
# Parse and compare PEP 440 versions
v = Version('1.2.3')
print(v.major, v.minor, v.micro) # 1 2 3
print(v.is_prerelease) # False
# Check if a version satisfies a specifier
spec = SpecifierSet('>=1.0,<2.0')
print(v in spec) # True
# Parse a PEP 508 requirement string
req = Requirement('requests[security]>=2.28; python_version>="3.8"')
print(req.name) # requests
print(req.extras) # {'security'}
print(req.specifier) # >=2.28
print(req.marker) # python_version >= "3.8"
# Normalize a package name (PEP 503)
print(canonicalize_name('Django')) # django
print(canonicalize_name('oslo.concurrency')) # oslo-concurrency
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'packaging'
The 'packaging' library is not installed in your current Python environment.
packaging.version.InvalidVersion: Invalid version: '...' (e.g., 'Invalid version: 'french toast'')
The version string provided does not conform to the PEP 440 versioning scheme, which the 'packaging' library strictly enforces.
fixEnsure the version string follows PEP 440 (e.g., '1.0', '1.0.post1', '1.0a1') or handle non-compliant versions gracefully in your code.
AttributeError: module 'packaging.version' has no attribute 'LegacyVersion'
The 'LegacyVersion' class was removed in 'packaging' version 22.0. This error occurs when older code or dependencies attempt to access it with a newer 'packaging' installation.
fixDowngrade the 'packaging' library to a compatible version (e.g., `pip install 'packaging<22.0'`) or update the dependent code to use `packaging.version.Version` and handle non-PEP 440 versions appropriately without `LegacyVersion`.
packaging.requirements.InvalidRequirement: Parse error at "': ...'": Expected stringEnd
The requirement string provided to `packaging.requirements.Requirement` is malformed and does not adhere to the PEP 508 specification for dependency specifiers.
fixCorrect the requirement string syntax. Ensure it follows the format 'package_name[extra] (specifier); marker', for example, 'my-package[test]>=1.0; python_version < "3.9"'.
packaging.specifiers.InvalidSpecifier: Invalid specifier: '...' (e.g., 'Invalid specifier: 'lolwat'')
The specifier string provided to `packaging.specifiers.Specifier` or `SpecifierSet` is syntactically incorrect and does not conform to PEP 440's specifier format.
fixProvide a valid version specifier string, such as '==1.0', '>=1.0,<2.0', '~=1.0.0', or '!=1.1'.
Audit
Dependencies
No dependency data recorded yet.