Skip to content

Commit bd2d6f6

Browse files
authored
Update/regenerate various ruff_python_stdlib APIs (#25273)
## Summary 1. Manually update various functions in `crates/ruff_python_stdlib/src/builtins.rs` to reflect new APIs added in Python 3.15. 2. Manually remove the incorrect inclusion of `frozenset` from `is_immutable_non_generic_type` in `crates/ruff_python_stdlib/src/typing.rs`. `frozenset` is a generic type. 3. Manually add `frozendict` to `is_immutable_generic_type` and `is_immutable_return_type` in `crates/ruff_python_stdlib/src/typing.rs` 4. Manually updates to `scripts/generate_builtin_modules.py`: use uv to invoke Python rather than relying on many different Python versions all being on `PATH`, drop support for Python 3.7 from the script (it can't be installed using uv), and apply various other simplifications. 5. Regenerate `is_builtin_module` in `crates/ruff_python_stdlib/src/sys/builtin_modules.rs` following the changes made in (4). Note that switching to uv-managed Python installs (PBS) appears to mean that quite a few more stdlib modules are recognised as being builtin modules, which is interesting. I also ran `scripts/generate_known_standard_library.py`, but it didn't make any changes to the Rust function generated by that script. ## Test Plan `cargo test`
1 parent 4bae734 commit bd2d6f6

6 files changed

Lines changed: 199 additions & 64 deletions

File tree

.github/workflows/ty-ecosystem-analyzer.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ on:
1414
- "crates/ruff_db"
1515
- "crates/ruff_python_ast"
1616
- "crates/ruff_python_parser"
17+
- "crates/ruff_python_stdlib"
1718
- ".github/workflows/ty-ecosystem-analyzer.yaml"
1819
- ".github/ty-ecosystem.toml"
1920
- "crates/ty_python_semantic/resources/primer/**"

crates/ruff_python_stdlib/src/builtins.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,12 @@ static ALWAYS_AVAILABLE_BUILTINS: &[&str] = &[
186186
static PY310_PLUS_BUILTINS: &[&str] = &["EncodingWarning", "aiter", "anext"];
187187
static PY311_PLUS_BUILTINS: &[&str] = &["BaseExceptionGroup", "ExceptionGroup"];
188188
static PY313_PLUS_BUILTINS: &[&str] = &["PythonFinalizationError"];
189-
static PY315_PLUS_BUILTINS: &[&str] = &["frozendict"];
189+
static PY315_PLUS_BUILTINS: &[&str] = &[
190+
"frozendict",
191+
"sentinel",
192+
"__lazy_import__",
193+
"ImportCycleError",
194+
];
190195

191196
/// Return the list of builtins for the given Python minor version.
192197
///
@@ -410,7 +415,10 @@ pub fn is_python_builtin(name: &str, minor_version: u8, is_notebook: bool) -> bo
410415
) | (10.., "EncodingWarning" | "aiter" | "anext")
411416
| (11.., "BaseExceptionGroup" | "ExceptionGroup")
412417
| (13.., "PythonFinalizationError")
413-
| (15.., "frozendict")
418+
| (
419+
15..,
420+
"frozendict" | "sentinel" | "__lazy_import__" | "ImportCycleError"
421+
)
414422
)
415423
}
416424

@@ -522,6 +530,6 @@ pub fn is_exception(name: &str, minor_version: u8) -> bool {
522530
| "UserWarning"
523531
) | (10.., "EncodingWarning")
524532
| (11.., "BaseExceptionGroup" | "ExceptionGroup")
525-
| (13.., "PythonFinalizationError")
533+
| (13.., "PythonFinalizationError" | "ImportCycleError")
526534
)
527535
}

crates/ruff_python_stdlib/src/sys/builtin_modules.rs

Lines changed: 144 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,47 +9,183 @@
99
/// modules.
1010
///
1111
/// [builtin module]: https://docs.python.org/3/library/sys.html#sys.builtin_module_names
12-
#[expect(clippy::unnested_or_patterns)]
12+
#[allow(clippy::unnested_or_patterns)]
1313
pub fn is_builtin_module(minor_version: u8, module: &str) -> bool {
1414
matches!(
1515
(minor_version, module),
1616
(
1717
_,
1818
"_abc"
1919
| "_ast"
20+
| "_asyncio"
21+
| "_bisect"
22+
| "_blake2"
23+
| "_bz2"
2024
| "_codecs"
25+
| "_codecs_cn"
26+
| "_codecs_hk"
27+
| "_codecs_iso2022"
28+
| "_codecs_jp"
29+
| "_codecs_kr"
30+
| "_codecs_tw"
2131
| "_collections"
32+
| "_contextvars"
33+
| "_csv"
34+
| "_ctypes"
35+
| "_curses"
36+
| "_curses_panel"
37+
| "_datetime"
38+
| "_decimal"
39+
| "_elementtree"
2240
| "_functools"
41+
| "_hashlib"
42+
| "_heapq"
2343
| "_imp"
2444
| "_io"
45+
| "_json"
2546
| "_locale"
47+
| "_lsprof"
48+
| "_lzma"
49+
| "_md5"
50+
| "_multibytecodec"
51+
| "_multiprocessing"
52+
| "_opcode"
2653
| "_operator"
54+
| "_pickle"
55+
| "_posixshmem"
56+
| "_posixsubprocess"
57+
| "_queue"
58+
| "_random"
59+
| "_scproxy"
60+
| "_sha1"
61+
| "_sha3"
2762
| "_signal"
63+
| "_socket"
64+
| "_sqlite3"
2865
| "_sre"
66+
| "_ssl"
2967
| "_stat"
68+
| "_statistics"
3069
| "_string"
70+
| "_struct"
3171
| "_symtable"
72+
| "_testinternalcapi"
3273
| "_thread"
3374
| "_tracemalloc"
75+
| "_uuid"
3476
| "_warnings"
3577
| "_weakref"
78+
| "array"
3679
| "atexit"
80+
| "binascii"
3781
| "builtins"
82+
| "cmath"
3883
| "errno"
3984
| "faulthandler"
85+
| "fcntl"
4086
| "gc"
87+
| "grp"
4188
| "itertools"
4289
| "marshal"
90+
| "math"
91+
| "mmap"
4392
| "posix"
4493
| "pwd"
94+
| "pyexpat"
95+
| "readline"
96+
| "resource"
97+
| "select"
4598
| "sys"
99+
| "syslog"
100+
| "termios"
46101
| "time"
47-
) | (7, "xxsubtype" | "zipimport")
48-
| (8, "xxsubtype")
49-
| (9, "_peg_parser" | "xxsubtype")
50-
| (10, "xxsubtype")
51-
| (11, "_tokenize" | "xxsubtype")
52-
| (12, "_tokenize" | "_typing")
53-
| (13, "_suggestions" | "_sysconfig" | "_tokenize" | "_typing")
102+
| "unicodedata"
103+
| "xxsubtype"
104+
| "zlib"
105+
) | (
106+
8,
107+
"_ctypes_test" | "_dbm" | "_sha256" | "_sha512" | "_tkinter" | "audioop" | "parser"
108+
) | (
109+
9,
110+
"_peg_parser"
111+
| "_sha256"
112+
| "_sha512"
113+
| "_testbuffer"
114+
| "_testimportmultiple"
115+
| "_testmultiphase"
116+
| "_xxsubinterpreters"
117+
| "_xxtestfuzz"
118+
| "_zoneinfo"
119+
| "audioop"
120+
| "parser"
121+
) | (
122+
10,
123+
"_sha256" | "_sha512" | "_xxsubinterpreters" | "_xxtestfuzz" | "_zoneinfo" | "audioop"
124+
) | (
125+
11,
126+
"_sha256"
127+
| "_sha512"
128+
| "_tokenize"
129+
| "_typing"
130+
| "_xxsubinterpreters"
131+
| "_xxtestfuzz"
132+
| "_zoneinfo"
133+
| "audioop"
134+
) | (
135+
12,
136+
"_sha2"
137+
| "_tokenize"
138+
| "_typing"
139+
| "_xxinterpchannels"
140+
| "_xxsubinterpreters"
141+
| "_xxtestfuzz"
142+
| "_zoneinfo"
143+
| "audioop"
144+
) | (
145+
13,
146+
"_interpchannels"
147+
| "_interpqueues"
148+
| "_interpreters"
149+
| "_sha2"
150+
| "_suggestions"
151+
| "_sysconfig"
152+
| "_tokenize"
153+
| "_typing"
154+
| "_xxtestfuzz"
155+
| "_zoneinfo"
156+
) | (
157+
14,
158+
"_hmac"
159+
| "_interpchannels"
160+
| "_interpqueues"
161+
| "_interpreters"
162+
| "_remote_debugging"
163+
| "_sha2"
164+
| "_suggestions"
165+
| "_sysconfig"
166+
| "_tokenize"
167+
| "_types"
168+
| "_typing"
169+
| "_xxtestfuzz"
170+
| "_zoneinfo"
171+
| "_zstd"
172+
) | (
173+
15,
174+
"_hmac"
175+
| "_interpchannels"
176+
| "_interpqueues"
177+
| "_interpreters"
178+
| "_math_integer"
179+
| "_remote_debugging"
180+
| "_sha2"
181+
| "_suggestions"
182+
| "_sysconfig"
183+
| "_tokenize"
184+
| "_types"
185+
| "_typing"
186+
| "_xxtestfuzz"
187+
| "_zoneinfo"
188+
| "_zstd"
189+
)
54190
)
55191
}

crates/ruff_python_stdlib/src/typing.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -246,15 +246,7 @@ pub fn is_immutable_non_generic_type(qualified_name: &[&str]) -> bool {
246246
| ["typing", "LiteralString" | "Sized"]
247247
| [
248248
"",
249-
"bool"
250-
| "bytes"
251-
| "complex"
252-
| "float"
253-
| "frozenset"
254-
| "int"
255-
| "object"
256-
| "range"
257-
| "str"
249+
"bool" | "bytes" | "complex" | "float" | "int" | "object" | "range" | "str"
258250
]
259251
)
260252
}
@@ -264,7 +256,7 @@ pub fn is_immutable_non_generic_type(qualified_name: &[&str]) -> bool {
264256
pub fn is_immutable_generic_type(qualified_name: &[&str]) -> bool {
265257
matches!(
266258
qualified_name,
267-
["" | "builtins", "frozenset" | "tuple"]
259+
["" | "builtins", "frozenset" | "tuple" | "frozendict"]
268260
| [
269261
"collections",
270262
"abc",
@@ -335,6 +327,7 @@ pub fn is_immutable_return_type(qualified_name: &[&str]) -> bool {
335327
| "str"
336328
| "tuple"
337329
| "slice"
330+
| "frozendict"
338331
]
339332
)
340333
}

scripts/check_ecosystem.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from contextlib import asynccontextmanager, nullcontext
2727
from pathlib import Path
2828
from signal import SIGINT, SIGTERM
29-
from typing import TYPE_CHECKING, NamedTuple, Self, TypeVar, cast
29+
from typing import TYPE_CHECKING, NamedTuple, Self, TypeVar
3030

3131
if TYPE_CHECKING:
3232
from collections.abc import AsyncIterator, Iterator, Sequence
@@ -424,10 +424,7 @@ async def limited_parallelism(coroutine: Awaitable[T]) -> T:
424424
print()
425425

426426
repo = repositories[(org, repo)]
427-
# TODO: ty otherwise considers this `list[set[str] | str]`,
428-
# seemingly ignoring `Diff.__iter__`. Seems like maybe a bug, but
429-
# pyright and mypy both do the same.
430-
diff_lines = cast(list[str], list(diff))
427+
diff_lines = list(diff)
431428

432429
print("<pre>")
433430
for line in diff_lines:

0 commit comments

Comments
 (0)