mirror of
https://github.com/astral-sh/ruff.git
synced 2025-11-19 12:16:43 +00:00
[ty] Fix generic inference for non-dataclass inheriting from generic dataclass (#21159)
## Summary Fixes https://github.com/astral-sh/ty/issues/1427 This PR fixes a regression introduced in alpha.24 where non-dataclass children of generic dataclasses lost generic type parameter information during `__init__` synthesis. The issue occurred because when looking up inherited members in the MRO, the child class's `inherited_generic_context` was correctly passed down, but `own_synthesized_member()` (which synthesizes dataclass `__init__` methods) didn't accept this parameter. It only used `self.inherited_generic_context(db)`, which returned the parent's context instead of the child's. The fix threads the child's generic context through to the synthesis logic, allowing proper generic type inference for inherited dataclass constructors. ## Test Plan - Added regression test for non-dataclass inheriting from generic dataclass - Verified the exact repro case from the issue now works - All 277 mdtest tests passing - Clippy clean - Manually verified with Python runtime, mypy, and pyright - all accept this code pattern ## Verification Tested against multiple type checkers: - ✅ Python runtime: Code works correctly - ✅ mypy: No issues found - ✅ pyright: 0 errors, 0 warnings - ✅ ty alpha.23: Worked (before regression) - ❌ ty alpha.24: Regression - ✅ ty with this fix: Works correctly --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: David Peter <mail@david-peter.de>
This commit is contained in:
parent
3585c96ea5
commit
735ec0c1f9
2 changed files with 39 additions and 3 deletions
|
|
@ -838,6 +838,40 @@ class WrappedIntAndExtraData[T](Wrap[int]):
|
|||
reveal_type(WrappedIntAndExtraData[bytes].__init__)
|
||||
```
|
||||
|
||||
### Non-dataclass inheriting from generic dataclass
|
||||
|
||||
This is a regression test for <https://github.com/astral-sh/ty/issues/1427>.
|
||||
|
||||
When a non-dataclass inherits from a generic dataclass, the generic type parameters should still be
|
||||
properly inferred when calling the inherited `__init__` method.
|
||||
|
||||
```py
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class ParentDataclass[T]:
|
||||
value: T
|
||||
|
||||
# Non-dataclass inheriting from generic dataclass
|
||||
class ChildOfParentDataclass[T](ParentDataclass[T]): ...
|
||||
|
||||
def uses_dataclass[T](x: T) -> ChildOfParentDataclass[T]:
|
||||
return ChildOfParentDataclass(x)
|
||||
|
||||
# TODO: ParentDataclass.__init__ should show generic types, not Unknown
|
||||
# revealed: (self: ParentDataclass[Unknown], value: Unknown) -> None
|
||||
reveal_type(ParentDataclass.__init__)
|
||||
|
||||
# revealed: (self: ParentDataclass[T@ChildOfParentDataclass], value: T@ChildOfParentDataclass) -> None
|
||||
reveal_type(ChildOfParentDataclass.__init__)
|
||||
|
||||
result_int = uses_dataclass(42)
|
||||
reveal_type(result_int) # revealed: ChildOfParentDataclass[Literal[42]]
|
||||
|
||||
result_str = uses_dataclass("hello")
|
||||
reveal_type(result_str) # revealed: ChildOfParentDataclass[Literal["hello"]]
|
||||
```
|
||||
|
||||
## Descriptor-typed fields
|
||||
|
||||
### Same type in `__get__` and `__set__`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue