From 53188f9d580c664d8935c61dbb7b5d05472f2930 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Sun, 2 Nov 2025 18:17:41 +0100 Subject: [PATCH 1/3] [uuid] Replace properties with Final fields Add UUID.__setattr__ Closes: #14964 --- stdlib/uuid.pyi | 57 +++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/stdlib/uuid.pyi b/stdlib/uuid.pyi index 303fb10eaf53..cee34ab7ca26 100644 --- a/stdlib/uuid.pyi +++ b/stdlib/uuid.pyi @@ -1,7 +1,8 @@ import builtins import sys +from _typeshed import Unused from enum import Enum -from typing import Final +from typing import Final, NoReturn from typing_extensions import LiteralString, TypeAlias _FieldsType: TypeAlias = tuple[int, int, int, int, int, int] @@ -13,6 +14,25 @@ class SafeUUID(Enum): class UUID: __slots__ = ("int", "is_safe", "__weakref__") + + is_safe: Final[SafeUUID] + bytes: Final[builtins.bytes] + bytes_le: Final[builtins.bytes] + clock_seq: Final[builtins.int] + clock_seq_hi_variant: Final[builtins.int] + clock_seq_low: Final[builtins.int] + fields: Final[_FieldsType] + hex: Final[str] + int: Final[builtins.int] + node: Final[builtins.int] + time: Final[builtins.int] + time_hi_version: Final[builtins.int] + time_low: Final[builtins.int] + time_mid: Final[builtins.int] + urn: Final[str] + variant: Final[str] + version: Final[builtins.int | None] + def __init__( self, hex: str | None = None, @@ -24,40 +44,6 @@ class UUID: *, is_safe: SafeUUID = SafeUUID.unknown, ) -> None: ... - @property - def is_safe(self) -> SafeUUID: ... - @property - def bytes(self) -> builtins.bytes: ... - @property - def bytes_le(self) -> builtins.bytes: ... - @property - def clock_seq(self) -> builtins.int: ... - @property - def clock_seq_hi_variant(self) -> builtins.int: ... - @property - def clock_seq_low(self) -> builtins.int: ... - @property - def fields(self) -> _FieldsType: ... - @property - def hex(self) -> str: ... - @property - def int(self) -> builtins.int: ... - @property - def node(self) -> builtins.int: ... - @property - def time(self) -> builtins.int: ... - @property - def time_hi_version(self) -> builtins.int: ... - @property - def time_low(self) -> builtins.int: ... - @property - def time_mid(self) -> builtins.int: ... - @property - def urn(self) -> str: ... - @property - def variant(self) -> str: ... - @property - def version(self) -> builtins.int | None: ... def __int__(self) -> builtins.int: ... def __eq__(self, other: object) -> bool: ... def __lt__(self, other: UUID) -> bool: ... @@ -65,6 +51,7 @@ class UUID: def __gt__(self, other: UUID) -> bool: ... def __ge__(self, other: UUID) -> bool: ... def __hash__(self) -> builtins.int: ... + def __setattr__(self, name: Unused, value: Unused) -> NoReturn: ... def getnode() -> int: ... def uuid1(node: int | None = None, clock_seq: int | None = None) -> UUID: ... From 88bce2809f5a52ba4b1c1a83be7ae9c4e271ef23 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Sun, 2 Nov 2025 18:42:43 +0100 Subject: [PATCH 2/3] Add stubtest allowlist entries --- stdlib/@tests/stubtest_allowlists/common.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index d8956df6b327..d32038924063 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -527,6 +527,23 @@ urllib.response.addbase.write # Methods that come from __getattr__() at runtime urllib.response.addbase.writelines # Methods that come from __getattr__() at runtime unittest.mock.patch # function with attributes, which we approximate with a callable class +# stubtest doesn't understand that Final class attributes are also read-only. +uuid.UUID.bytes +uuid.UUID.bytes_le +uuid.UUID.clock_seq +uuid.UUID.clock_seq_hi_variant +uuid.UUID.clock_seq_low +uuid.UUID.fields +uuid.UUID.hex +uuid.UUID.node +uuid.UUID.time +uuid.UUID.time_hi_version +uuid.UUID.time_low +uuid.UUID.time_mid +uuid.UUID.urn +uuid.UUID.variant +uuid.UUID.version + _?weakref\.CallableProxyType\.__getattr__ # Should have all attributes of proxy _?weakref\.(ref|ReferenceType)\.__init__ # C implementation has incorrect signature _?weakref\.(ref|ReferenceType)\.__call__ # C function default annotation is wrong From 9d397e232fd35244d30e117081666216641fb527 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Wed, 5 Nov 2025 10:40:55 +0100 Subject: [PATCH 3/3] Restore UUID properties --- stdlib/@tests/stubtest_allowlists/common.txt | 17 -------- stdlib/uuid.pyi | 46 +++++++++++++------- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index d32038924063..d8956df6b327 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -527,23 +527,6 @@ urllib.response.addbase.write # Methods that come from __getattr__() at runtime urllib.response.addbase.writelines # Methods that come from __getattr__() at runtime unittest.mock.patch # function with attributes, which we approximate with a callable class -# stubtest doesn't understand that Final class attributes are also read-only. -uuid.UUID.bytes -uuid.UUID.bytes_le -uuid.UUID.clock_seq -uuid.UUID.clock_seq_hi_variant -uuid.UUID.clock_seq_low -uuid.UUID.fields -uuid.UUID.hex -uuid.UUID.node -uuid.UUID.time -uuid.UUID.time_hi_version -uuid.UUID.time_low -uuid.UUID.time_mid -uuid.UUID.urn -uuid.UUID.variant -uuid.UUID.version - _?weakref\.CallableProxyType\.__getattr__ # Should have all attributes of proxy _?weakref\.(ref|ReferenceType)\.__init__ # C implementation has incorrect signature _?weakref\.(ref|ReferenceType)\.__call__ # C function default annotation is wrong diff --git a/stdlib/uuid.pyi b/stdlib/uuid.pyi index cee34ab7ca26..055f4def311c 100644 --- a/stdlib/uuid.pyi +++ b/stdlib/uuid.pyi @@ -14,24 +14,8 @@ class SafeUUID(Enum): class UUID: __slots__ = ("int", "is_safe", "__weakref__") - is_safe: Final[SafeUUID] - bytes: Final[builtins.bytes] - bytes_le: Final[builtins.bytes] - clock_seq: Final[builtins.int] - clock_seq_hi_variant: Final[builtins.int] - clock_seq_low: Final[builtins.int] - fields: Final[_FieldsType] - hex: Final[str] int: Final[builtins.int] - node: Final[builtins.int] - time: Final[builtins.int] - time_hi_version: Final[builtins.int] - time_low: Final[builtins.int] - time_mid: Final[builtins.int] - urn: Final[str] - variant: Final[str] - version: Final[builtins.int | None] def __init__( self, @@ -44,6 +28,36 @@ class UUID: *, is_safe: SafeUUID = SafeUUID.unknown, ) -> None: ... + @property + def bytes(self) -> builtins.bytes: ... + @property + def bytes_le(self) -> builtins.bytes: ... + @property + def clock_seq(self) -> builtins.int: ... + @property + def clock_seq_hi_variant(self) -> builtins.int: ... + @property + def clock_seq_low(self) -> builtins.int: ... + @property + def fields(self) -> _FieldsType: ... + @property + def hex(self) -> str: ... + @property + def node(self) -> builtins.int: ... + @property + def time(self) -> builtins.int: ... + @property + def time_hi_version(self) -> builtins.int: ... + @property + def time_low(self) -> builtins.int: ... + @property + def time_mid(self) -> builtins.int: ... + @property + def urn(self) -> str: ... + @property + def variant(self) -> str: ... + @property + def version(self) -> builtins.int | None: ... def __int__(self) -> builtins.int: ... def __eq__(self, other: object) -> bool: ... def __lt__(self, other: UUID) -> bool: ...