mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
[ty] Implement implicit inheritance from Generic[]
for PEP-695 generic classes (#18283)
This commit is contained in:
parent
1d20cf9570
commit
0a11baf29c
8 changed files with 166 additions and 101 deletions
|
@ -37,7 +37,7 @@ class RepeatedTypevar(Generic[T, T]): ...
|
|||
You can only specialize `typing.Generic` with typevars (TODO: or param specs or typevar tuples).
|
||||
|
||||
```py
|
||||
# error: [invalid-argument-type] "`<class 'int'>` is not a valid argument to `typing.Generic`"
|
||||
# error: [invalid-argument-type] "`<class 'int'>` is not a valid argument to `Generic`"
|
||||
class GenericOfType(Generic[int]): ...
|
||||
```
|
||||
|
||||
|
|
|
@ -67,6 +67,41 @@ T = TypeVar("T")
|
|||
|
||||
# error: [invalid-generic-class] "Cannot both inherit from `typing.Generic` and use PEP 695 type variables"
|
||||
class BothGenericSyntaxes[U](Generic[T]): ...
|
||||
|
||||
reveal_type(BothGenericSyntaxes.__mro__) # revealed: tuple[<class 'BothGenericSyntaxes[Unknown]'>, Unknown, <class 'object'>]
|
||||
|
||||
# error: [invalid-generic-class] "Cannot both inherit from `typing.Generic` and use PEP 695 type variables"
|
||||
# error: [invalid-base] "Cannot inherit from plain `Generic`"
|
||||
class DoublyInvalid[T](Generic): ...
|
||||
|
||||
reveal_type(DoublyInvalid.__mro__) # revealed: tuple[<class 'DoublyInvalid[Unknown]'>, Unknown, <class 'object'>]
|
||||
```
|
||||
|
||||
Generic classes implicitly inherit from `Generic`:
|
||||
|
||||
```py
|
||||
class Foo[T]: ...
|
||||
|
||||
# revealed: tuple[<class 'Foo[Unknown]'>, typing.Generic, <class 'object'>]
|
||||
reveal_type(Foo.__mro__)
|
||||
# revealed: tuple[<class 'Foo[int]'>, typing.Generic, <class 'object'>]
|
||||
reveal_type(Foo[int].__mro__)
|
||||
|
||||
class A: ...
|
||||
class Bar[T](A): ...
|
||||
|
||||
# revealed: tuple[<class 'Bar[Unknown]'>, <class 'A'>, typing.Generic, <class 'object'>]
|
||||
reveal_type(Bar.__mro__)
|
||||
# revealed: tuple[<class 'Bar[int]'>, <class 'A'>, typing.Generic, <class 'object'>]
|
||||
reveal_type(Bar[int].__mro__)
|
||||
|
||||
class B: ...
|
||||
class Baz[T](A, B): ...
|
||||
|
||||
# revealed: tuple[<class 'Baz[Unknown]'>, <class 'A'>, <class 'B'>, typing.Generic, <class 'object'>]
|
||||
reveal_type(Baz.__mro__)
|
||||
# revealed: tuple[<class 'Baz[int]'>, <class 'A'>, <class 'B'>, typing.Generic, <class 'object'>]
|
||||
reveal_type(Baz[int].__mro__)
|
||||
```
|
||||
|
||||
## Specializing generic classes explicitly
|
||||
|
|
|
@ -644,14 +644,14 @@ reveal_type(C.__mro__) # revealed: tuple[<class 'C'>, Unknown, <class 'object'>
|
|||
|
||||
class D(D.a):
|
||||
a: D
|
||||
#reveal_type(D.__class__) # revealed: <class 'type'>
|
||||
reveal_type(D.__class__) # revealed: <class 'type'>
|
||||
reveal_type(D.__mro__) # revealed: tuple[<class 'D'>, Unknown, <class 'object'>]
|
||||
|
||||
class E[T](E.a): ...
|
||||
#reveal_type(E.__class__) # revealed: <class 'type'>
|
||||
reveal_type(E.__mro__) # revealed: tuple[<class 'E[Unknown]'>, Unknown, <class 'object'>]
|
||||
reveal_type(E.__class__) # revealed: <class 'type'>
|
||||
reveal_type(E.__mro__) # revealed: tuple[<class 'E[Unknown]'>, Unknown, typing.Generic, <class 'object'>]
|
||||
|
||||
class F[T](F(), F): ... # error: [cyclic-class-definition]
|
||||
#reveal_type(F.__class__) # revealed: <class 'type'>
|
||||
reveal_type(F.__class__) # revealed: type[Unknown]
|
||||
reveal_type(F.__mro__) # revealed: tuple[<class 'F[Unknown]'>, Unknown, <class 'object'>]
|
||||
```
|
||||
|
|
|
@ -58,9 +58,13 @@ class Bar1(Protocol[T], Generic[T]):
|
|||
class Bar2[T](Protocol):
|
||||
x: T
|
||||
|
||||
# error: [invalid-generic-class] "Cannot both inherit from subscripted `typing.Protocol` and use PEP 695 type variables"
|
||||
# error: [invalid-generic-class] "Cannot both inherit from subscripted `Protocol` and use PEP 695 type variables"
|
||||
class Bar3[T](Protocol[T]):
|
||||
x: T
|
||||
|
||||
# Note that this class definition *will* actually succeed at runtime,
|
||||
# unlike classes that combine PEP-695 type parameters with inheritance from `Generic[]`
|
||||
reveal_type(Bar3.__mro__) # revealed: tuple[<class 'Bar3[Unknown]'>, typing.Protocol, typing.Generic, <class 'object'>]
|
||||
```
|
||||
|
||||
It's an error to include both bare `Protocol` and subscripted `Protocol[]` in the bases list
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue