Skip to content

Commit dfe9c2c

Browse files
authored
Make _Sentinel immutable (sphinx-doc#13782)
1 parent 1883c0d commit dfe9c2c

File tree

1 file changed

+42
-16
lines changed

1 file changed

+42
-16
lines changed

sphinx/ext/autodoc/_sentinels.py

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,40 @@
22

33
TYPE_CHECKING = False
44
if TYPE_CHECKING:
5-
from typing import NoReturn
5+
from typing import NoReturn, Self, _SpecialForm
66

77

88
class _Sentinel:
99
"""Create a unique sentinel object."""
1010

11-
def __init__(self, name: str, /) -> None:
12-
self._name = name
11+
__slots__ = ('_name',)
12+
13+
_name: str
14+
15+
def __new__(cls, name: str, /) -> Self:
16+
sentinel = super().__new__(cls)
17+
object.__setattr__(sentinel, '_name', str(name))
18+
return sentinel
1319

1420
def __repr__(self) -> str:
15-
return f'<{self._name}>'
21+
return self._name
22+
23+
def __setattr__(self, key: str, value: object) -> NoReturn:
24+
msg = f'{self._name} is immutable'
25+
raise AttributeError(msg)
1626

17-
def __or__(self, other: object) -> type[_Sentinel | object]:
18-
return self | other
27+
def __or__(self, other: object) -> _SpecialForm:
28+
from typing import Union
1929

20-
def __ror__(self, other: object) -> type[object | _Sentinel]:
21-
return other | self
30+
return Union[self, other] # NoQA: UP007
31+
32+
def __ror__(self, other: object) -> _SpecialForm:
33+
from typing import Union
34+
35+
return Union[other, self] # NoQA: UP007
2236

2337
def __getstate__(self) -> NoReturn:
24-
msg = f'Cannot pickle {type(self).__name__!r} object'
38+
msg = f'Cannot pickle {self._name}'
2539
raise TypeError(msg)
2640

2741

@@ -42,10 +56,22 @@ def __contains__(self, item: object) -> bool:
4256
return False
4357

4458

45-
ALL = _All('ALL')
46-
EMPTY = _Empty('EMPTY')
47-
UNINITIALIZED_ATTR = _Sentinel('UNINITIALIZED_ATTR')
48-
INSTANCE_ATTR = _Sentinel('INSTANCE_ATTR')
49-
SLOTS_ATTR = _Sentinel('SLOTS_ATTR')
50-
SUPPRESS = _Sentinel('SUPPRESS')
51-
RUNTIME_INSTANCE_ATTRIBUTE = _Sentinel('RUNTIME_INSTANCE_ATTRIBUTE')
59+
if TYPE_CHECKING:
60+
# For the sole purpose of satisfying the type checker.
61+
# fmt: off
62+
class ALL: ...
63+
class EMPTY: ...
64+
class INSTANCE_ATTR: ...
65+
class RUNTIME_INSTANCE_ATTRIBUTE: ...
66+
class SLOTS_ATTR: ...
67+
class SUPPRESS: ...
68+
class UNINITIALIZED_ATTR: ...
69+
# fmt: on
70+
else:
71+
ALL = _All('ALL')
72+
EMPTY = _Empty('EMPTY')
73+
INSTANCE_ATTR = _Sentinel('INSTANCE_ATTR')
74+
RUNTIME_INSTANCE_ATTRIBUTE = _Sentinel('RUNTIME_INSTANCE_ATTRIBUTE')
75+
SLOTS_ATTR = _Sentinel('SLOTS_ATTR')
76+
SUPPRESS = _Sentinel('SUPPRESS')
77+
UNINITIALIZED_ATTR = _Sentinel('UNINITIALIZED_ATTR')

0 commit comments

Comments
 (0)