Skip to content

Commit beedc1d

Browse files
AlexWaygoodAkuli
andauthored
Improve sys stubs (#6816)
Co-authored-by: Akuli <[email protected]>
1 parent 6ff9020 commit beedc1d

File tree

1 file changed

+132
-56
lines changed

1 file changed

+132
-56
lines changed

stdlib/sys.pyi

Lines changed: 132 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ displayhook: Callable[[object], Any]
3434
excepthook: Callable[[Type[BaseException], BaseException, TracebackType | None], Any]
3535
exec_prefix: str
3636
executable: str
37-
float_repr_style: str
37+
float_repr_style: Literal["short", "legacy"]
3838
hexversion: int
3939
last_type: Type[BaseException] | None
4040
last_value: BaseException | None
@@ -74,49 +74,105 @@ if sys.platform == "win32":
7474
winver: str
7575
_xoptions: dict[Any, Any]
7676

77+
# Type alias used as a mixin for structseq classes that cannot be instantiated at runtime
78+
# This can't be represented in the type system, so we just use `structseq[Any]`
79+
_uninstantiable_structseq = structseq[Any]
80+
7781
flags: _flags
7882

79-
class _flags:
80-
debug: int
81-
division_warning: int
82-
inspect: int
83-
interactive: int
84-
optimize: int
85-
dont_write_bytecode: int
86-
no_user_site: int
87-
no_site: int
88-
ignore_environment: int
89-
verbose: int
90-
bytes_warning: int
91-
quiet: int
92-
hash_randomization: int
83+
if sys.version_info >= (3, 10):
84+
_FlagTuple = tuple[int, int, int, int, int, int, int, int, int, int, int, int, int, bool, int, int]
85+
elif sys.version_info >= (3, 7):
86+
_FlagTuple = tuple[int, int, int, int, int, int, int, int, int, int, int, int, int, bool, int]
87+
else:
88+
_FlagTuple = tuple[int, int, int, int, int, int, int, int, int, int, int, int, int]
89+
90+
@final
91+
class _flags(_uninstantiable_structseq, _FlagTuple):
92+
@property
93+
def debug(self) -> int: ...
94+
@property
95+
def inspect(self) -> int: ...
96+
@property
97+
def interactive(self) -> int: ...
98+
@property
99+
def optimize(self) -> int: ...
100+
@property
101+
def dont_write_bytecode(self) -> int: ...
102+
@property
103+
def no_user_site(self) -> int: ...
104+
@property
105+
def no_site(self) -> int: ...
106+
@property
107+
def ignore_environment(self) -> int: ...
108+
@property
109+
def verbose(self) -> int: ...
110+
@property
111+
def bytes_warning(self) -> int: ...
112+
@property
113+
def quiet(self) -> int: ...
114+
@property
115+
def hash_randomization(self) -> int: ...
116+
@property
117+
def isolated(self) -> int: ...
93118
if sys.version_info >= (3, 7):
94-
dev_mode: int
95-
utf8_mode: int
119+
@property
120+
def dev_mode(self) -> bool: ...
121+
@property
122+
def utf8_mode(self) -> int: ...
123+
if sys.version_info >= (3, 10):
124+
@property
125+
def warn_default_encoding(self) -> int: ... # undocumented
96126

97127
float_info: _float_info
98128

99-
class _float_info:
100-
epsilon: float # DBL_EPSILON
101-
dig: int # DBL_DIG
102-
mant_dig: int # DBL_MANT_DIG
103-
max: float # DBL_MAX
104-
max_exp: int # DBL_MAX_EXP
105-
max_10_exp: int # DBL_MAX_10_EXP
106-
min: float # DBL_MIN
107-
min_exp: int # DBL_MIN_EXP
108-
min_10_exp: int # DBL_MIN_10_EXP
109-
radix: int # FLT_RADIX
110-
rounds: int # FLT_ROUNDS
129+
@final
130+
class _float_info(structseq[float], tuple[float, int, int, float, int, int, int, int, float, int, int]):
131+
@property
132+
def max(self) -> float: ... # DBL_MAX
133+
@property
134+
def max_exp(self) -> int: ... # DBL_MAX_EXP
135+
@property
136+
def max_10_exp(self) -> int: ... # DBL_MAX_10_EXP
137+
@property
138+
def min(self) -> float: ... # DBL_MIN
139+
@property
140+
def min_exp(self) -> int: ... # DBL_MIN_EXP
141+
@property
142+
def min_10_exp(self) -> int: ... # DBL_MIN_10_EXP
143+
@property
144+
def dig(self) -> int: ... # DBL_DIG
145+
@property
146+
def mant_dig(self) -> int: ... # DBL_MANT_DIG
147+
@property
148+
def epsilon(self) -> float: ... # DBL_EPSILON
149+
@property
150+
def radix(self) -> int: ... # FLT_RADIX
151+
@property
152+
def rounds(self) -> int: ... # FLT_ROUNDS
111153

112154
hash_info: _hash_info
113155

114-
class _hash_info:
115-
width: int
116-
modulus: int
117-
inf: int
118-
nan: int
119-
imag: int
156+
@final
157+
class _hash_info(structseq[Any | int], tuple[int, int, int, int, int, str, int, int, int]):
158+
@property
159+
def width(self) -> int: ...
160+
@property
161+
def modulus(self) -> int: ...
162+
@property
163+
def inf(self) -> int: ...
164+
@property
165+
def nan(self) -> int: ...
166+
@property
167+
def imag(self) -> int: ...
168+
@property
169+
def algorithm(self) -> str: ...
170+
@property
171+
def hash_bits(self) -> int: ...
172+
@property
173+
def seed_bits(self) -> int: ...
174+
@property
175+
def cutoff(self) -> int: ... # undocumented
120176

121177
implementation: _implementation
122178

@@ -125,16 +181,22 @@ class _implementation:
125181
version: _version_info
126182
hexversion: int
127183
cache_tag: str
128-
_multiarch: str
184+
# Define __getattr__, as the documentation states:
185+
# > sys.implementation may contain additional attributes specific to the Python implementation.
186+
# > These non-standard attributes must start with an underscore, and are not described here.
187+
def __getattr__(self, name: str) -> Any: ...
129188

130189
int_info: _int_info
131190

132-
class _int_info:
133-
bits_per_digit: int
134-
sizeof_digit: int
191+
@final
192+
class _int_info(structseq[int], tuple[int, int]):
193+
@property
194+
def bits_per_digit(self) -> int: ...
195+
@property
196+
def sizeof_digit(self) -> int: ...
135197

136198
@final
137-
class _version_info(structseq[Any | int], tuple[int, int, int, str, int]):
199+
class _version_info(_uninstantiable_structseq, tuple[int, int, int, str, int]):
138200
@property
139201
def major(self) -> int: ...
140202
@property
@@ -185,19 +247,30 @@ _TraceFunc = Callable[[FrameType, str, Any], Optional[Callable[[FrameType, str,
185247
def gettrace() -> _TraceFunc | None: ...
186248
def settrace(tracefunc: _TraceFunc | None) -> None: ...
187249

188-
class _WinVersion(tuple[int, int, int, int, str, int, int, int, int, tuple[int, int, int]]):
189-
major: int
190-
minor: int
191-
build: int
192-
platform: int
193-
service_pack: str
194-
service_pack_minor: int
195-
service_pack_major: int
196-
suite_mast: int
197-
product_type: int
198-
platform_version: tuple[int, int, int]
199-
200250
if sys.platform == "win32":
251+
# A tuple of length 5, even though it has more than 5 attributes.
252+
@final
253+
class _WinVersion(_uninstantiable_structseq, tuple[int, int, int, int, str]):
254+
@property
255+
def major(self) -> int: ...
256+
@property
257+
def minor(self) -> int: ...
258+
@property
259+
def build(self) -> int: ...
260+
@property
261+
def platform(self) -> int: ...
262+
@property
263+
def service_pack(self) -> str: ...
264+
@property
265+
def service_pack_minor(self) -> int: ...
266+
@property
267+
def service_pack_major(self) -> int: ...
268+
@property
269+
def suite_mask(self) -> int: ...
270+
@property
271+
def product_type(self) -> int: ...
272+
@property
273+
def platform_version(self) -> tuple[int, int, int]: ...
201274
def getwindowsversion() -> _WinVersion: ...
202275

203276
def intern(__string: str) -> str: ...
@@ -219,7 +292,7 @@ if sys.version_info < (3, 9):
219292
def setcheckinterval(__n: int) -> None: ... # deprecated
220293

221294
if sys.version_info >= (3, 8):
222-
# not exported by sys
295+
# Doesn't exist at runtime, but exported in the stubs so pytest etc. can annotate their code more easily.
223296
class UnraisableHookArgs:
224297
exc_type: Type[BaseException]
225298
exc_value: BaseException | None
@@ -232,9 +305,12 @@ if sys.version_info >= (3, 8):
232305

233306
_AsyncgenHook = Optional[Callable[[AsyncGenerator[Any, Any]], None]]
234307

235-
class _asyncgen_hooks(tuple[_AsyncgenHook, _AsyncgenHook]):
236-
firstiter: _AsyncgenHook
237-
finalizer: _AsyncgenHook
308+
@final
309+
class _asyncgen_hooks(structseq[_AsyncgenHook], tuple[_AsyncgenHook, _AsyncgenHook]):
310+
@property
311+
def firstiter(self) -> _AsyncgenHook: ...
312+
@property
313+
def finalizer(self) -> _AsyncgenHook: ...
238314

239315
def get_asyncgen_hooks() -> _asyncgen_hooks: ...
240316
def set_asyncgen_hooks(firstiter: _AsyncgenHook = ..., finalizer: _AsyncgenHook = ...) -> None: ...

0 commit comments

Comments
 (0)