Skip to content

Commit a4ef0fd

Browse files
committed
Update/regenerate various ruff_python_stdlib APIs
1 parent 590ad07 commit a4ef0fd

4 files changed

Lines changed: 201 additions & 68 deletions

File tree

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
}
Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
"""Script to generate `crates/ruff_python_stdlib/src/builtin_modules.rs`.
2-
3-
This script requires the following executables to be callable via a subprocess:
4-
- `python3.7`
5-
- `python3.8`
6-
- `python3.9`
7-
- `python3.10`
8-
- `python3.11`
9-
- `python3.12`
10-
- `python3.13`
1+
"""Script to generate `crates/ruff_python_stdlib/src/sys/builtin_modules.rs`.
2+
3+
This script requires `uvx` to be available on PATH.
114
"""
125

136
from __future__ import annotations
@@ -17,43 +10,46 @@
1710
import textwrap
1811
from functools import partial
1912
from pathlib import Path
13+
from typing import Final
2014

2115
MODULE_CRATE = "ruff_python_stdlib"
2216
MODULE_PATH = Path("crates") / MODULE_CRATE / "src" / "sys" / "builtin_modules.rs"
23-
24-
type Version = tuple[int, int]
25-
26-
PYTHON_VERSIONS: list[Version] = [
27-
(3, 7),
28-
(3, 8),
29-
(3, 9),
30-
(3, 10),
31-
(3, 11),
32-
(3, 12),
33-
(3, 13),
34-
]
35-
36-
37-
def builtin_modules_on_version(major_version: int, minor_version: int) -> set[str]:
38-
executable = f"python{major_version}.{minor_version}"
39-
try:
40-
proc = subprocess.run(
41-
[executable, "-c", "import sys; print(sys.builtin_module_names)"],
42-
check=True,
43-
text=True,
44-
capture_output=True,
45-
)
46-
except subprocess.CalledProcessError as e:
47-
print(e.stdout)
48-
print(e.stderr)
49-
raise
17+
PYTHON_VERSIONS: Final = range(8, 16) # Python 3.8 through 3.15
18+
19+
20+
def builtin_modules_on_version(minor_version: int) -> set[str]:
21+
command_1 = [
22+
"uv",
23+
"--managed-python",
24+
"python",
25+
"install",
26+
f"python3.{minor_version}",
27+
"--upgrade",
28+
]
29+
command_2 = [
30+
"uvx",
31+
"--managed-python",
32+
f"python3.{minor_version}",
33+
"-c",
34+
"import sys; print(sys.builtin_module_names)",
35+
]
36+
for command in command_1, command_2:
37+
try:
38+
proc = subprocess.run(
39+
command,
40+
check=True,
41+
text=True,
42+
capture_output=True,
43+
)
44+
except subprocess.CalledProcessError as e:
45+
print(e.stdout)
46+
print(e.stderr)
47+
raise
5048
return set(eval(proc.stdout))
5149

5250

53-
def generate_module(
54-
script_destination: Path, crate_name: str, python_versions: list[Version]
55-
) -> None:
56-
with script_destination.open("w") as f:
51+
def generate_module() -> None:
52+
with MODULE_PATH.open("w") as f:
5753
print = partial(builtins.print, file=f)
5854

5955
print(
@@ -70,16 +66,16 @@ def generate_module(
7066
/// modules.
7167
///
7268
/// [builtin module]: https://docs.python.org/3/library/sys.html#sys.builtin_module_names
73-
#[expect(clippy::unnested_or_patterns)]
69+
#[allow(clippy::unnested_or_patterns)]
7470
pub fn is_builtin_module(minor_version: u8, module: &str) -> bool {
7571
matches!((minor_version, module),
7672
""",
7773
)
7874
)
7975

8076
modules_by_version = {
81-
minor_version: builtin_modules_on_version(major_version, minor_version)
82-
for major_version, minor_version in python_versions
77+
minor_version: builtin_modules_on_version(minor_version)
78+
for minor_version in PYTHON_VERSIONS
8379
}
8480

8581
# First, add a case for the modules that are in all versions.
@@ -93,7 +89,7 @@ def generate_module(
9389
print(")")
9490

9591
# Next, add any version-specific modules.
96-
for _major_version, minor_version in python_versions:
92+
for minor_version in PYTHON_VERSIONS:
9793
version_modules = set.difference(
9894
modules_by_version[minor_version],
9995
ubiquitous_modules,
@@ -109,8 +105,8 @@ def generate_module(
109105

110106
print(")}")
111107

112-
subprocess.run(["cargo", "fmt", "--package", crate_name], check=True)
108+
subprocess.run(["cargo", "fmt", "--package", MODULE_CRATE], check=True)
113109

114110

115111
if __name__ == "__main__":
116-
generate_module(MODULE_PATH, MODULE_CRATE, PYTHON_VERSIONS)
112+
generate_module()

0 commit comments

Comments
 (0)