ruff/crates
David Peter 03d8679adf
[red-knot] Preliminary `NamedTuple` support (#17738)
## Summary

Adds preliminary support for `NamedTuple`s, including:
* No false positives when constructing a `NamedTuple` object
* Correct signature for the synthesized `__new__` method, i.e. proper
checking of constructor calls
* A patched MRO (`NamedTuple` => `tuple`), mainly to make type inference
of named attributes possible, but also to better reflect the runtime
MRO.

All of this works:
```py
from typing import NamedTuple

class Person(NamedTuple):
    id: int
    name: str
    age: int | None = None

alice = Person(1, "Alice", 42)
alice = Person(id=1, name="Alice", age=42)

reveal_type(alice.id)  # revealed: int
reveal_type(alice.name)  # revealed: str
reveal_type(alice.age)  # revealed: int | None

# error: [missing-argument]
Person(3)

# error: [too-many-positional-arguments]
Person(3, "Eve", 99, "extra")

# error: [invalid-argument-type]
Person(id="3", name="Eve")
```

Not included:
* type inference for index-based access.
* support for the functional `MyTuple = NamedTuple("MyTuple", […])`
syntax

## Test Plan

New Markdown tests

## Ecosystem analysis

```
                          Diagnostic Analysis Report                           
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━┓
┃ Diagnostic ID                     ┃ Severity ┃ Removed ┃ Added ┃ Net Change ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━┩
│ lint:call-non-callable            │ error    │       0 │     3 │         +3 │
│ lint:call-possibly-unbound-method │ warning  │       0 │     4 │         +4 │
│ lint:invalid-argument-type        │ error    │       0 │    72 │        +72 │
│ lint:invalid-context-manager      │ error    │       0 │     2 │         +2 │
│ lint:invalid-return-type          │ error    │       0 │     2 │         +2 │
│ lint:missing-argument             │ error    │       0 │    46 │        +46 │
│ lint:no-matching-overload         │ error    │   19121 │     0 │     -19121 │
│ lint:not-iterable                 │ error    │       0 │     6 │         +6 │
│ lint:possibly-unbound-attribute   │ warning  │      13 │    32 │        +19 │
│ lint:redundant-cast               │ warning  │       0 │     1 │         +1 │
│ lint:unresolved-attribute         │ error    │       0 │    10 │        +10 │
│ lint:unsupported-operator         │ error    │       3 │     9 │         +6 │
│ lint:unused-ignore-comment        │ warning  │      15 │     4 │        -11 │
├───────────────────────────────────┼──────────┼─────────┼───────┼────────────┤
│ TOTAL                             │          │   19152 │   191 │     -18961 │
└───────────────────────────────────┴──────────┴─────────┴───────┴────────────┘

Analysis complete. Found 13 unique diagnostic IDs.
Total diagnostics removed: 19152
Total diagnostics added: 191
Net change: -18961
```

I uploaded the ecosystem full diff (ignoring the 19k
`no-matching-overload` diagnostics)
[here](https://shark.fish/diff-namedtuple.html).

* There are some new `missing-argument` false positives which come from
the fact that named tuples are often created using unpacking as in
`MyNamedTuple(*fields)`, which we do not understand yet.
* There are some new `unresolved-attribute` false positives, because
methods like `_replace` are not available.
* Lots of the `invalid-argument-type` diagnostics look like true
positives

---------

Co-authored-by: Douglas Creager <dcreager@dcreager.net>
2025-04-30 22:52:04 +02:00
..
red_knot ruff_db: render file paths in diagnostics as relative paths if possible 2025-04-28 14:32:34 -04:00
red_knot_ide ruff_db: render file paths in diagnostics as relative paths if possible 2025-04-28 14:32:34 -04:00
red_knot_project [red-knot] Include salsa backtrace in check and mdtest panic messages (#17732) 2025-04-30 10:26:40 +02:00
red_knot_python_semantic [red-knot] Preliminary `NamedTuple` support (#17738) 2025-04-30 22:52:04 +02:00
red_knot_server Split `SourceLocation` into `LineColumn` and `SourceLocation` (#17587) 2025-04-27 11:27:33 +01:00
red_knot_test [red-knot] Use 'full' salsa backtrace output that includes durability and revisions (#17735) 2025-04-30 11:04:06 +00:00
red_knot_vendored Sync vendored typeshed stubs (#17402) 2025-04-15 09:16:42 +02:00
red_knot_wasm [red-knot] Fix offset handling in playground for 2-code-point UTF16 characters (#17520) 2025-04-27 11:44:55 +01:00
ruff [red-knot] Include salsa backtrace in check and mdtest panic messages (#17732) 2025-04-30 10:26:40 +02:00
ruff_annotate_snippets ruff_annotate_snippets: address unused code warnings 2025-04-07 08:24:08 -04:00
ruff_benchmark [red-knot] Preliminary `NamedTuple` support (#17738) 2025-04-30 22:52:04 +02:00
ruff_cache Fix cache key collisions for paths with separators (#12159) 2024-07-03 07:36:46 -05:00
ruff_db [red-knot] Include salsa backtrace in check and mdtest panic messages (#17732) 2025-04-30 10:26:40 +02:00
ruff_dev Upgrade to Rust 1.86 and bump MSRV to 1.84 (#17171) 2025-04-03 15:59:44 +00:00
ruff_diagnostics Show errors for attempted fixes only when passed `--verbose` (#15237) 2025-01-03 08:50:13 -06:00
ruff_formatter Upgrade to Rust 1.86 and bump MSRV to 1.84 (#17171) 2025-04-03 15:59:44 +00:00
ruff_graph [red-knot] Detect version-related syntax errors (#16379) 2025-04-17 14:00:30 -04:00
ruff_index [red-knot] Don't use separate ID types for each alist (#16415) 2025-02-28 14:55:55 -05:00
ruff_linter [`airflow`] apply Replacement::AutoImport to `AIR312` (#17570) 2025-04-30 15:53:10 -04:00
ruff_macros Upgrade to Rust 1.86 and bump MSRV to 1.84 (#17171) 2025-04-03 15:59:44 +00:00
ruff_notebook Split `SourceLocation` into `LineColumn` and `SourceLocation` (#17587) 2025-04-27 11:27:33 +01:00
ruff_python_ast Add Python 3.14 to configuration options (#17647) 2025-04-28 16:29:00 -05:00
ruff_python_ast_integration_tests Visit `Identifier` node as part of the `SourceOrderVisitor` (#17110) 2025-04-01 16:58:09 +02:00
ruff_python_codegen Upgrade to Rust 1.86 and bump MSRV to 1.84 (#17171) 2025-04-03 15:59:44 +00:00
ruff_python_formatter Split `SourceLocation` into `LineColumn` and `SourceLocation` (#17587) 2025-04-27 11:27:33 +01:00
ruff_python_index Extract `LineIndex` independent methods from `Locator` (#13938) 2024-10-28 07:53:41 +00:00
ruff_python_literal Preserve triple quotes and prefixes for strings (#15818) 2025-02-04 08:41:06 -05:00
ruff_python_parser [syntax-errors] Detect single starred expression assignment `x = *y` (#17624) 2025-04-30 15:04:00 -04:00
ruff_python_resolver Upgrade to Rust 1.86 and bump MSRV to 1.84 (#17171) 2025-04-03 15:59:44 +00:00
ruff_python_semantic [`flake8-use-pathlib`] Fix `PTH123` false positive when `open` is passed a file descriptor from a function call (#17705) 2025-04-29 16:51:38 -04:00
ruff_python_stdlib Revert "Add all PEP-585 names to UP006 rule" (#15250) 2025-01-04 12:23:53 +01:00
ruff_python_trivia [red-knot] Ignore surrounding whitespace when looking for `<!-- snapshot-diagnostics -->` directives in mdtests (#16380) 2025-02-27 13:25:31 +00:00
ruff_python_trivia_integration_tests Pass `ParserOptions` to the parser (#16220) 2025-02-19 10:50:50 -05:00
ruff_server Split `SourceLocation` into `LineColumn` and `SourceLocation` (#17587) 2025-04-27 11:27:33 +01:00
ruff_source_file [red-knot] Fix offset handling in playground for 2-code-point UTF16 characters (#17520) 2025-04-27 11:44:55 +01:00
ruff_text_size [`ruff`] `itertools.starmap(..., zip(...))` (`RUF058`) (#15483) 2025-01-16 15:18:12 +01:00
ruff_wasm Split `SourceLocation` into `LineColumn` and `SourceLocation` (#17587) 2025-04-27 11:27:33 +01:00
ruff_workspace Fix example syntax for pydocstyle ignore_var_parameters option (#17740) 2025-04-30 18:19:41 +02:00