Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions src/packaging/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
import typing
from typing import Any, Callable, Literal, SupportsInt, Tuple, TypedDict, Union

from ._structures import Infinity, InfinityType, NegativeInfinity, NegativeInfinityType
from ._structures import (Infinity, InfinityType, NegativeInfinity,
NegativeInfinityType)

if typing.TYPE_CHECKING:
from typing_extensions import Self, Unpack
Expand Down Expand Up @@ -318,16 +319,43 @@ def __init__(self, version: str) -> None:
self._key_cache = None

def __replace__(self, **kwargs: Unpack[_VersionReplace]) -> Self:
epoch = _validate_epoch(kwargs["epoch"]) if "epoch" in kwargs else self._epoch
release = (
_validate_release(kwargs["release"])
if "release" in kwargs
else self._release
)
pre = _validate_pre(kwargs["pre"]) if "pre" in kwargs else self._pre
post = _validate_post(kwargs["post"]) if "post" in kwargs else self._post
dev = _validate_dev(kwargs["dev"]) if "dev" in kwargs else self._dev
local = _validate_local(kwargs["local"]) if "local" in kwargs else self._local
# Fast path: if only local is being changed (common case in _public_version)
if len(kwargs) == 1 and "local" in kwargs:
new_local = _validate_local(kwargs["local"])
if new_local == self._local:
return self

new_version = self.__class__.__new__(self.__class__)
new_version._key_cache = None
new_version._epoch = self._epoch
new_version._release = self._release
new_version._pre = self._pre
new_version._post = self._post
new_version._dev = self._dev
new_version._local = new_local
return new_version

# General path: handle all possible parameters
epoch = self._epoch
release = self._release
pre = self._pre
post = self._post
dev = self._dev
local = self._local

if "epoch" in kwargs:
epoch = _validate_epoch(kwargs["epoch"])
if "release" in kwargs:
release = _validate_release(kwargs["release"])
if "pre" in kwargs:
pre = _validate_pre(kwargs["pre"])
if "post" in kwargs:
post = _validate_post(kwargs["post"])
if "dev" in kwargs:
dev = _validate_dev(kwargs["dev"])
if "local" in kwargs:
local = _validate_local(kwargs["local"])


if (
epoch == self._epoch
Expand Down