diff --git a/src/pdm/pytest.py b/src/pdm/pytest.py index e7a51ce710..287be9aafd 100644 --- a/src/pdm/pytest.py +++ b/src/pdm/pytest.py @@ -653,6 +653,10 @@ def caller( os.environ.update(old_env) if cleanup: core.exit_stack.close() + # Clear the build directory cache to avoid stale references + from pdm.models.candidates import PreparedCandidate + + PreparedCandidate._build_dir_cache.clear() result = RunResult(exit_code, stdout.getvalue(), stderr.getvalue(), exception) diff --git a/src/pdm/utils.py b/src/pdm/utils.py index da18240163..b0ae6a747a 100644 --- a/src/pdm/utils.py +++ b/src/pdm/utils.py @@ -352,17 +352,27 @@ def comparable_version(version: str) -> Version: if hasattr(parsed, "__replace__"): # packaging >= 26 parsed = parsed.__replace__(local=None) else: + # packaging < 26 does not have __replace__ method + # In this version, we need to manually update _version and recompute _key + # Note: In packaging >= 26, _key is a read-only property, but this else branch + # only executes on packaging < 26 where _key is a regular attribute that can be + # assigned. We use object.__setattr__() instead of direct assignment to satisfy + # type checkers that analyze based on the current packaging version. from packaging.version import _cmpkey parsed._version = parsed._version._replace(local=None) - parsed._key = _cmpkey( - parsed._version.epoch, - parsed._version.release, - parsed._version.pre, - parsed._version.post, - parsed._version.dev, - parsed._version.local, + object.__setattr__( + parsed, + "_key", + _cmpkey( + parsed._version.epoch, + parsed._version.release, + parsed._version.pre, + parsed._version.post, + parsed._version.dev, + parsed._version.local, + ), ) return parsed