Skip to content

AttributeError: property '_key' of 'Version' object has no setter after upgrade to packaging 26.0 #3729

@lambda

Description

@lambda

Describe the bug

Our CI pipelines to check for updates to packages broke, because installing PDM pulled in a new packaging 26.0, which seems to be incompatible with PDM.

$ pdm update -v $EXTRA_PDM_UPDATE_ARGS --no-sync
WARNING: Project requires a python version of <3.14,>=3.12, The virtualenv is being created for you as it cannot be matched to the right version.
INFO: python.use_venv is on, creating a virtualenv for this project...
Run command: ['/usr/local/bin/python3.12', '-m', 'virtualenv', '/builds/software/py-beta-manufacturing-plans/.venv', '-p', '/usr/local/bin/python3.12', '--prompt=py-beta-manufacturing-plans-3.12', '--no-pip', '--no-setuptools', '--no-wheel']
The --no-wheel and --wheel options are deprecated. They have no effect for Python > 3.8 as wheel is no longer bundled in virtualenv.
created virtual environment CPython3.12.12.final.0-64 in 38ms
  creator CPython3Posix(dest=/builds/software/py-beta-manufacturing-plans/.venv, clear=False, no_vcs_ignore=False, global=False)
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
Virtualenv is created successfully at /builds/software/py-beta-manufacturing-plans/.venv
...
pdm.termui: Fetching hashes for python-jose@3.5.0
pdm.termui: Fetching hashes for rsa@4.9.1
pdm.termui: Fetching hashes for mkdocs-autorefs@1.4.3
pdm.termui: Fetching hashes for ecdsa@0.19.1
pdm.termui: Fetching hashes for py-beta-common@2.4.0
pdm.termui: Fetching hashes for mkdocstrings@1.0.1
pdm.termui: Fetching hashes for pyasn1@0.6.2
pdm.termui: Fetching hashes for bracex@2.6
pdm.termui: Fetching hashes for fonttools@4.61.1
pdm.termui: Fetching hashes for coverage@7.13.1
pdm.termui: Fetching hashes for coverage@7.13.1
Traceback (most recent call last):
  File "/usr/local/bin/pdm", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pdm/core.py", line 392, in main
    return core.main(args or sys.argv[1:])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pdm/core.py", line 270, in main
    raise cast(Exception, err).with_traceback(traceback) from None
  File "/usr/local/lib/python3.12/site-packages/pdm/core.py", line 265, in main
    self.handle(project, options)
  File "/usr/local/lib/python3.12/site-packages/pdm/core.py", line 195, in handle
    command.handle(project, options)
  File "/usr/local/lib/python3.12/site-packages/pdm/cli/commands/update.py", line 75, in handle
    self.do_update(
  File "/usr/local/lib/python3.12/site-packages/pdm/cli/commands/update.py", line 179, in do_update
    resolved = do_lock(
               ^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pdm/cli/actions.py", line 153, in do_lock
    data = result_repo.format_lockfile(groups=groups, strategy=lock_strategy)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pdm/models/repositories/lock.py", line 240, in format_lockfile
    base.update(entry.candidate.as_lockfile_entry(project.root))
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pdm/models/candidates.py", line 258, in as_lockfile_entry
    version = str(comparable_version(version))
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pdm/utils.py", line 353, in comparable_version
    parsed._key = _cmpkey(
    ^^^^^^^^^^^
AttributeError: property '_key' of 'Version' object has no setter

To reproduce

Haven't been able to repro it with a public package, but it looks like it's related to an internal package we have that has version number 3.15.1.dev1+g271bb71:

brcampbell@BETA-0661:~/tmp/pdm-test$ pdm add -v 'py-beta-cdk>=3.15.1.dev1+g271bb71'
/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/models/requirements.py:517: FutureWarning: Local version label can only be used with `==` or `!=` operators
  pkg_req = parse_as_pkg_requirement(line)
Adding packages to default dependencies: py-beta-cdk>=3.15.1.dev1
pdm.termui: ======== Start resolving requirements ========
pdm.termui:   py-beta-cdk>=3.15.1.dev1
pdm.termui:   Adding requirement python<3.14,>=3.12
pdm.termui:   Adding requirement py-beta-cdk>=3.15.1.dev1
...snip...
pdm.termui: ======== Resolution Result ========
pdm.termui:                                  python None
pdm.termui:                             py-beta-cdk 3.15.1.dev1+g271bb71
...snip...
pdm.termui: Fetching hashes for MarkupSafe@3.0.3
pdm.termui: Fetching hashes for mypy-extensions@1.1.0
Traceback (most recent call last):
  File "/home/brcampbell/.local/bin/pdm", line 7, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/core.py", line 391, in main
    return core.main(args or sys.argv[1:])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/core.py", line 270, in main
    raise cast(Exception, err).with_traceback(traceback) from None
  File "/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/core.py", line 265, in main
    self.handle(project, options)
  File "/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/core.py", line 195, in handle
    command.handle(project, options)
  File "/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/cli/commands/add.py", line 71, in handle
    self.do_add(
  File "/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/cli/commands/add.py", line 159, in do_add
    resolved = do_lock(
               ^^^^^^^^
  File "/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/cli/actions.py", line 166, in do_lock
    project.lockfile.format_lockfile(result_repo, groups=groups, strategy=lock_strategy)
  File "/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/project/lockfile/pdmlock.py", line 91, in format_lockfile
    base.update(entry.candidate.as_lockfile_entry(project.root))
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/models/candidates.py", line 267, in as_lockfile_entry
    version = str(comparable_version(version))
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/brcampbell/.local/pipx/venvs/pdm/lib/python3.12/site-packages/pdm/utils.py", line 354, in comparable_version
    parsed._key = _cmpkey(
    ^^^^^^^^^^^
AttributeError: property '_key' of 'Version' object has no setter

Expected Behavior

I expect to be able to add or update packages when this package is present in my dependency tree.

Environment Information

PDM version:
  2.26.5
Python Interpreter:
  /home/brcampbell/tmp/pdm-test/.venv/bin/python (3.12)
Project Root:
  /home/brcampbell/tmp/pdm-test
Local Packages:
  /home/brcampbell/tmp/pdm-test/.venv/lib/python3.12/site-packages
{
  "implementation_name": "cpython",
  "implementation_version": "3.12.3",
  "os_name": "posix",
  "platform_machine": "x86_64",
  "platform_release": "6.8.0-90-generic",
  "platform_system": "Linux",
  "platform_version": "#91-Ubuntu SMP PREEMPT_DYNAMIC Tue Nov 18 14:14:30 UTC 2025",
  "python_full_version": "3.12.3",
  "platform_python_implementation": "CPython",
  "python_version": "3.12",
  "sys_platform": "linux"
}

Verbose Command Output

Included above

Additional Context

packaging 26.0 has this in the release notes:

Lazily calculate _key in Version by @notatallshaw in pypa/packaging#989 and regression for packaging_legacy fixed by @henryiii in pypa/packaging#1048

Which replaces the _key attribute with a property that only has a getter: https://github.com/pypa/packaging/pull/989/files#diff-c588bfbc3b4ed422d8a41f9939cbfe1f4ecc79cf94625f68290a73ef2cb66333L228-R242

Are you willing to submit a PR to fix this bug?

  • Yes, I would like to submit a PR.

Metadata

Metadata

Assignees

Labels

🐛 bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions