{"id":245,"library":"packaging","title":"packaging","description":"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).","status":"active","version":"26.0","language":"python","source_language":"en","source_url":"https://github.com/pypa/packaging","tags":["packaging","pypa","pep440","version","specifier","requirements","markers","pip","python"],"install":[{"cmd":"pip install packaging","lang":"bash","label":"Python"}],"dependencies":[],"imports":[{"note":"LegacyVersion was removed in 22.0. Version() now raises InvalidVersion for non-PEP 440 strings instead of returning a LegacyVersion.","wrong":"from packaging.version import LegacyVersion","symbol":"Version","correct":"from packaging.version import Version"},{"note":"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.","wrong":"v = parse('1.0'); type(v) == LegacyVersion","symbol":"parse","correct":"from packaging.version import Version, parse"},{"note":"Specifier support was moved out of packaging.version into packaging.specifiers in an early breaking release. Always import from packaging.specifiers.","wrong":"from packaging.version import SpecifierSet","symbol":"SpecifierSet","correct":"from packaging.specifiers import SpecifierSet"},{"symbol":"Requirement","correct":"from packaging.requirements import Requirement"},{"note":"Returns NormalizedName (a NewType of str). Useful for reliable package name comparison. Pass validate=True to also reject invalid distribution names.","symbol":"canonicalize_name","correct":"from packaging.utils import canonicalize_name"},{"symbol":"Marker","correct":"from packaging.markers import Marker"}],"quickstart":{"code":"from packaging.version import Version\nfrom packaging.specifiers import SpecifierSet\nfrom packaging.requirements import Requirement\nfrom packaging.utils import canonicalize_name\n\n# Parse and compare PEP 440 versions\nv = Version('1.2.3')\nprint(v.major, v.minor, v.micro)  # 1 2 3\nprint(v.is_prerelease)             # False\n\n# Check if a version satisfies a specifier\nspec = SpecifierSet('>=1.0,<2.0')\nprint(v in spec)                   # True\n\n# Parse a PEP 508 requirement string\nreq = Requirement('requests[security]>=2.28; python_version>=\"3.8\"')\nprint(req.name)      # requests\nprint(req.extras)    # {'security'}\nprint(req.specifier) # >=2.28\nprint(req.marker)    # python_version >= \"3.8\"\n\n# Normalize a package name (PEP 503)\nprint(canonicalize_name('Django'))          # django\nprint(canonicalize_name('oslo.concurrency')) # oslo-concurrency","lang":"python","description":"Core usage of packaging 26.x: version parsing, specifier matching, requirement parsing, and name canonicalization."},"warnings":[{"fix":"Wrap Version() / parse() calls in a try/except InvalidVersion block. Migrate any non-PEP 440 version strings to compliant ones.","message":"LegacyVersion and LegacySpecifier were removed in 22.0. packaging.version.parse() now raises InvalidVersion for non-PEP 440 version strings instead of silently returning a LegacyVersion object.","severity":"breaking","affected_versions":"< 22.0"},{"fix":"Use: from packaging.specifiers import SpecifierSet, Specifier","message":"SpecifierSet and Specifier were moved from packaging.version to packaging.specifiers in an early release. Importing from packaging.version will fail.","severity":"breaking","affected_versions":"all"},{"fix":"Guard attribute access with `if metadata.summary is not None` rather than truthiness checks.","message":"Optional metadata.Metadata attributes now default to None (changed in 24.0). Code checking for empty-string defaults will silently mishandle absent fields.","severity":"breaking","affected_versions":"< 24.0"},{"fix":"spec.filter(versions, prereleases=True) or SpecifierSet('>=1.0', prereleases=True)","message":"SpecifierSet.filter() and Specifier.contains() exclude pre-releases by default unless the specifier itself includes a pre-release version. Pass prereleases=True explicitly to include them.","severity":"gotcha","affected_versions":"all"},{"fix":"Compare only after canonicalization: canonicalize_name(a) == canonicalize_name(b)","message":"canonicalize_name() returns a NormalizedName (typing.NewType of str). Mixing raw strings and NormalizedName values causes mypy errors. Always canonicalize before comparing package names.","severity":"gotcha","affected_versions":"all"},{"fix":"Pin to an exact version in production tooling, e.g. packaging==26.0, and review the changelog on each upgrade.","message":"The library uses calendar versioning (YY.N), not semver. There is no reliable way to determine whether a release contains breaking changes from the version number alone.","severity":"gotcha","affected_versions":"all"},{"fix":"No extra dependencies needed. Just pip install packaging.","message":"packaging has no runtime dependencies since 21.0 (pyparsing was removed and replaced with a hand-written parser). Do not add pyparsing as a workaround for older compatibility issues.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T12:18:22.966Z","next_check":"2026-06-25T00:00:00.000Z","problems":[{"fix":"pip install packaging","cause":"The 'packaging' library is not installed in your current Python environment.","error":"ModuleNotFoundError: No module named 'packaging'"},{"fix":"Ensure the version string follows PEP 440 (e.g., '1.0', '1.0.post1', '1.0a1') or handle non-compliant versions gracefully in your code.","cause":"The version string provided does not conform to the PEP 440 versioning scheme, which the 'packaging' library strictly enforces.","error":"packaging.version.InvalidVersion: Invalid version: '...' (e.g., 'Invalid version: 'french toast'')"},{"fix":"Downgrade 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`.","cause":"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.","error":"AttributeError: module 'packaging.version' has no attribute 'LegacyVersion'"},{"fix":"Correct 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\"'.","cause":"The requirement string provided to `packaging.requirements.Requirement` is malformed and does not adhere to the PEP 508 specification for dependency specifiers.","error":"packaging.requirements.InvalidRequirement: Parse error at \"': ...'\": Expected stringEnd"},{"fix":"Provide a valid version specifier string, such as '==1.0', '>=1.0,<2.0', '~=1.0.0', or '!=1.1'.","cause":"The specifier string provided to `packaging.specifiers.Specifier` or `SpecifierSet` is syntactically incorrect and does not conform to PEP 440's specifier format.","error":"packaging.specifiers.InvalidSpecifier: Invalid specifier: '...' (e.g., 'Invalid specifier: 'lolwat'')"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"18.3M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":0.8,"disk_size":"20.2M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":0.8,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":0.7,"disk_size":"12.1M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":0.7,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":1.9,"disk_size":"11.7M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":1.7,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"17.8M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}