mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-08 04:38:04 +00:00
[ty] synthesize __setattr__ for frozen dataclasses (#19307)
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 / Fuzz for new ty panics (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-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
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 / Fuzz for new ty panics (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-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
## Summary Synthesize a `__setattr__` method with a return type of `Never` for frozen dataclasses. https://docs.python.org/3/library/dataclasses.html#frozen-instances https://docs.python.org/3/library/dataclasses.html#dataclasses.FrozenInstanceError ### Related https://github.com/astral-sh/ty/issues/111 https://github.com/astral-sh/ruff/pull/17974#discussion_r2108527106 https://github.com/astral-sh/ruff/pull/18347#discussion_r2128174665 ## Test Plan New Markdown tests --------- Co-authored-by: David Peter <mail@david-peter.de>
This commit is contained in:
parent
c7640a433e
commit
39b41838f3
4 changed files with 143 additions and 106 deletions
|
@ -1806,7 +1806,7 @@ class Frozen:
|
|||
raise AttributeError("Attributes can not be modified")
|
||||
|
||||
instance = Frozen()
|
||||
instance.non_existing = 2 # error: [invalid-assignment] "Cannot assign to attribute `non_existing` on type `Frozen` whose `__setattr__` method returns `Never`/`NoReturn`"
|
||||
instance.non_existing = 2 # error: [invalid-assignment] "Can not assign to unresolved attribute `non_existing` on type `Frozen`"
|
||||
instance.existing = 2 # error: [invalid-assignment] "Cannot assign to attribute `existing` on type `Frozen` whose `__setattr__` method returns `Never`/`NoReturn`"
|
||||
```
|
||||
|
||||
|
|
|
@ -415,8 +415,7 @@ frozen_instance = MyFrozenGeneric[int](1)
|
|||
frozen_instance.x = 2 # error: [invalid-assignment]
|
||||
```
|
||||
|
||||
When attempting to mutate an unresolved attribute on a frozen dataclass, only `unresolved-attribute`
|
||||
is emitted:
|
||||
Attempting to mutate an unresolved attribute on a frozen dataclass:
|
||||
|
||||
```py
|
||||
from dataclasses import dataclass
|
||||
|
@ -425,7 +424,39 @@ from dataclasses import dataclass
|
|||
class MyFrozenClass: ...
|
||||
|
||||
frozen = MyFrozenClass()
|
||||
frozen.x = 2 # error: [unresolved-attribute]
|
||||
frozen.x = 2 # error: [invalid-assignment] "Can not assign to unresolved attribute `x` on type `MyFrozenClass`"
|
||||
```
|
||||
|
||||
A diagnostic is also emitted if a frozen dataclass is inherited, and an attempt is made to mutate an
|
||||
attribute in the child class:
|
||||
|
||||
```py
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class MyFrozenClass:
|
||||
x: int = 1
|
||||
|
||||
class MyFrozenChildClass(MyFrozenClass): ...
|
||||
|
||||
frozen = MyFrozenChildClass()
|
||||
frozen.x = 2 # error: [invalid-assignment]
|
||||
```
|
||||
|
||||
The same diagnostic is emitted if a frozen dataclass is inherited, and an attempt is made to delete
|
||||
an attribute:
|
||||
|
||||
```py
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class MyFrozenClass:
|
||||
x: int = 1
|
||||
|
||||
class MyFrozenChildClass(MyFrozenClass): ...
|
||||
|
||||
frozen = MyFrozenChildClass()
|
||||
del frozen.x # TODO this should emit an [invalid-assignment]
|
||||
```
|
||||
|
||||
### `match_args`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue