mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-02 06:42:02 +00:00
36 commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
![]() |
b51c4f82ea
|
Rename Red Knot (#17820) | ||
![]() |
e170fe493d
|
[red-knot] Trust all symbols in stub files (#17588)
## Summary *Generally* trust undeclared symbols in stubs, not just at the module level. Follow-up on the discussion [here](https://github.com/astral-sh/ruff/pull/17577#discussion_r2055945909). ## Test Plan New Markdown test. |
||
![]() |
e91e2f49db
|
[red-knot] Trust module-level undeclared symbols in stubs (#17577)
## Summary Many symbols in typeshed are defined without being declared. For example: ```pyi # builtins: IOError = OSError # types LambdaType = FunctionType NotImplementedType = _NotImplementedType # typing Text = str # random uniform = _inst.uniform # optparse make_option = Option # all over the place: _T = TypeVar("_T") ``` Here, we introduce a change that skips widening the public type of these symbols (by unioning with `Unknown`). fixes #17032 ## Ecosystem analysis This is difficult to analyze in detail, but I went over most changes and it looks very favorable to me overall. The diff on the overall numbers is: ``` errors: 1287 -> 859 (reduction by 428) warnings: 45 -> 59 (increase by 14) ``` ### Removed false positives `invalid-base` examples: ```diff - error[lint:invalid-base] /tmp/mypy_primer/projects/pip/src/pip/_vendor/rich/console.py:548:27: Invalid class base with type `Unknown | Literal[_local]` (all bases must be a class, `Any`, `Unknown` or `Todo`) - error[lint:invalid-base] /tmp/mypy_primer/projects/tornado/tornado/iostream.py:84:25: Invalid class base with type `Unknown | Literal[OSError]` (all bases must be a class, `Any`, `Unknown` or `Todo`) - error[lint:invalid-base] /tmp/mypy_primer/projects/mitmproxy/test/conftest.py:35:40: Invalid class base with type `Unknown | Literal[_UnixDefaultEventLoopPolicy]` (all bases must be a class, `Any`, `Unknown` or `Todo`) ``` `invalid-exception-caught` examples: ```diff - error[lint:invalid-exception-caught] /tmp/mypy_primer/projects/cloud-init/cloudinit/cmd/status.py:334:16: Cannot catch object of type `Literal[ProcessExecutionError]` in an exception handler (must be a `BaseException` subclass or a tuple of `BaseException` subclasses) - error[lint:invalid-exception-caught] /tmp/mypy_primer/projects/jinja/src/jinja2/loaders.py:537:16: Cannot catch object of type `Literal[TemplateNotFound]` in an exception handler (must be a `BaseException` subclass or a tuple of `BaseException` subclasses) ``` `unresolved-reference` examples |
||
![]() |
4d50ee6f52
|
[red-knot] Track reachability of scopes (#17332)
## Summary Track the reachability of nested scopes within their parent scopes. We use this as an additional requirement for emitting `unresolved-reference` diagnostics (and in the future, `unresolved-attribute` and `unresolved-import`). This means that we only emit `unresolved-reference` for a given use of a symbol if the use itself is reachable (within its own scope), *and if the scope itself is reachable*. For example, no diagnostic should be emitted for the use of `x` here: ```py if False: x = 1 def f(): print(x) # this use of `x` is reachable inside the `f` scope, # but the whole `f` scope is not reachable. ``` There are probably more fine-grained ways of solving this problem, but they require a more sophisticated understanding of nested scopes (see #15777, in particular https://github.com/astral-sh/ruff/issues/15777#issuecomment-2788950267). But it doesn't seem completely unreasonable to silence *this specific kind of error* in unreachable scopes. ## Test Plan Observed changes in reachability tests and ecosystem. |
||
![]() |
62f8d855d2
|
[red-knot] Improve Debug implementation for semantic_index::SymbolTable (#17172)
## Summary `dbg!`ing a `SymbolTable` is currently very noisy due to the `symbols_by_name` field, which doesn't tell you very much at all. The noisiness makes debugging difficult. This PR removes the `symbols_by_name` field from the `Debug` implementation. ## Test Plan `dbg!` output before of the `builtins.pyi` global-scope symbol table: <details> ``` [crates/red_knot_python_semantic/src/symbol.rs:633:5] symbol_table(db, scope) = SymbolTable { symbols: [ Symbol { name: Name("_ast"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_sitebuiltins"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_typeshed"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("sys"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("types"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("dict_items"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("dict_keys"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("dict_values"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("AnyStr_co"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ConvertibleToFloat"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ConvertibleToInt"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("FileDescriptorOrPath"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("OpenBinaryMode"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("OpenBinaryModeReading"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("OpenBinaryModeUpdating"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("OpenBinaryModeWriting"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("OpenTextMode"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ReadableBuffer"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsAdd"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsAiter"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsAnext"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsDivMod"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsFlush"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsIter"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsKeysAndGetItem"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsLenAndGetItem"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsNext"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsRAdd"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsRDivMod"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsRichComparison"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsRichComparisonT"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsWrite"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Awaitable"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Callable"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Iterable"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Iterator"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("MutableSet"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Reversible"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("AbstractSet"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Sized"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("BufferedRandom"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("BufferedReader"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("BufferedWriter"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("FileIO"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("TextIOWrapper"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("CellType"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("CodeType"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("TracebackType"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("IO"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Any"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("BinaryIO"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ClassVar"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Generic"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Mapping"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("MutableMapping"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("MutableSequence"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Protocol"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Sequence"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsAbs"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsBytes"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsComplex"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsFloat"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SupportsIndex"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("TypeVar"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("final"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("overload"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("type_check_only"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Concatenate"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Literal"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("LiteralString"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ParamSpec"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Self"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("TypeAlias"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("TypeGuard"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("TypeIs"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("TypeVarTuple"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("deprecated"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("GenericAlias"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_T"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("int"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_I"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_T_co"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_T_contra"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_R_co"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_KT"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_VT"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_S"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_T1"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_T2"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_T3"), flags: SymbolFlags( IS_BOUND, ), }, Symbol { name: Name("_T4"), flags: SymbolFlags( IS_BOUND, ), }, Symbol { name: Name("_T5"), flags: SymbolFlags( IS_BOUND, ), }, Symbol { name: Name("_SupportsNextT_co"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_SupportsAnextT_co"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_AwaitableT"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_AwaitableT_co"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_P"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_StartT_co"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_StopT_co"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_StepT_co"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("object"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("staticmethod"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("classmethod"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("type"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("super"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_PositiveInteger"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_NegativeInteger"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_LiteralInteger"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("float"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("complex"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_FormatMapMapping"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_TranslateTable"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("str"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("bytes"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("bytearray"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_IntegerFormats"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("memoryview"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("bool"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("slice"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("tuple"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("function"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("list"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("dict"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("set"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("frozenset"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("enumerate"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("range"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("property"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_NotImplementedType"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("NotImplemented"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("abs"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("all"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("any"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ascii"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("bin"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("breakpoint"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("callable"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("chr"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_PathLike"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("aiter"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_SupportsSynchronousAnext"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("anext"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("compile"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("copyright"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("credits"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("delattr"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("dir"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("divmod"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("eval"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("exec"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("exit"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("filter"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("format"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("getattr"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("globals"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("hasattr"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("hash"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("help"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("hex"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("id"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("input"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_GetItemIterable"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("iter"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_ClassInfo"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("isinstance"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("issubclass"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("len"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("license"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("locals"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("map"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("max"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("min"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("next"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("oct"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_Opener"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("open"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ord"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_SupportsWriteAndFlush"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("print"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_E_contra"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_M_contra"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_SupportsPow2"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_SupportsPow3NoneOnly"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_SupportsPow3"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_SupportsSomeKindOfPow"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("pow"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("quit"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("reversed"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("repr"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_SupportsRound1"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_SupportsRound2"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("round"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("setattr"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("sorted"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_AddableT1"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_AddableT2"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_SupportsSumWithNoDefaultGiven"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_SupportsSumNoDefaultT"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("sum"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("vars"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("zip"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("__import__"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("__build_class__"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("EllipsisType"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ellipsis"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Ellipsis"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("BaseException"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("GeneratorExit"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("KeyboardInterrupt"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SystemExit"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Exception"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("StopIteration"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("OSError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("EnvironmentError"), flags: SymbolFlags( IS_BOUND, ), }, Symbol { name: Name("IOError"), flags: SymbolFlags( IS_BOUND, ), }, Symbol { name: Name("WindowsError"), flags: SymbolFlags( IS_BOUND, ), }, Symbol { name: Name("ArithmeticError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("AssertionError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("AttributeError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("BufferError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("EOFError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ImportError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("LookupError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("MemoryError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("NameError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ReferenceError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("RuntimeError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("StopAsyncIteration"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SyntaxError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SystemError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("TypeError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ValueError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("FloatingPointError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("OverflowError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ZeroDivisionError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ModuleNotFoundError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("IndexError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("KeyError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("UnboundLocalError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("BlockingIOError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ChildProcessError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ConnectionError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("BrokenPipeError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ConnectionAbortedError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ConnectionRefusedError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ConnectionResetError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("FileExistsError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("FileNotFoundError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("InterruptedError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("IsADirectoryError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("NotADirectoryError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("PermissionError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ProcessLookupError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("TimeoutError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("NotImplementedError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("RecursionError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("IndentationError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("TabError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("UnicodeError"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("UnicodeDecodeError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("UnicodeEncodeError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("UnicodeTranslateError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("Warning"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("UserWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("DeprecationWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("SyntaxWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("RuntimeWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("FutureWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("PendingDeprecationWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ImportWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("UnicodeWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("BytesWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ResourceWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("EncodingWarning"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("_BaseExceptionT_co"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_BaseExceptionT"), flags: SymbolFlags( IS_BOUND, ), }, Symbol { name: Name("_ExceptionT_co"), flags: SymbolFlags( IS_USED | IS_BOUND, ), }, Symbol { name: Name("_ExceptionT"), flags: SymbolFlags( IS_BOUND, ), }, Symbol { name: Name("BaseExceptionGroup"), flags: SymbolFlags( IS_USED | IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("ExceptionGroup"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, Symbol { name: Name("PythonFinalizationError"), flags: SymbolFlags( IS_BOUND | IS_DECLARED, ), }, ], symbols_by_name: { ScopedSymbolId( 235, ): (), ScopedSymbolId( 267, ): (), ScopedSymbolId( 86, ): (), ScopedSymbolId( 22, ): (), ScopedSymbolId( 182, ): (), ScopedSymbolId( 213, ): (), ScopedSymbolId( 252, ): (), ScopedSymbolId( 177, ): (), ScopedSymbolId( 173, ): (), ScopedSymbolId( 108, ): (), ScopedSymbolId( 122, ): (), ScopedSymbolId( 118, ): (), ScopedSymbolId( 197, ): (), ScopedSymbolId( 69, ): (), ScopedSymbolId( 134, ): (), ScopedSymbolId( 52, ): (), ScopedSymbolId( 248, ): (), ScopedSymbolId( 168, ): (), ScopedSymbolId( 2, ): (), ScopedSymbolId( 129, ): (), ScopedSymbolId( 5, ): (), ScopedSymbolId( 18, ): (), ScopedSymbolId( 150, ): (), ScopedSymbolId( 9, ): (), ScopedSymbolId( 16, ): (), ScopedSymbolId( 205, ): (), ScopedSymbolId( 246, ): (), ScopedSymbolId( 68, ): (), ScopedSymbolId( 93, ): (), ScopedSymbolId( 189, ): (), ScopedSymbolId( 161, ): (), ScopedSymbolId( 64, ): (), ScopedSymbolId( 124, ): (), ScopedSymbolId( 229, ): (), ScopedSymbolId( 94, ): (), ScopedSymbolId( 202, ): (), ScopedSymbolId( 67, ): (), ScopedSymbolId( 120, ): (), ScopedSymbolId( 219, ): (), ScopedSymbolId( 12, ): (), ScopedSymbolId( 20, ): (), ScopedSymbolId( 79, ): (), ScopedSymbolId( 11, ): (), ScopedSymbolId( 157, ): (), ScopedSymbolId( 216, ): (), ScopedSymbolId( 231, ): (), ScopedSymbolId( 239, ): (), ScopedSymbolId( 140, ): (), ScopedSymbolId( 36, ): (), ScopedSymbolId( 13, ): (), ScopedSymbolId( 184, ): (), ScopedSymbolId( 204, ): (), ScopedSymbolId( 70, ): (), ScopedSymbolId( 259, ): (), ScopedSymbolId( 96, ): (), ScopedSymbolId( 111, ): (), ScopedSymbolId( 72, ): (), ScopedSymbolId( 247, ): (), ScopedSymbolId( 101, ): (), ScopedSymbolId( 242, ): (), ScopedSymbolId( 261, ): (), ScopedSymbolId( 263, ): (), ScopedSymbolId( 214, ): (), ScopedSymbolId( 62, ): (), ScopedSymbolId( 166, ): (), ScopedSymbolId( 244, ): (), ScopedSymbolId( 257, ): (), ScopedSymbolId( 133, ): (), ScopedSymbolId( 112, ): (), ScopedSymbolId( 87, ): (), ScopedSymbolId( 90, ): (), ScopedSymbolId( 117, ): (), ScopedSymbolId( 158, ): (), ScopedSymbolId( 162, ): (), ScopedSymbolId( 230, ): (), ScopedSymbolId( 154, ): (), ScopedSymbolId( 255, ): (), ScopedSymbolId( 35, ): (), ScopedSymbolId( 39, ): (), ScopedSymbolId( 138, ): (), ScopedSymbolId( 190, ): (), ScopedSymbolId( 21, ): (), ScopedSymbolId( 66, ): (), ScopedSymbolId( 181, ): (), ScopedSymbolId( 7, ): (), ScopedSymbolId( 236, ): (), ScopedSymbolId( 251, ): (), ScopedSymbolId( 152, ): (), ScopedSymbolId( 227, ): (), ScopedSymbolId( 78, ): (), ScopedSymbolId( 55, ): (), ScopedSymbolId( 61, ): (), ScopedSymbolId( 253, ): (), ScopedSymbolId( 47, ): (), ScopedSymbolId( 65, ): (), ScopedSymbolId( 153, ): (), ScopedSymbolId( 104, ): (), ScopedSymbolId( 74, ): (), ScopedSymbolId( 107, ): (), ScopedSymbolId( 149, ): (), ScopedSymbolId( 98, ): (), ScopedSymbolId( 155, ): (), ScopedSymbolId( 169, ): (), ScopedSymbolId( 180, ): (), ScopedSymbolId( 237, ): (), ScopedSymbolId( 146, ): (), ScopedSymbolId( 15, ): (), ScopedSymbolId( 243, ): (), ScopedSymbolId( 17, ): (), ScopedSymbolId( 136, ): (), ScopedSymbolId( 80, ): (), ScopedSymbolId( 44, ): (), ScopedSymbolId( 228, ): (), ScopedSymbolId( 60, ): (), ScopedSymbolId( 245, ): (), ScopedSymbolId( 193, ): (), ScopedSymbolId( 264, ): (), ScopedSymbolId( 268, ): (), ScopedSymbolId( 58, ): (), ScopedSymbolId( 258, ): (), ScopedSymbolId( 279, ): (), ScopedSymbolId( 113, ): (), ScopedSymbolId( 135, ): (), ScopedSymbolId( 240, ): (), ScopedSymbolId( 85, ): (), ScopedSymbolId( 186, ): (), ScopedSymbolId( 100, ): (), ScopedSymbolId( 187, ): (), ScopedSymbolId( 106, ): (), ScopedSymbolId( 73, ): (), ScopedSymbolId( 223, ): (), ScopedSymbolId( 49, ): (), ScopedSymbolId( 83, ): (), ScopedSymbolId( 77, ): (), ScopedSymbolId( 43, ): (), ScopedSymbolId( 274, ): (), ScopedSymbolId( 46, ): (), ScopedSymbolId( 151, ): (), ScopedSymbolId( 217, ): (), ScopedSymbolId( 178, ): (), ScopedSymbolId( 278, ): (), ScopedSymbolId( 132, ): (), ScopedSymbolId( 6, ): (), ScopedSymbolId( 174, ): (), ScopedSymbolId( 99, ): (), ScopedSymbolId( 196, ): (), ScopedSymbolId( 109, ): (), ScopedSymbolId( 128, ): (), ScopedSymbolId( 123, ): (), ScopedSymbolId( 102, ): (), ScopedSymbolId( 116, ): (), ScopedSymbolId( 172, ): (), ScopedSymbolId( 32, ): (), ScopedSymbolId( 105, ): (), ScopedSymbolId( 241, ): (), ScopedSymbolId( 95, ): (), ScopedSymbolId( 206, ): (), ScopedSymbolId( 209, ): (), ScopedSymbolId( 198, ): (), ScopedSymbolId( 81, ): (), ScopedSymbolId( 170, ): (), ScopedSymbolId( 171, ): (), ScopedSymbolId( 8, ): (), ScopedSymbolId( 276, ): (), ScopedSymbolId( 1, ): (), ScopedSymbolId( 212, ): (), ScopedSymbolId( 222, ): (), ScopedSymbolId( 33, ): (), ScopedSymbolId( 144, ): (), ScopedSymbolId( 194, ): (), ScopedSymbolId( 125, ): (), ScopedSymbolId( 89, ): (), ScopedSymbolId( 38, ): (), ScopedSymbolId( 51, ): (), ScopedSymbolId( 19, ): (), ScopedSymbolId( 163, ): (), ScopedSymbolId( 0, ): (), ScopedSymbolId( 211, ): (), ScopedSymbolId( 3, ): (), ScopedSymbolId( 226, ): (), ScopedSymbolId( 121, ): (), ScopedSymbolId( 148, ): (), ScopedSymbolId( 232, ): (), ScopedSymbolId( 262, ): (), ScopedSymbolId( 260, ): (), ScopedSymbolId( 91, ): (), ScopedSymbolId( 270, ): (), ScopedSymbolId( 269, ): (), ScopedSymbolId( 225, ): (), ScopedSymbolId( 191, ): (), ScopedSymbolId( 115, ): (), ScopedSymbolId( 28, ): (), ScopedSymbolId( 220, ): (), ScopedSymbolId( 164, ): (), ScopedSymbolId( 250, ): (), ScopedSymbolId( 137, ): (), ScopedSymbolId( 141, ): (), ScopedSymbolId( 24, ): (), ScopedSymbolId( 54, ): (), ScopedSymbolId( 45, ): (), ScopedSymbolId( 188, ): (), ScopedSymbolId( 75, ): (), ScopedSymbolId( 40, ): (), ScopedSymbolId( 234, ): (), ScopedSymbolId( 30, ): (), ScopedSymbolId( 41, ): (), ScopedSymbolId( 127, ): (), ScopedSymbolId( 185, ): (), ScopedSymbolId( 145, ): (), ScopedSymbolId( 23, ): (), ScopedSymbolId( 238, ): (), ScopedSymbolId( 143, ): (), ScopedSymbolId( 167, ): (), ScopedSymbolId( 110, ): (), ScopedSymbolId( 25, ): (), ScopedSymbolId( 31, ): (), ScopedSymbolId( 57, ): (), ScopedSymbolId( 195, ): (), ScopedSymbolId( 221, ): (), ScopedSymbolId( 218, ): (), ScopedSymbolId( 37, ): (), ScopedSymbolId( 71, ): (), ScopedSymbolId( 50, ): (), ScopedSymbolId( 176, ): (), ScopedSymbolId( 179, ): (), ScopedSymbolId( 200, ): (), ScopedSymbolId( 266, ): (), ScopedSymbolId( 277, ): (), ScopedSymbolId( 119, ): (), ScopedSymbolId( 84, ): (), ScopedSymbolId( 114, ): (), ScopedSymbolId( 165, ): (), ScopedSymbolId( 271, ): (), ScopedSymbolId( 280, ): (), ScopedSymbolId( 256, ): (), ScopedSymbolId( 249, ): (), ScopedSymbolId( 88, ): (), ScopedSymbolId( 27, ): (), ScopedSymbolId( 139, ): (), ScopedSymbolId( 265, ): (), ScopedSymbolId( 4, ): (), ScopedSymbolId( 53, ): (), ScopedSymbolId( 29, ): (), ScopedSymbolId( 130, ): (), ScopedSymbolId( 42, ): (), ScopedSymbolId( 76, ): (), ScopedSymbolId( 147, ): (), ScopedSymbolId( 156, ): (), ScopedSymbolId( 208, ): (), ScopedSymbolId( 273, ): (), ScopedSymbolId( 183, ): (), ScopedSymbolId( 224, ): (), ScopedSymbolId( 97, ): (), ScopedSymbolId( 233, ): (), ScopedSymbolId( 82, ): (), ScopedSymbolId( 142, ): (), ScopedSymbolId( 254, ): (), ScopedSymbolId( 131, ): (), ScopedSymbolId( 63, ): (), ScopedSymbolId( 48, ): (), ScopedSymbolId( 215, ): (), ScopedSymbolId( 103, ): (), ScopedSymbolId( 14, ): (), ScopedSymbolId( 92, ): (), ScopedSymbolId( 207, ): (), ScopedSymbolId( 275, ): (), ScopedSymbolId( 160, ): (), ScopedSymbolId( 26, ): (), ScopedSymbolId( 56, ): (), ScopedSymbolId( 34, ): (), ScopedSymbolId( 272, ): (), ScopedSymbolId( 59, ): (), ScopedSymbolId( 126, ): (), ScopedSymbolId( 159, ): (), ScopedSymbolId( 199, ): (), ScopedSymbolId( 175, ): (), ScopedSymbolId( 192, ): (), ScopedSymbolId( 201, ): (), ScopedSymbolId( 203, ): (), ScopedSymbolId( 210, ): (), ScopedSymbolId( 10, ): (), }, } ``` </details> I checked that with this PR, the second field is gone from the debug output (I'd paste it in, but it goes over the GitHub comment length maximum). |
||
![]() |
aca6254e82
|
[red-knot] fix eager nested scopes handling (#16916)
## Summary From #16861, and the continuation of #16915. This PR fixes the incorrect behavior of `TypeInferenceBuilder::infer_name_load` in eager nested scopes. And this PR closes #16341. ## Test Plan New test cases are added in `annotations/deferred.md`. |
||
![]() |
2d892bc9f7
|
Fix typos (#16908)
## Summary The noun is spelled "descend<strong><em>a</em></strong>nt" and the adjective "descend<strong><em>e</em></strong>nt". ## Test Plan [From the English Wiktionary](https://en.wiktionary.org/wiki/descendent#Usage_notes): > The adjective, "descending from a biological ancestor", may be spelt either with an <i>[a](https://en.wiktionary.org/wiki/-ant)</i> or with an <i>[e](https://en.wiktionary.org/wiki/-ent)</i> in the final syllable (see [descendant](https://en.wiktionary.org/wiki/descendant)). However, the noun <i>descendant</i>, "one who is the progeny of someone", may be spelt only with an <i>[a](https://en.wiktionary.org/wiki/-ant)</i>. Compare also <i>[dependent](https://en.wiktionary.org/wiki/dependent#English)</i> and <i>[dependant](https://en.wiktionary.org/wiki/dependant#English)</i>. |
||
![]() |
c100d519e9
|
[internal]: Upgrade salsa (#16794)
## Summary Another salsa upgrade. The main motivation is to stay on a recent salsa version because there are still a lot of breaking changes happening. The most significant changes in this update: * Salsa no longer derives `Debug` by default. It now requires `interned(debug)` (or similar) * This version ships the foundation for garbage collecting interned values. However, this comes at the cost that queries now track which interned values they created (or read). The micro benchmarks in the salsa repo showed a significant perf regression. Will see if this also visible in our benchmarks. ## Test Plan `cargo test` |
||
![]() |
78b5f0b165
|
[red-knot] detect invalid return type (#16540)
## Summary This PR closes #16248. If the return type of the function isn't assignable to the one specified, an `invalid-return-type` error occurs. I thought it would be better to report this as a different kind of error than the `invalid-assignment` error, so I defined this as a new error. ## Test Plan All type inconsistencies in the test cases have been replaced with appropriate ones. --------- Co-authored-by: Carl Meyer <carl@astral.sh> |
||
![]() |
820a31af5d
|
[red-knot] Attribute access and the descriptor protocol (#16416)
## Summary * Attributes/method are now properly looked up on metaclasses, when called on class objects * We properly distinguish between data descriptors and non-data descriptors (but we do not yet support them in store-context, i.e. `obj.data_descr = …`) * The descriptor protocol is now implemented in a single unified place for instances, classes and dunder-calls. Unions and possibly-unbound symbols are supported in all possible stages of the process by creating union types as results. * In general, the handling of "possibly-unbound" symbols has been improved in a lot of places: meta-class attributes, attributes, descriptors with possibly-unbound `__get__` methods, instance attributes, … * We keep track of type qualifiers in a lot more places. I anticipate that this will be useful if we import e.g. `Final` symbols from other modules (see relevant change to typing spec: https://github.com/python/typing/pull/1937). * Detection and special-casing of the `typing.Protocol` special form in order to avoid lots of changes in the test suite due to new `@Todo` types when looking up attributes on builtin types which have `Protocol` in their MRO. We previously looked up attributes in a wrong way, which is why this didn't come up before. closes #16367 closes #15966 ## Context The way attribute lookup in `Type::member` worked before was simply wrong (mostly my own fault). The whole instance-attribute lookup should probably never have been integrated into `Type::member`. And the `Type::static_member` function that I introduced in my last descriptor PR was the wrong abstraction. It's kind of fascinating how far this approach took us, but I am pretty confident that the new approach proposed here is what we need to model this correctly. There are three key pieces that are required to implement attribute lookups: - **`Type::class_member`**/**`Type::find_in_mro`**: The `Type::find_in_mro` method that can look up attributes on class bodies (and corresponding bases). This is a partial function on types, as it can not be called on instance types like`Type::Instance(…)` or `Type::IntLiteral(…)`. For this reason, we usually call it through `Type::class_member`, which is essentially just `type.to_meta_type().find_in_mro(…)` plus union/intersection handling. - **`Type::instance_member`**: This new function is basically the type-level equivalent to `obj.__dict__[name]` when called on `Type::Instance(…)`. We use this to discover instance attributes such as those that we see as declarations on class bodies or as (annotated) assignments to `self.attr` in methods of a class. - The implementation of the descriptor protocol. It works slightly different for instances and for class objects, but it can be described by the general framework: - Call `type.class_member("attribute")` to look up "attribute" in the MRO of the meta type of `type`. Call the resulting `Symbol` `meta_attr` (even if it's unbound). - Use `meta_attr.class_member("__get__")` to look up `__get__` on the *meta type* of `meta_attr`. Call it with `__get__(meta_attr, self, self.to_meta_type())`. If this fails (either the lookup or the call), just proceed with `meta_attr`. Otherwise, replace `meta_attr` in the following with the return type of `__get__`. In this step, we also probe if a `__set__` or `__delete__` method exists and store it in `meta_attr_kind` (can be either "data descriptor" or "normal attribute or non-data descriptor"). - Compute a `fallback` type. - For instances, we use `self.instance_member("attribute")` - For class objects, we use `class_attr = self.find_in_mro("attribute")`, and then try to invoke the descriptor protocol on `class_attr`, i.e. we look up `__get__` on the meta type of `class_attr` and call it with `__get__(class_attr, None, self)`. This additional invocation of the descriptor protocol on the fallback type is one major asymmetry in the otherwise universal descriptor protocol implementation. - Finally, we look at `meta_attr`, `meta_attr_kind` and `fallback`, and handle various cases of (possible) unboundness of these symbols. - If `meta_attr` is bound and a data descriptor, just return `meta_attr` - If `meta_attr` is not a data descriptor, and `fallback` is bound, just return `fallback` - If `meta_attr` is not a data descriptor, and `fallback` is unbound, return `meta_attr` - Return unions of these three possibilities for partially-bound symbols. This allows us to handle class objects and instances within the same framework. There is a minor additional detail where for instances, we do not allow the fallback type (the instance attribute) to completely shadow the non-data descriptor. We do this because we (currently) don't want to pretend that we can statically infer that an instance attribute is always set. Dunder method calls can also be embedded into this framework. The only thing that changes is that *there is no fallback type*. If a dunder method is called on an instance, we do not fall back to instance variables. If a dunder method is called on a class object, we only look it up on the meta class, never on the class itself. ## Test Plan New Markdown tests. |
||
![]() |
cfc6941d5c
|
[red-knot] Resolve references in eager nested scopes eagerly (#16079)
We now resolve references in "eager" scopes correctly — using the bindings and declarations that are visible at the point where the eager scope is created, not the "public" type of the symbol (typically the bindings visible at the end of the scope). --------- Co-authored-by: Alex Waygood <alex.waygood@gmail.com> |
||
![]() |
69d86d1d69
|
Transition to salsa coarse-grained tracked structs (#15763)
## Summary Transition to using coarse-grained tracked structs (depends on https://github.com/salsa-rs/salsa/pull/657). For now, this PR doesn't add any `#[tracked]` fields, meaning that any changes cause the entire struct to be invalidated. It also changes `AstNodeRef` to be compared/hashed by pointer address, instead of performing a deep AST comparison. ## Test Plan This yields a 10-15% improvement on my machine (though weirdly some runs were 5-10% without being flagged as inconsistent by criterion, is there some non-determinism involved?). It's possible that some of this is unrelated, I'll try applying the patch to the current salsa version to make sure. --------- Co-authored-by: Micha Reiser <micha@reiser.io> |
||
![]() |
102c2eec12
|
[red-knot] Implicit instance attributes (#15811)
## Summary Add support for implicitly-defined instance attributes, i.e. support type inference for cases like this: ```py class C: def __init__(self) -> None: self.x: int = 1 self.y = None reveal_type(C().x) # int reveal_type(C().y) # Unknown | None ``` ## Benchmarks Codspeed reports no change in a cold-cache benchmark, and a -1% regression in the incremental benchmark. On `black`'s `src` folder, I don't see a statistically significant difference between the branches: | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |:---|---:|---:|---:|---:| | `./red_knot_main check --project /home/shark/black/src` | 133.7 ± 9.5 | 126.7 | 164.7 | 1.01 ± 0.08 | | `./red_knot_feature check --project /home/shark/black/src` | 132.2 ± 5.1 | 118.1 | 140.9 | 1.00 | ## Test Plan Updated and new Markdown tests |
||
![]() |
0caab81d3d
|
@no_type_check support (#15122)
Co-authored-by: Carl Meyer <carl@astral.sh> |
||
![]() |
a90e404c3f
|
[red-knot] PEP 695 type aliases (#14357)
## Summary Add support for (non-generic) type aliases. The main motivation behind this was to get rid of panics involving expressions in (generic) type aliases. But it turned out the best way to fix it was to implement (partial) support for type aliases. ```py type IntOrStr = int | str reveal_type(IntOrStr) # revealed: typing.TypeAliasType reveal_type(IntOrStr.__name__) # revealed: Literal["IntOrStr"] x: IntOrStr = 1 reveal_type(x) # revealed: Literal[1] def f() -> None: reveal_type(x) # revealed: int | str ``` ## Test Plan - Updated corpus test allow list to reflect that we don't panic anymore. - Added Markdown-based test for type aliases (`type_alias.md`) |
||
![]() |
62d650226b
|
[red-knot] Derive more Default methods (#14361)
|
||
![]() |
4323512a65
|
Remove AST-node dependency from FunctionType and ClassType (#14087)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> |
||
![]() |
d2c9f5e43c
|
[red-knot] Fallback to attributes on types.ModuleType if a symbol can't be found in locals or globals (#13904) | ||
![]() |
d988204b1b
|
[red-knot] add Declarations support to semantic indexing (#13334)
Add support for declared types to the semantic index. This involves a lot of renaming to clarify the distinction between bindings and declarations. The Definition (or more specifically, the DefinitionKind) becomes responsible for determining which definitions are bindings, which are declarations, and which are both, and the symbol table building is refactored a bit so that the `IS_BOUND` (renamed from `IS_DEFINED` for consistent terminology) flag is always set when a binding is added, rather than being set separately (and requiring us to ensure it is set properly). The `SymbolState` is split into two parts, `SymbolBindings` and `SymbolDeclarations`, because we need to store live bindings for every declaration and live declarations for every binding; the split lets us do this without storing more than we need. The massive doc comment in `use_def.rs` is updated to reflect bindings vs declarations. The `UseDefMap` gains some new APIs which are allow-unused for now, since this PR doesn't yet update type inference to take declarations into account. |
||
![]() |
3c4ec82aee
|
[red-knot] support non-local name lookups (#13177)
Add support for non-local name lookups. There's one TODO around annotated assignments without a RHS; these need a fair amount of attention, which they'll get in an upcoming PR about declared vs inferred types. Fixes #11663 |
||
![]() |
7027344dfc
|
Add scope and definitions for comprehensions (#12748)
## Summary This PR adds scope and definition for comprehension nodes. This includes the following nodes: * List comprehension * Dictionary comprehension * Set comprehension * Generator expression ### Scope Each expression here adds it's own scope with one caveat - the `iter` expression of the first generator is part of the parent scope. For example, in the following code snippet the `iter1` variable is evaluated in the outer scope. ```py [x for x in iter1] ``` > The iterable expression in the leftmost for clause is evaluated directly in the enclosing scope and then passed as an argument to the implicitly nested scope. > > Reference: https://docs.python.org/3/reference/expressions.html#displays-for-lists-sets-and-dictionaries There's another special case for assignment expressions: > There is one special case: an assignment expression occurring in a list, set or dict comprehension or in a generator expression (below collectively referred to as “comprehensions”) binds the target in the containing scope, honoring a nonlocal or global declaration for the target in that scope, if one exists. > > Reference: https://peps.python.org/pep-0572/#scope-of-the-target For example, in the following code snippet, the variables `a` and `b` are available after the comprehension while `x` isn't: ```py [a := 1 for x in range(2) if (b := 2)] ``` ### Definition Each comprehension node adds a single definition, the "target" variable (`[_ for target in iter]`). This has been accounted for and a new variant has been added to `DefinitionKind`. ### Type Inference Currently, type inference is limited to a single scope. It doesn't _enter_ in another scope to infer the types of the remaining expressions of a node. To accommodate this, the type inference for a **scope** requires new methods which _doesn't_ infer the type of the `iter` expression of the leftmost outer generator (that's defined in the enclosing scope). The type inference for the scope region is split into two parts: * `infer_generator_expression` (similarly for comprehensions) infers the type of the `iter` expression of the leftmost outer generator * `infer_generator_expression_scope` (similarly for comprehension) infers the type of the remaining expressions except for the one mentioned in the previous point The type inference for the **definition** also needs to account for this special case of leftmost generator. This is done by defining a `first` boolean parameter which indicates whether this comprehension definition occurs first in the enclosing expression. ## Test Plan New test cases were added to validate multiple scenarios. Refer to the documentation for each test case which explains what is being tested. |
||
![]() |
2d3914296d
|
[red-knot] handle all syntax without panic (#12499)
Extend red-knot type inference to cover all syntax, so that inferring types for a scope gives all expressions a type. This means we can run the red-knot semantic lint on all Python code without panics. It also means we can infer types for `builtins.pyi` without panics. To keep things simple, this PR intentionally doesn't add any new type inference capabilities: the expanded coverage is all achieved with `Type::Unknown`. But this puts the skeleton in place for adding better inference of all these language features. I also had to add basic Salsa cycle recovery (with just `Type::Unknown` for now), because some `builtins.pyi` definitions are cyclic. To test this, I added a comprehensive corpus of test snippets sourced from Cinder under [MIT license](https://github.com/facebookincubator/cinder/blob/cinder/3.10/cinderx/LICENSE), which matches Ruff's license. I also added to this corpus some additional snippets for newer language features: all the `27_func_generic_*` and `73_class_generic_*` files, as well as `20_lambda_default_arg.py`, and added a test which runs semantic-lint over all these files. (The test doesn't assert the test-corpus files are lint-free; just that they are able to lint without a panic.) |
||
![]() |
eac965ecaf
|
[red-knot] Watch search paths (#12407) | ||
![]() |
181e7b3c0d
|
[red-knot] rename module_global to global (#12385)
Per comments in https://github.com/astral-sh/ruff/pull/12269, "module global" is kind of long, and arguably redundant. I tried just using "module" but there were too many cases where I felt this was ambiguous. I like the way "global" works out better, though it does require an understanding that in Python "global" generally means "module global" not "globally global" (though in a sense module globals are also globally global since modules are singletons). |
||
![]() |
519eca9fe7
|
[red-knot] support implicit global name lookups (#12374)
Support falling back to a global name lookup if a name isn't defined in the local scope, in the cases where that is correct according to Python semantics. In class scopes, a name lookup checks the local namespace first, and if the name isn't found there, looks it up in globals. In function scopes (and type parameter scopes, which are function-like), if a name has any definitions in the local scope, it is a local, and accessing it when none of those definitions have executed yet just results in an `UnboundLocalError`, it does not fall back to a global. If the name does not have any definitions in the local scope, then it is an implicit global. Public symbol type lookups never include such a fall back. For example, if a name is not defined in a class scope, it is not available as a member on that class, even if a name lookup within the class scope would have fallen back to a global lookup. This PR makes the `@override` lint rule work again. Not yet included/supported in this PR: * Support for free variables / closures: a free symbol in a nested function-like scope referring to a symbol in an outer function-like scope. * Support for `global` and `nonlocal` statements, which force a symbol to be treated as global or nonlocal even if it has definitions in the local scope. * Module-global lookups should fall back to builtins if the name isn't found in the module scope. I would like to expose nicer APIs for the various kinds of symbols (explicit global, implicit global, free, etc), but this will also wait for a later PR, when more kinds of symbols are supported. |
||
![]() |
595b1aa4a1
|
[red-knot] per-definition inference, use-def maps (#12269)
Implements definition-level type inference, with basic control flow (only if statements and if expressions so far) in Salsa. There are a couple key ideas here: 1) We can do type inference queries at any of three region granularities: an entire scope, a single definition, or a single expression. These are represented by the `InferenceRegion` enum, and the entry points are the salsa queries `infer_scope_types`, `infer_definition_types`, and `infer_expression_types`. Generally per-scope will be used for scopes that we are directly checking and per-definition will be used anytime we are looking up symbol types from another module/scope. Per-expression should be uncommon: used only for the RHS of an unpacking or multi-target assignment (to avoid re-inferring the RHS once per symbol defined in the assignment) and for test nodes in type narrowing (e.g. the `test` of an `If` node). All three queries return a `TypeInference` with a map of types for all definitions and expressions within their region. If you do e.g. scope-level inference, when it hits a definition, or an independently-inferable expression, it should use the relevant query (which may already be cached) to get all types within the smaller region. This avoids double-inferring smaller regions, even though larger regions encompass smaller ones. 2) Instead of building a control-flow graph and lazily traversing it to find definitions which reach a use of a name (which is O(n^2) in the worst case), instead semantic indexing builds a use-def map, where every use of a name knows which definitions can reach that use. We also no longer track all definitions of a symbol in the symbol itself; instead the use-def map also records which defs remain visible at the end of the scope, and considers these the publicly-visible definitions of the symbol (see below). Major items left as TODOs in this PR, to be done in follow-up PRs: 1) Free/global references aren't supported yet (only lookup based on definitions in current scope), which means the override-check example doesn't currently work. This is the first thing I'll fix as follow-up to this PR. 2) Control flow outside of if statements and expressions. 3) Type narrowing. There are also some smaller relevant changes here: 1) Eliminate `Option` in the return type of member lookups; instead always return `Type::Unbound` for a name we can't find. Also use `Type::Unbound` for modules we can't resolve (not 100% sure about this one yet.) 2) Eliminate the use of the terms "public" and "root" to refer to module-global scope or symbols. Instead consistently use the term "module-global". It's longer, but it's the clearest, and the most consistent with typical Python terminology. In particular I don't like "public" for this use because it has other implications around author intent (is an underscore-prefixed module-global symbol "public"?). And "root" is just not commonly used for this in Python. 3) Eliminate the `PublicSymbol` Salsa ingredient. Many non-module-global symbols can also be seen from other scopes (e.g. by a free var in a nested scope, or by class attribute access), and thus need to have a "public type" (that is, the type not as seen from a particular use in the control flow of the same scope, but the type as seen from some other scope.) So all symbols need to have a "public type" (here I want to keep the use of the term "public", unless someone has a better term to suggest -- since it's "public type of a symbol" and not "public symbol" the confusion with e.g. initial underscores is less of an issue.) At least initially, I would like to try not having special handling for module-global symbols vs other symbols. 4) Switch to using "definitions that reach end of scope" rather than "all definitions" in determining the public type of a symbol. I'm convinced that in general this is the right way to go. We may want to refine this further in future for some free-variable cases, but it can be changed purely by making changes to the building of the use-def map (the `public_definitions` index in it), without affecting any other code. One consequence of combining this with no control-flow support (just last-definition-wins) is that some inference tests now give more wrong-looking results; I left TODO comments on these tests to fix them when control flow is added. And some potential areas for consideration in the future: 1) Should `symbol_ty` be a Salsa query? This would require making all symbols a Salsa ingredient, and tracking even more dependencies. But it would save some repeated reconstruction of unions, for symbols with multiple public definitions. For now I'm not making it a query, but open to changing this in future with actual perf evidence that it's better. |
||
![]() |
ac04380f36
|
[red-knot] Rename FileSystem to System (#12214)
|
||
![]() |
0e44235981
|
[red-knot] intern types using Salsa (#12061)
Intern types using Salsa interning instead of in the `TypeInference` result. This eliminates the need for `TypingContext`, and also paves the way for finer-grained type inference queries. |
||
![]() |
3ce8b9fcae
|
Make Definition a salsa-ingredient (#12151)
|
||
![]() |
dcb9523b1e
|
Address review feedback from 11963 (#12145) | ||
![]() |
228b1c4235
|
[red-knot] Remove Scope::name (#12137)
|
||
![]() |
37f260b5af
|
Introduce HasTy trait and SemanticModel facade (#11963)
|
||
![]() |
5109b50bb3
|
Use CompactString for Identifier (#12101)
|
||
![]() |
927069c12f
|
[red-knot] Upgrade to Salsa 3.0 (#11952) | ||
![]() |
b456051be8
|
[red-knot] Add tracing to Salsa queries (#11949) | ||
![]() |
2dfbf118d7
|
[red-knot] Extract red_knot_python_semantic crate (#11926)
|
Renamed from crates/ruff_python_semantic/src/red_knot/semantic_index/symbol.rs (Browse further)