mirror of https://github.com/astral-sh/ruff
[red-knot] Add tests for classes that have incompatible `__new__` and `__init__` methods (#17747)
Closes #17737
This commit is contained in:
parent
650cbdd296
commit
d33a503686
|
|
@ -343,6 +343,64 @@ reveal_type(Foo(1)) # revealed: Foo
|
||||||
reveal_type(Foo(1, 2)) # revealed: Foo
|
reveal_type(Foo(1, 2)) # revealed: Foo
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Incompatible signatures
|
||||||
|
|
||||||
|
```py
|
||||||
|
import abc
|
||||||
|
|
||||||
|
class Foo:
|
||||||
|
def __new__(cls) -> "Foo":
|
||||||
|
return object.__new__(cls)
|
||||||
|
|
||||||
|
def __init__(self, x):
|
||||||
|
self.x = 42
|
||||||
|
|
||||||
|
# error: [missing-argument] "No argument provided for required parameter `x` of bound method `__init__`"
|
||||||
|
reveal_type(Foo()) # revealed: Foo
|
||||||
|
|
||||||
|
# error: [too-many-positional-arguments] "Too many positional arguments to function `__new__`: expected 0, got 1"
|
||||||
|
reveal_type(Foo(42)) # revealed: Foo
|
||||||
|
|
||||||
|
class Foo2:
|
||||||
|
def __new__(cls, x) -> "Foo2":
|
||||||
|
return object.__new__(cls)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# error: [missing-argument] "No argument provided for required parameter `x` of function `__new__`"
|
||||||
|
reveal_type(Foo2()) # revealed: Foo2
|
||||||
|
|
||||||
|
# error: [too-many-positional-arguments] "Too many positional arguments to bound method `__init__`: expected 0, got 1"
|
||||||
|
reveal_type(Foo2(42)) # revealed: Foo2
|
||||||
|
|
||||||
|
class Foo3(metaclass=abc.ABCMeta):
|
||||||
|
def __new__(cls) -> "Foo3":
|
||||||
|
return object.__new__(cls)
|
||||||
|
|
||||||
|
def __init__(self, x):
|
||||||
|
self.x = 42
|
||||||
|
|
||||||
|
# error: [missing-argument] "No argument provided for required parameter `x` of bound method `__init__`"
|
||||||
|
reveal_type(Foo3()) # revealed: Foo3
|
||||||
|
|
||||||
|
# error: [too-many-positional-arguments] "Too many positional arguments to function `__new__`: expected 0, got 1"
|
||||||
|
reveal_type(Foo3(42)) # revealed: Foo3
|
||||||
|
|
||||||
|
class Foo4(metaclass=abc.ABCMeta):
|
||||||
|
def __new__(cls, x) -> "Foo4":
|
||||||
|
return object.__new__(cls)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# error: [missing-argument] "No argument provided for required parameter `x` of function `__new__`"
|
||||||
|
reveal_type(Foo4()) # revealed: Foo4
|
||||||
|
|
||||||
|
# error: [too-many-positional-arguments] "Too many positional arguments to bound method `__init__`: expected 0, got 1"
|
||||||
|
reveal_type(Foo4(42)) # revealed: Foo4
|
||||||
|
```
|
||||||
|
|
||||||
### Lookup of `__new__`
|
### Lookup of `__new__`
|
||||||
|
|
||||||
The `__new__` method is always invoked on the class itself, never on the metaclass. This is
|
The `__new__` method is always invoked on the class itself, never on the metaclass. This is
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue