Commit graph

10296 commits

Author SHA1 Message Date
renovate[bot]
396a7162d6
Update Rust crate ctrlc to v3.4.6 (#17246) 2025-04-06 22:01:24 -04:00
renovate[bot]
040f80ab68
Update Rust crate clap to v4.5.35 (#17245) 2025-04-06 22:01:18 -04:00
Micha Reiser
67f8c30b53
[red-knot] Remove global dead_code from red-knot-server (#17229)
## Summary

Use more local `expect(dead_code)` suppressions instead of a global
`allow(dead_code)` in `lib.rs`.

Remove some methods that are either easy to add later, are less likely
to be needed for red knot, or it's unclear if we'd add it the same way
as in ruff.
2025-04-06 22:09:24 +01:00
Micha Reiser
e01d228a71
[playground] Provide fallback monospace-font (#17242)
<img width="1679" alt="Screenshot 2025-04-06 at 22 51 43"
src="https://github.com/user-attachments/assets/ccd9dd1a-67cd-4bc3-a22a-f3c530b8670d"
/>
2025-04-06 21:57:20 +01:00
Micha Reiser
51bdb87fd8
[red-knot] Fix loading color in dark mode (#17237)
Some checks are pending
CI / cargo clippy (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
## Summary

The loading indicator on dark mode isn't "visible" because it's black on
black. Use white as text color instead.
2025-04-06 18:30:21 +01:00
Alex Waygood
ac5d220d75
[red-knot] Fix python setting in mdtests, and rewrite a site-packages test as an mdtest (#17222)
## Summary

This PR does the following things:
- Fixes the `python` configuration setting for mdtest (added in
https://github.com/astral-sh/ruff/pull/17221) so that it expects a path
pointing to a venv's `sys.prefix` variable rather than the a path
pointing to the venv's `site-packages` subdirectory. This brings the
`python` setting in mdtest in sync with our CLI `--python` flag.
- Tweaks mdtest so that it automatically creates a valid `pyvenv.cfg`
file for you if you don't specify one. This makes it much more ergonomic
to write an mdtest with a custom `python` setting: red-knot will reject
a `python` setting that points to a directory that doesn't have a
`pyvenv.cfg` file in it
- Tweaks mdtest so that it doesn't check a custom `pyvenv.cfg` as Python
source code if you _do_ add a custom `pyvenv.cfg` file for your mock
virtual environment in an mdtest. (You get a lot of diagnostics about
Python syntax errors in the `pyvenv.cfg` file, otherwise!)
- Rewrites the test added in
https://github.com/astral-sh/ruff/pull/17178 as an mdtest, and deletes
the original test that was added in that PR

## Test Plan

I verified that the new mdtest fails if I revert the changes to
`resolver.rs` that were added in
https://github.com/astral-sh/ruff/pull/17178
2025-04-06 18:24:32 +01:00
Matthew Mckee
73a9974d8a
Fix CallableTypeOf display signature (#17235) 2025-04-06 18:12:52 +01:00
Micha Reiser
3dd6d0a422
[playground] Add Reset button (#17236)
## Summary

Add a *Reset* button to both Ruff's and Red Knot's playground that
resets the playground to its initial state.

Closes https://github.com/astral-sh/ruff/issues/17195

## Test Plan



https://github.com/user-attachments/assets/753cca19-155a-44b1-89ba-76744487a55d


https://github.com/user-attachments/assets/7d19f04c-70f4-4d9e-b745-0486cb1d4993
2025-04-06 17:09:56 +00:00
Micha Reiser
4571c5f56f
[red-knot] Simplify playground editor state (#17223)
Some checks are pending
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
## Summary
Reduce the number of `useRef`s in `Editor`
2025-04-05 19:49:08 +02:00
Micha Reiser
1c652e6b98
[red-knot] Allow setting python in mdtests (#17221)
## Summary

This PR extends the mdtest options to allow setting the
`environment.python` option.

## Test Plan

I let @AlexWaygood write a test and he'll tell me if it works 😆
2025-04-05 16:43:31 +02:00
renovate[bot]
172af7b4b0
Update dependency vite to v6.2.5 (#17211)
Some checks are pending
CI / cargo fuzz build (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [vite](https://vite.dev)
([source](https://redirect.github.com/vitejs/vite/tree/HEAD/packages/vite))
| [`6.2.4` ->
`6.2.5`](https://renovatebot.com/diffs/npm/vite/6.2.4/6.2.5) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/vite/6.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vite/6.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vite/6.2.4/6.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vite/6.2.4/6.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

### GitHub Vulnerability Alerts

####
[CVE-2025-31486](https://redirect.github.com/vitejs/vite/security/advisories/GHSA-xcj6-pq6g-qj4x)

### Summary

The contents of arbitrary files can be returned to the browser.

### Impact

Only apps explicitly exposing the Vite dev server to the network (using
--host or [server.host config
option](https://vitejs.dev/config/server-options.html#server-host)) are
affected..

### Details

#### `.svg`

Requests ending with `.svg` are loaded at this line.

037f801075/packages/vite/src/node/plugins/asset.ts (L285-L290)
By adding `?.svg` with `?.wasm?init` or with `sec-fetch-dest: script`
header, the restriction was able to bypass.

This bypass is only possible if the file is smaller than
[`build.assetsInlineLimit`](https://vite.dev/config/build-options.html#build-assetsinlinelimit)
(default: 4kB) and when using Vite 6.0+.

#### relative paths

The check was applied before the id normalization. This allowed requests
to bypass with relative paths (e.g. `../../`).

### PoC

```bash
npm create vite@latest
cd vite-project/
npm install
npm run dev
```

send request to read `etc/passwd`

```bash
curl 'http://127.0.0.1:5173/etc/passwd?.svg?.wasm?init'
```

```bash
curl 'http://127.0.0.1:5173/@&#8203;fs/x/x/x/vite-project/?/../../../../../etc/passwd?import&?raw'
```

---

### Release Notes

<details>
<summary>vitejs/vite (vite)</summary>

###
[`v6.2.5`](https://redirect.github.com/vitejs/vite/releases/tag/v6.2.5)

[Compare
Source](https://redirect.github.com/vitejs/vite/compare/v6.2.4...v6.2.5)

Please refer to
[CHANGELOG.md](https://redirect.github.com/vitejs/vite/blob/v6.2.5/packages/vite/CHANGELOG.md)
for details.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "" (UTC), Automerge - At any time (no
schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/astral-sh/ruff).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMjcuMyIsInVwZGF0ZWRJblZlciI6IjM5LjIyNy4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJpbnRlcm5hbCIsInNlY3VyaXR5Il19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-05 08:28:01 +01:00
cake-monotone
7e6d3838bd
[red-knot] Add cycle handling to narrow constraints queries (#17209)
## Summary

This PR fixes the cycle issue that was causing problems in the `support
super` PR.

### Affected queries
- `all_narrowing_constraints_for_expression`
- `all_negative_narrowing_constraints_for_expression`


--

Additionally, `bidict` and `werkzeug` have been added to the
project-selection list in `mypy_primer`.
This PR also addresses the panics that occurred while analyzing those
packages:

- `bidict`: panic triggered by
`all_narrowing_constraints_for_expression`
- `werkzeug`: panic triggered by
`all_negative_narrowing_constraints_for_expression`

I think the mypy-primer results for this PR can serve as sufficient test
:)
2025-04-04 22:26:20 -07:00
David Peter
1a6a10b30f
[red-knot] Empty tuple is always-falsy (#17213)
Some checks are pending
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
## Summary

Fix assignability of `tuple[()]` to `AlwaysFalsy`.

closes #17202 

## Test Plan

Ran the property tests for a while
2025-04-04 22:00:28 +02:00
Brent Westbrook
b3243b5e2a
Run fuzzer with --preview (#17210)
Summary
--

Updates `fuzz.py` to run with `--preview`, which should allow it to
catch semantic syntax errors.

Test Plan
--

@AlexWaygood and I temporarily made any named expression a semantic
syntax error and checked that this led to fuzzing errors. We also tested
that reverting the `--preview` addition did not show any errors.

We also ran the fuzzer on 500 seeds on `main` but didn't find any
issues, (un)fortunately.
2025-04-04 15:13:59 -04:00
Brent Westbrook
95d6ed40cc
Bump 0.11.4 (#17212) 2025-04-04 14:09:10 -04:00
Brent Westbrook
acc5662e8b
[syntax-errors] Allow yield in base classes and annotations (#17206)
Summary
--

This PR fixes the issue pointed out by @JelleZijlstra in
https://github.com/astral-sh/ruff/pull/17101#issuecomment-2777480204.
Namely, I conflated two very different errors from CPython:

```pycon
>>> def m[T](x: (yield from 1)): ...
  File "<python-input-310>", line 1
    def m[T](x: (yield from 1)): ...
                 ^^^^^^^^^^^^
SyntaxError: yield expression cannot be used within the definition of a generic
>>> def m(x: (yield from 1)): ...
  File "<python-input-311>", line 1
    def m(x: (yield from 1)): ...
              ^^^^^^^^^^^^
SyntaxError: 'yield from' outside function
>>> def outer():
...     def m(x: (yield from 1)): ...
...
>>>
```

I thought the second error was the same as the first, but `yield` (and
`yield from`) is actually valid in this position when inside a function
scope. The same is true for base classes, as pointed out in the original
comment.

We don't currently raise an error for `yield` outside of a function, but
that should be handled separately.

On the upside, this had the benefit of removing the
`InvalidExpressionPosition::BaseClass` variant and the
`allow_named_expr` field from the visitor because they were both no
longer used.

Test Plan
--

Updated inline tests.
2025-04-04 13:48:28 -04:00
David Salvisberg
33a56f198b
Don't skip visiting non-tuple slice in typing.Annotated subscripts (#17201)
Some checks are pending
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
Fixes: #17196

## Summary

Skipping these nodes for malformed type expressions would lead to
incorrect semantic state, which can in turn mean we emit false positives
for rules like `unused-variable`(`F841`)

## Test Plan

`cargo nextest run`
2025-04-04 18:47:40 +05:30
David Peter
5cee346744
[red-knot] mypy_primer: do not specify Python version (#17200)
## Summary

* Pull in latest changes from upstream (which includes an update to a
`pyproject.toml` layout and a `uv.lock` file, which should make CI more
deterministic)
* Do not specify `--python-version 3.13` in Red Knot runs


https://github.com/astral-sh/mypy_primer/compare/add-red-knot-support-v2...astral-sh:mypy_primer:add-red-knot-support-v3

## Test Plan

Tested locally
2025-04-04 13:55:40 +02:00
Micha Reiser
ffa824e037
[red-knot] Add Type.definition method (#17153)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
## Summary

This is a follow up to the goto type definition PR. Specifically, that
we want to avoid exposing too many semantic model internals publicly.

I want to get some feedback on the approach taken. I think it goes into
the right direction but I'm not super happy with it.
The basic idea is that we add a `Type::definition` method which does the
"goto type definition". The parts that I think make it awkward:

* We can't directly return `Definition` because we don't create a
`Definition` for modules (but we could?). Although I think it makes
sense to possibly have a more public wrapper type anyway?
* It doesn't handle unions and intersections. Mainly because not all
elements in an intersection may have a definition and we only want to
show a navigation target for intersections if there's only a single
positive element (besides maybe `Unknown`).


An alternative design or an addition to this design is to introduce a
`SemanticAnalysis(Db)` struct that has methods like
`type_definition(&self, type)` which explicitly exposes the methods we
want. I don't feel comfortable design this API yet because it's unclear
how fine granular it has to be (and if it is very fine granular,
directly using `Type` might be better after all)


## Test Plan

`cargo test`
2025-04-04 10:56:20 +02:00
Max Mynter
98b95c9c38
Implement Invalid rule provided as rule RUF102 with --fix (#17138)
<!--
Thank you for contributing to Ruff! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

Closes #17084

## Summary
This PR adds a new rule (RUF102) to detect and fix invalid rule codes in
`noqa` comments.
Invalid rule codes in `noqa` directives serve no purpose and may
indicate outdated code suppressions.

This extends the previous behaviour originating from
`crates/ruff_linter/src/noqa.rs` which would only emit a warnigs.
With this rule a `--fix` is available.

The rule:
1. Analyzes all `noqa` directives to identify invalid rule codes
2. Provides autofix functionality to:
   - Remove the entire comment if all codes are invalid
   - Remove only the invalid codes when mixed with valid codes
3. Preserves original comment formatting and whitespace where possible

Example cases:
- `# noqa: XYZ111` → Remove entire comment (keep empty line)
- `# noqa: XYZ222, XYZ333` → Remove entire comment (keep empty line)
-  `# noqa: F401, INVALID123` → Keep only valid codes (`# noqa: F401`)

## Test Plan
- Added tests in
`crates/ruff_linter/resources/test/fixtures/ruff/RUF102.py` covering
different example cases.

<!-- How was it tested? -->

## Notes 
- This does not handle cases where parsing fails. E.g. `# noqa:
NON_EXISTENT, ANOTHER_INVALID` causes a `LexicalError` and the
diagnostic is not propagated and we cannot handle the diagnostic. I am
also unsure what proper `fix` handling would be and making the user
aware we don't understand the codes is probably the best bet.
- The rule is added to the Preview rule group as it's a new addition

## Questions
- Should we remove the warnings, now that we have a rule?
- Is the current fix behavior appropriate for all cases, particularly
the handling of whitespace and line deletions?
- I'm new to the codebase; let me know if there are rule utilities which
could have used but didn't.

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
2025-04-04 08:05:59 +00:00
Micha Reiser
a4ba10ff0a
[red-knot] Add basic on-hover to playground and LSP (#17057)
## Summary

Implement a very basic hover in the playground and LSP.

It's basic, because it only shows the type on-hover. Most other LSPs
also show:

* The signature of the symbol beneath the cursor. E.g. `class
Test(a:int, b:int)` (we want something like
54f7da25f9/packages/pyright-internal/src/analyzer/typeEvaluator.ts (L21929-L22129))
* The symbols' documentation
* Do more fancy markdown rendering

I decided to defer these features for now because it requires new
semantic APIs (similar to *goto definition*), and investing in fancy
rendering only makes sense once we have the relevant data.

Closes [#16826](https://github.com/astral-sh/ruff/issues/16826)

## Test Plan



https://github.com/user-attachments/assets/044aeee4-58ad-4d4e-9e26-ac2a712026be


https://github.com/user-attachments/assets/4a1f4004-2982-4cf2-9dfd-cb8b84ff2ecb
2025-04-04 08:13:43 +02:00
Carl Meyer
bf0306887a
[red-knot] don't remove negations when simplifying constrained typevars (#17189)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
For two non-disjoint types `P` and `Q`, the simplification of `(P | Q) &
~Q` is not `P`, but `P & ~Q`. In other words, the non-empty set `P & Q`
is also excluded from the type.

The same applies for a constrained typevar `[T: (P, Q)]`: `T & ~Q`
should simplify to `P & ~Q`, not just `P`.

Implementing this is actually purely a matter of removing code from the
constrained typevar simplification logic; we just need to not bother
removing the negations. If the negations are actually redundant (because
the constraint types are disjoint), normal intersection simplification
will already eliminate them (as shown in the added test.)
2025-04-03 16:30:57 -07:00
Brent Westbrook
4f924bb975
[minor] Fix extra semicolon for clippy (#17188) 2025-04-03 18:17:00 -04:00
Brent Westbrook
c2b2e42ad3
[syntax-errors] Invalid syntax in annotations (#17101)
Summary
--

This PR detects the use of invalid syntax in annotation scopes,
including
`yield` and `yield from` expressions and named expressions. I combined a
few
different types of CPython errors here, but I think the resulting error
messages
still make sense and are even preferable to what CPython gives. For
example, we
report `yield expression cannot be used in a type annotation` for both
of these:

```pycon
>>> def f[T](x: (yield 1)): ...
  File "<python-input-26>", line 1
    def f[T](x: (yield 1)): ...
                 ^^^^^^^
SyntaxError: yield expression cannot be used within the definition of a generic
>>> def foo() -> (yield x): ...
  File "<python-input-28>", line 1
    def foo() -> (yield x): ...
                  ^^^^^^^
SyntaxError: 'yield' outside function
```

Fixes https://github.com/astral-sh/ruff/issues/11118.

Test Plan
--

New inline tests, along with some updates to existing tests.
2025-04-03 17:56:55 -04:00
Brent Westbrook
24b1b1d52c
[syntax-errors] Duplicate attributes in match class pattern (#17186)
Summary
--

Detects duplicate attributes in a `match` class pattern:

```python
match x:
    case Class(x=1, x=2): ...
```

which are more analogous to the similar check for mapping patterns than
to the
multiple assignments rule.

I also realized that both this and the mapping check would only work on
top-level patterns, despite the possibility that they can be nested
inside other
patterns:

```python
match x:
    case [{"x": 1, "x": 2}]: ...  # false negative in the old version
```

and moved these checks into the recursive pattern visitor instead.

I also tidied up some of the names like the `multiple_case_assignment`
function
and the `MultipleCaseAssignmentVisitor`, which are now doing more than
checking
for multiple assignments.

Test Plan
--

New inline tests for both classes and mappings.
2025-04-03 17:55:37 -04:00
Brent Westbrook
6a07dd227d
[syntax-errors] Fix multiple assignment for class keyword argument (#17184)
Summary
--

Fixes #17181. The cases being tested with multiple *keys* being equal
are actually a slightly different error, more like the error for
`MatchMapping` than like the other multiple assignment errors:

```pycon
>>> match x:
...     case Class(x=x, x=x): ...
...
  File "<python-input-249>", line 2
    case Class(x=x, x=x): ...
                      ^
SyntaxError: attribute name repeated in class pattern: x
>>> match x:
...     case {"x": 1, "x": 2}: ...
...
  File "<python-input-251>", line 2
    case {"x": 1, "x": 2}: ...
         ^^^^^^^^^^^^^^^^
SyntaxError: mapping pattern checks duplicate key ('x')
>>> match x:
...     case [x, x]: ...
...
  File "<python-input-252>", line 2
    case [x, x]: ...
             ^
SyntaxError: multiple assignments to name 'x' in pattern
```

This PR just stops the false positive reported in the issue, but I will
quickly follow it up with a new rule (or possibly combined with the
mapping rule) catching the repeated attributes separately.

Test Plan
--

New inline `test_ok` and updating the `test_err` cases to have duplicate
values instead of keys.
2025-04-03 17:32:39 -04:00
Aria Desires
8aa5686e63
use astral-sh/cargo-dist instead (#17187) 2025-04-03 17:25:12 -04:00
Micha Reiser
e7684d3493
Enable overindented docs lint (#17182)
## Summary

It turns out that `a.` isn't a list format supported by rustdoc. I
changed the documentation to use `1.`, `2.` instead.

## Test Plan

`cargo clippy`
2025-04-03 20:27:11 +01:00
Douglas Creager
64e7e1aa64
[red-knot] Add Type::TypeVar variant (#17102)
This adds a new `Type` variant for holding an instance of a typevar
inside of a generic function or class. We don't handle specializing the
typevars yet, but this should implement most of the typing rules for
inside the generic function/class, where we don't know yet which
specific type the typevar will be specialized to.

This PR does _not_ yet handle the constraint that multiple occurrences
of the typevar must be specialized to the _same_ time. (There is an
existing test case for this in `generics/functions.md` which is still
marked as TODO.)

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Carl Meyer <carl@astral.sh>
2025-04-03 14:36:29 -04:00
Carl Meyer
45c43735e0
[red-knot] update to latest Salsa with fixpoint caching fix (#17179)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
With this PR, we no longer "hang" (not actually a hang, just an
explosion in execution time) when checking pylint.
2025-04-03 09:05:09 -07:00
Micha Reiser
8a4158c5f8
Upgrade to Rust 1.86 and bump MSRV to 1.84 (#17171)
<!--
Thank you for contributing to Ruff! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

I decided to disable the new
[`needless_continue`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue)
rule because I often found the explicit `continue` more readable over an
empty block or having to invert the condition of an other branch.


## Test Plan

`cargo test`

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-04-03 15:59:44 +00:00
David Peter
fedd982fd5
[red-knot] Avoid unresolved-reference in unreachable code (#17169)
## Summary

This PR changes the inferred type for symbols in unreachable sections of
code to `Never` (instead of reporting them as unbound), in order to
silence false positive diagnostics. See the lengthy comment in the code
for further details.

## Test Plan

- Updated Markdown tests.
- Manually verified a couple of ecosystem diagnostic changes.
2025-04-03 16:52:11 +02:00
Alex Waygood
a1eb834a5f
Fix relative import resolution in site-packages packages when the site-packages search path is a subdirectory of the first-party search path (#17178)
## Summary

If a package in `site-packages` had this directory structure:

```py
# bar/__init__.py
from .a import A

# bar/a.py
class A: ...
```

then we would fail to resolve the `from .a import A` import _if_ (as is
usually the case!) the `site-packages` search path was located inside a
`.venv` directory that was a subdirectory of the project's first-party
search path. The reason for this is a bug in `file_to_module` in the
module resolver. In this loop, we would identify that
`/project_root/.venv/lib/python3.13/site-packages/foo/__init__.py` can
be turned into a path relative to the first-party search path
(`/project_root`):


6e2b8f9696/crates/red_knot_python_semantic/src/module_resolver/resolver.rs (L101-L110)

but we'd then try to turn the relative path
(.venv/lib/python3.13/site-packages/foo/__init__.py`) into a module
path, realise that it wasn't a valid module path... and therefore
immediately `break` out of the loop before trying any other search paths
(such as the `site-packages` search path).

This bug was originally reported on Discord by @MatthewMckee4.

## Test Plan

I added a unit test for `file_to_module` in `resolver.rs`, and an
integration test that shows we can now resolve the import correctly in
`infer.rs`.
2025-04-03 15:48:05 +01:00
Carl Meyer
c1f93a702c
[DO NOT LAND] bump Salsa version (#17176)
Update to latest Salsa main branch, so as to get a baseline for
measuring the perf effect of https://github.com/salsa-rs/salsa/pull/786
on red-knot in isolation from other recent changes in Salsa main branch.
2025-04-03 14:31:41 +00:00
Brent Westbrook
6e2b8f9696
[syntax-errors] Detect duplicate keys in match mapping patterns (#17129)
Summary
--

Detects duplicate literals in `match` mapping keys.

This PR also adds a `source` method to `SemanticSyntaxContext` to
display the duplicated key in the error message by slicing out its
range.

Test Plan
--

New inline tests.
2025-04-03 10:22:37 -04:00
Alex Waygood
ca0cce3f9c
[red-knot] Fix more [redundant-cast] false positives (#17170)
Fixes #17164. Simply checking whether one type is gradually equivalent
to another is too simplistic here: `Any` is gradually equivalent to
`Todo`, but we should permit users to cast from `Todo` or `Unknown` to
`Any` without complaining about it. This changes our logic so that we
only complain about redundant casts if:
- the two types are exactly equal (when normalized) OR they are
equivalent (we'll still complain about `Any -> Any` casts, and about
`Any | str | int` -> `str | int | Any` casts, since their normalized
forms are exactly equal, even though the type is not fully static -- and
therefore does not participate in equivalence relations)
- AND the casted type does not contain `Todo`
2025-04-03 15:00:00 +01:00
David Peter
3f00010a7a
[red-knot] Three-argument type-calls take 'str' as the first argument (#17168)
## Summary

Similar to #17163, a minor fix in the signature of `type(…)`.

## Test Plan

New MD tests
2025-04-03 15:45:08 +02:00
Dylan
d401a5440e
Control flow: return and raise (#17121)
We add support for `return` and `raise` statements in the control flow
graph: we simply add an edge to the terminal block, push the statements
to the current block, and proceed.

This implementation will have to be modified somewhat once we add
support for `try` statements - then we will need to check whether to
_defer_ the jump. But for now this will do!

Also in this PR: We fix the `unreachable` diagnostic range so that it
lumps together consecutive unreachable blocks.
2025-04-03 08:30:29 -05:00
Brent Westbrook
755ece0c36
Bump 0.11.3 (#17173) 2025-04-03 09:05:40 -04:00
Alex Waygood
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).
2025-04-03 13:37:29 +01:00
David Peter
130339f3d8
[red-knot] Fix str(…) calls (#17163)
## Summary

The existing signature for `str` calls had various problems, one of
which I noticed while looking at some ecosystem projects (`scrapy`,
added as a project to mypy_primer in this PR).

## Test Plan

- New tests for `str(…)` calls.
- Observed reduction of false positives in ecosystem checks
2025-04-03 13:26:32 +02:00
Eric Mark Martin
e50fc049ab
[red-knot] visibility_constraint analysis for match cases (#17077)
## Summary

Add visibility constraint analysis for pattern predicate kinds
`Singleton`, `Or`, and `Class`.

## Test Plan

update conditional/match.md
2025-04-03 11:15:33 +00:00
Micha Reiser
66355a6185
[red-knot] Fix playground crashes when diagnostics are stale (#17165)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
## Summary

Fixes a crash in the playground where it crashed with an "index out of
bounds" error in the `Diagnostic::to_range` call
after deleting content at the end of the file. 

The root cause was that the playground uses `useDeferred` to avoid too
frequent `checkFile` calls (to get a smoother UX).
However, this has the problem that the rendered `diagnostics` can be
stable (from before the last change).
Rendering the diagnostics can then fail because the `toRange` call
queries the latest content and not the content
from when the diagnostics were created.

The fix is "easy" in the sense that we now eagerly perform the `toRange`
calls. This way, it doesn't matter
when the diagnostics are stale for a few ms. 

This problem can only be observed on examples where Red Knot is "slow"
(takes more than ~16ms to check) because
only then does `useDeferred` "debounce" the `check` calls.
2025-04-03 10:18:36 +02:00
Dhruv Manilawala
177afabe18
[red-knot] Callable types are disjoint from literals (#17160)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
## Summary

A callable type is disjoint from other literal types. For example,
`Type::StringLiteral` must be an instance of exactly `str`, not a
subclass of `str`, and `str` is not callable. The same applies to other
literal types.

This should hopefully fix #17144, I couldn't produce any failures after
running property tests multiple times.

## Test Plan

Add test cases for disjointness check between callable and other literal
types.

Run property tests multiple times.
2025-04-03 03:38:13 +05:30
Alex Waygood
28c68934a4
[red-knot] Fix inference for pow between two literal integers (#17161)
## Summary

Python `**` works differently to Rust `**`!

## Test Plan

Added an mdtest for various edge cases, and checked in the Python REPL
that we infer the correct type in all the new cases tested.
2025-04-02 21:25:57 +00:00
Alex Waygood
195bb433db
[red-knot] Add GitHub PR annotations when mdtests fail in CI (#17150)
## Summary

This PR adds a CI job that causes GitHub to add annotations to a PR diff
when mdtest assertions fail. For example:

<details>
<summary>Screenshot</summary>


![image](https://github.com/user-attachments/assets/bb2a649b-46ab-429d-a576-b36545940eaf)

</details>

## Motivation

Debugging mdtest failures locally is currently a really nice experience:
- Errors are displayed with pretty colours, which makes them much more
readable
- If you run the test from inside an IDE, you can CTRL-click on a path
and jump directly to the line that had the failing assertion
- If you use
[`mdtest.py`](https://github.com/astral-sh/ruff/blob/main/crates/red_knot_python_semantic/mdtest.py),
you don't even need to recompile anything after changing an assertion in
an mdtest, amd the test results instantly live-update with each change
to the MarkDown file

Debugging mdtest failures in CI is much more unpleasant, however.
Sometimes an error message is just

> [static-assert-error] Argument evaluates to `False`

...which doesn't tell you very much unless you navigate to the line in
question that has the failing mdtest assertion. The line in question
might not even be touched by the PR, and even if it is, it can be hard
to find the line if the PR touches many files. Unlike locally, you can't
click on the error and jump straight to the line that contains the
failing assertion. You also don't get colourised output in CI
(https://github.com/astral-sh/ruff/issues/13939).

GitHub PR annotations should make it really easy to debug why mdtests
are failing on PRs, making PR review much easier.

## Test Plan

I opened a PR to my fork
[here](https://github.com/AlexWaygood/ruff/pull/11/files) with some
bogus changes to an mdtest to show what it looks like when there are
failures in CI and this job has been added. Scroll down to
`crates/red_knot_python_semantic/resources/mdtest/type_properties/is_equivalent_to.md`
on the "files changed" tab for that PR to see the annotations.
2025-04-02 21:51:52 +01:00
Alex Waygood
c2bb5d5250
[red-knot] Fix equivalence of differently ordered unions that contain Callable types (#17145)
## Summary

Fixes https://github.com/astral-sh/ruff/issues/17058.

Equivalent callable types were not understood as equivalent when they
appeared nested inside unions and intersections. This PR fixes that by
ensuring that `Callable` elements nested inside unions, intersections
and tuples have their representations normalized before one union type
is compared with another for equivalence, or before one intersection
type is compared with another for equivalence.

The normalizations applied to a `Callable` type are:
- the type of the default value is stripped from all parameters (only
whether the parameter _has_ a default value is relevant to whether one
`Callable` type is equivalent to another)
- The names of the parameters are stripped from positional-only
parameters, variadic parameters and keyword-variadic parameters
- Unions and intersections that are present (top-level or nested) inside
parameter annotations or return annotations are normalized.

Adding a `CallableType::normalized()` method also allows us to simplify
the implementation of `CallableType::is_equivalent_to()`.

### Should these normalizations be done eagerly as part of a
`CallableType` constructor?

I considered this. It's something that we could still consider doing in
the future; this PR doesn't rule it out as a possibility. However, I
didn't pursue it for now, for several reasons:
1. Our current `Display` implementation doesn't handle well the
possibility that a parameter might not have a name or an annotated type.
Callable types with parameters like this would be displayed as follows:
   ```py
   (, ,) -> None: ...
   ```

That's fixable! It could easily become something like `(Unknown,
Unknown) -> None: ...`. But it also illustrates that we probably want to
retain the parameter names when displaying the signature of a `lambda`
function if you're hovering over a reference to the lambda in an IDE.
Currently we don't have a `LambdaType` struct for representing `lambda`
functions; if we wanted to eagerly normalize signatures when creating
`CallableType`s, we'd probably have to add a `LambdaType` struct so that
we would retain the full signature of a `lambda` function, rather than
representing it as an eagerly simplified `CallableType`.
2. In order to ensure that it's impossible to create `CallableType`s
without the parameters being normalized, I'd either have to create an
alternative `SimplifiedSignature` struct (which would duplicate a lot of
code), or move `CallableType` to a new module so that the only way of
constructing a `CallableType` instance would be via a constructor method
that performs the normalizations eagerly on the callable's signature.
Again, this isn't a dealbreaker, and I think it's still an option, but
it would be a lot of churn, and it didn't seem necessary for now. Doing
it this way, at least to start with, felt like it would create a diff
that's easier to review and felt like it would create fewer merge
conflicts for others.

## Test Plan

- Added a regression mdtest for
https://github.com/astral-sh/ruff/issues/17058
- Ran `QUICKCHECK_TESTS=1000000 cargo test --release -p
red_knot_python_semantic -- --ignored types::property_tests::stable`
2025-04-02 17:43:34 +00:00
David Peter
cb7dae1e96
[red-knot] Add initial set of tests for unreachable code (#17159)
## Summary

Add an initial set of tests that will eventually document our behavior
around unreachable code. In the last section of this suite, I argue why
we should never type check unreachable sections and never emit any
diagnostics in these sections.
2025-04-02 19:39:44 +02:00
Wei Lee
8833484b10
[airflow] Move AIR302 to AIR301 and AIR303 to AIR302 (#17151)
## Summary

Following up the discussion in
https://github.com/astral-sh/ruff/issues/14626#issuecomment-2766548545,
we're to reorganize airflow rules. Before this discussion happens, we
combine required changes and suggested changes in to one single error
code.

This PR first rename the original error code to the new error code as we
discussed. We will gradually extract suggested changes out of AIR301 and
AIR302 to AIR311 and AIR312 in the following PRs

## Test Plan

Except for file, error code rename, the test case should work as it used
to be.
2025-04-02 23:01:31 +05:30
Andrew Gallant
adeba3dca7 ruff_db: simplify lifetimes on DiagnosticDisplay
I initially split the lifetime out into three distinct lifetimes on
near-instinct because I moved the struct into the public API. But
because they are all shared borrows, and because there are no other APIs
on `DisplayDiagnostic` to access individual fields (and probably never
will be), it's probably fine to just specify one lifetime. Because of
subtyping, the one lifetime will be the shorter of the three.

There's also the point that `ruff_db` isn't _really_ a public API, since
it isn't a library that others depend on. So my instinct is probably a
bit off there.
2025-04-02 12:47:02 -04:00