1#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
11pub struct PythonVersion {
12 pub major: u16,
13 pub minor: u16,
14}
15impl PythonVersion {
16 pub const fn new(major: u16, minor: u16) -> Self {
17 Self { major, minor }
18 }
19}
20const FIRST: PythonVersion = PythonVersion::new(3, 0);
21const END: PythonVersion = PythonVersion::new(3, 16);
22const UNDECLARED_FLOOR: PythonVersion = PythonVersion::new(3, 9);
25
26#[derive(Clone, Copy, Debug, PartialEq, Eq)]
27pub enum Availability {
28 Present,
29 Absent,
30 Unknown,
31}
32
33#[derive(Clone, Copy, Debug)]
34pub struct VersionRange {
35 pub since: PythonVersion,
36}
37impl VersionRange {
38 pub fn availability(self, version: Option<PythonVersion>) -> Availability {
39 let minimum = version.unwrap_or(UNDECLARED_FLOOR);
40 if !(FIRST..END).contains(&minimum) || self.since > minimum {
41 Availability::Unknown
42 } else {
43 Availability::Present
44 }
45 }
46}
47
48#[derive(Clone, Copy, Debug)]
49pub enum BuiltinKind {
50 Type,
51 Callable,
52 Value,
53}
54#[derive(Clone, Copy, Debug)]
55pub struct Builtin {
56 pub name: &'static str,
57 pub qualified_name: &'static str,
58 pub kind: BuiltinKind,
59 pub versions: VersionRange,
60}
61macro_rules! builtin {
62 ($name:ident, $kind:ident, $minor:literal) => {
63 Builtin {
64 name: stringify!($name),
65 qualified_name: concat!("builtins.", stringify!($name)),
66 kind: BuiltinKind::$kind,
67 versions: VersionRange {
68 since: PythonVersion::new(3, $minor),
69 },
70 }
71 };
72}
73
74pub const BUILTINS: &[Builtin] = &[
75 builtin!(ArithmeticError, Type, 0),
76 builtin!(AssertionError, Type, 0),
77 builtin!(AttributeError, Type, 0),
78 builtin!(BaseException, Type, 0),
79 builtin!(BaseExceptionGroup, Type, 11),
80 builtin!(BlockingIOError, Type, 3),
81 builtin!(BrokenPipeError, Type, 3),
82 builtin!(BufferError, Type, 0),
83 builtin!(BytesWarning, Type, 0),
84 builtin!(ChildProcessError, Type, 3),
85 builtin!(ConnectionAbortedError, Type, 3),
86 builtin!(ConnectionError, Type, 3),
87 builtin!(ConnectionRefusedError, Type, 3),
88 builtin!(ConnectionResetError, Type, 3),
89 builtin!(DeprecationWarning, Type, 0),
90 builtin!(EOFError, Type, 0),
91 builtin!(Ellipsis, Value, 0),
92 builtin!(EncodingWarning, Type, 10),
93 builtin!(EnvironmentError, Type, 0),
94 builtin!(Exception, Type, 0),
95 builtin!(ExceptionGroup, Type, 11),
96 builtin!(False, Value, 0),
97 builtin!(FileExistsError, Type, 3),
98 builtin!(FileNotFoundError, Type, 3),
99 builtin!(FloatingPointError, Type, 0),
100 builtin!(FutureWarning, Type, 0),
101 builtin!(GeneratorExit, Type, 0),
102 builtin!(IOError, Type, 0),
103 builtin!(ImportCycleError, Type, 15),
104 builtin!(ImportError, Type, 0),
105 builtin!(ImportWarning, Type, 0),
106 builtin!(IndentationError, Type, 0),
107 builtin!(IndexError, Type, 0),
108 builtin!(InterruptedError, Type, 3),
109 builtin!(IsADirectoryError, Type, 3),
110 builtin!(KeyError, Type, 0),
111 builtin!(KeyboardInterrupt, Type, 0),
112 builtin!(LookupError, Type, 0),
113 builtin!(MemoryError, Type, 0),
114 builtin!(ModuleNotFoundError, Type, 6),
115 builtin!(NameError, Type, 0),
116 builtin!(None, Value, 0),
117 builtin!(NotADirectoryError, Type, 3),
118 builtin!(NotImplemented, Value, 0),
119 builtin!(NotImplementedError, Type, 0),
120 builtin!(OSError, Type, 0),
121 builtin!(OverflowError, Type, 0),
122 builtin!(PendingDeprecationWarning, Type, 0),
123 builtin!(PermissionError, Type, 3),
124 builtin!(ProcessLookupError, Type, 3),
125 builtin!(PythonFinalizationError, Type, 13),
126 builtin!(RecursionError, Type, 5),
127 builtin!(ReferenceError, Type, 0),
128 builtin!(ResourceWarning, Type, 2),
129 builtin!(RuntimeError, Type, 0),
130 builtin!(RuntimeWarning, Type, 0),
131 builtin!(StopAsyncIteration, Type, 5),
132 builtin!(StopIteration, Type, 0),
133 builtin!(SyntaxError, Type, 0),
134 builtin!(SyntaxWarning, Type, 0),
135 builtin!(SystemError, Type, 0),
136 builtin!(SystemExit, Type, 0),
137 builtin!(TabError, Type, 0),
138 builtin!(TimeoutError, Type, 3),
139 builtin!(True, Value, 0),
140 builtin!(TypeError, Type, 0),
141 builtin!(UnboundLocalError, Type, 0),
142 builtin!(UnicodeDecodeError, Type, 0),
143 builtin!(UnicodeEncodeError, Type, 0),
144 builtin!(UnicodeError, Type, 0),
145 builtin!(UnicodeTranslateError, Type, 0),
146 builtin!(UnicodeWarning, Type, 0),
147 builtin!(UserWarning, Type, 0),
148 builtin!(ValueError, Type, 0),
149 builtin!(Warning, Type, 0),
150 builtin!(ZeroDivisionError, Type, 0),
151 builtin!(__build_class__, Callable, 0),
152 builtin!(__debug__, Value, 0),
153 builtin!(__import__, Callable, 0),
154 builtin!(abs, Callable, 0),
155 builtin!(aiter, Callable, 10),
156 builtin!(all, Callable, 0),
157 builtin!(anext, Callable, 10),
158 builtin!(any, Callable, 0),
159 builtin!(ascii, Callable, 0),
160 builtin!(bin, Callable, 0),
161 builtin!(bool, Type, 0),
162 builtin!(breakpoint, Callable, 7),
163 builtin!(bytearray, Type, 0),
164 builtin!(bytes, Type, 0),
165 builtin!(callable, Callable, 2),
166 builtin!(chr, Callable, 0),
167 builtin!(classmethod, Type, 0),
168 builtin!(compile, Callable, 0),
169 builtin!(complex, Type, 0),
170 builtin!(delattr, Callable, 0),
171 builtin!(dict, Type, 0),
172 builtin!(dir, Callable, 0),
173 builtin!(divmod, Callable, 0),
174 builtin!(enumerate, Type, 0),
175 builtin!(eval, Callable, 0),
176 builtin!(exec, Callable, 0),
177 builtin!(filter, Type, 0),
178 builtin!(float, Type, 0),
179 builtin!(format, Callable, 0),
180 builtin!(frozendict, Type, 15),
181 builtin!(frozenset, Type, 0),
182 builtin!(getattr, Callable, 0),
183 builtin!(globals, Callable, 0),
184 builtin!(hasattr, Callable, 0),
185 builtin!(hash, Callable, 0),
186 builtin!(hex, Callable, 0),
187 builtin!(id, Callable, 0),
188 builtin!(input, Callable, 0),
189 builtin!(int, Type, 0),
190 builtin!(isinstance, Callable, 0),
191 builtin!(issubclass, Callable, 0),
192 builtin!(iter, Callable, 0),
193 builtin!(len, Callable, 0),
194 builtin!(list, Type, 0),
195 builtin!(locals, Callable, 0),
196 builtin!(map, Type, 0),
197 builtin!(max, Callable, 0),
198 builtin!(memoryview, Type, 0),
199 builtin!(min, Callable, 0),
200 builtin!(next, Callable, 0),
201 builtin!(object, Type, 0),
202 builtin!(oct, Callable, 0),
203 builtin!(open, Callable, 0),
204 builtin!(ord, Callable, 0),
205 builtin!(pow, Callable, 0),
206 builtin!(print, Callable, 0),
207 builtin!(property, Type, 0),
208 builtin!(range, Type, 0),
209 builtin!(repr, Callable, 0),
210 builtin!(reversed, Type, 0),
211 builtin!(round, Callable, 0),
212 builtin!(sentinel, Type, 15),
213 builtin!(set, Type, 0),
214 builtin!(setattr, Callable, 0),
215 builtin!(slice, Type, 0),
216 builtin!(sorted, Callable, 0),
217 builtin!(staticmethod, Type, 0),
218 builtin!(str, Type, 0),
219 builtin!(sum, Callable, 0),
220 builtin!(super, Type, 0),
221 builtin!(tuple, Type, 0),
222 builtin!(type, Type, 0),
223 builtin!(vars, Callable, 0),
224 builtin!(zip, Type, 0),
225];
226
227pub fn implicit_base(version: Option<PythonVersion>) -> Option<&'static Builtin> {
229 let object = BUILTINS
230 .iter()
231 .find(|row| row.name == "object")
232 .expect("object is a Python language root");
233 (object.versions.availability(version) == Availability::Present).then_some(object)
234}
235pub fn builtin(name: &str) -> Option<&'static Builtin> {
236 BUILTINS.iter().find(|row| row.name == name)
237}
238
239#[derive(Clone, Copy, Debug)]
240pub struct ObjectMember {
241 pub name: &'static str,
242 pub versions: VersionRange,
243}
244macro_rules! member {
245 ($name:literal, $minor:literal) => {
246 ObjectMember {
247 name: $name,
248 versions: VersionRange {
249 since: PythonVersion::new(3, $minor),
250 },
251 }
252 };
253}
254pub const OBJECT_MEMBERS: &[ObjectMember] = &[
256 member!("__class__", 0),
257 member!("__delattr__", 0),
258 member!("__dir__", 3),
259 member!("__doc__", 0),
260 member!("__eq__", 0),
261 member!("__format__", 0),
262 member!("__ge__", 0),
263 member!("__getattribute__", 0),
264 member!("__getstate__", 11),
265 member!("__gt__", 0),
266 member!("__hash__", 0),
267 member!("__init__", 0),
268 member!("__init_subclass__", 6),
269 member!("__le__", 0),
270 member!("__lt__", 0),
271 member!("__ne__", 0),
272 member!("__new__", 0),
273 member!("__reduce__", 0),
274 member!("__reduce_ex__", 0),
275 member!("__repr__", 0),
276 member!("__setattr__", 0),
277 member!("__sizeof__", 0),
278 member!("__str__", 0),
279 member!("__subclasshook__", 0),
280];
281
282pub fn object_member(name: &str, version: Option<PythonVersion>) -> Availability {
283 match OBJECT_MEMBERS.iter().find(|row| row.name == name) {
284 Some(row) => row.versions.availability(version),
285 None if version.is_none_or(|v| (FIRST..END).contains(&v)) => Availability::Absent,
286 None => Availability::Unknown,
287 }
288}
289
290pub fn has_fixed_value_class_surface(qualified_name: &str) -> bool {
294 matches!(
295 qualified_name,
296 "types.NoneType"
297 | "builtins.bool"
298 | "builtins.int"
299 | "builtins.float"
300 | "builtins.str"
301 | "builtins.bytes"
302 | "builtins.list"
303 | "builtins.tuple"
304 | "builtins.dict"
305 | "builtins.set"
306 | "builtins.frozenset"
307 | "builtins.object"
308 )
309}