Skip to content

Commit d33a503

Browse files
authored
[red-knot] Add tests for classes that have incompatible __new__ and __init__ methods (#17747)
Closes #17737
1 parent 650cbdd commit d33a503

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

crates/red_knot_python_semantic/resources/mdtest/call/constructor.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,64 @@ reveal_type(Foo(1)) # revealed: Foo
343343
reveal_type(Foo(1, 2)) # revealed: Foo
344344
```
345345

346+
### Incompatible signatures
347+
348+
```py
349+
import abc
350+
351+
class Foo:
352+
def __new__(cls) -> "Foo":
353+
return object.__new__(cls)
354+
355+
def __init__(self, x):
356+
self.x = 42
357+
358+
# error: [missing-argument] "No argument provided for required parameter `x` of bound method `__init__`"
359+
reveal_type(Foo()) # revealed: Foo
360+
361+
# error: [too-many-positional-arguments] "Too many positional arguments to function `__new__`: expected 0, got 1"
362+
reveal_type(Foo(42)) # revealed: Foo
363+
364+
class Foo2:
365+
def __new__(cls, x) -> "Foo2":
366+
return object.__new__(cls)
367+
368+
def __init__(self):
369+
pass
370+
371+
# error: [missing-argument] "No argument provided for required parameter `x` of function `__new__`"
372+
reveal_type(Foo2()) # revealed: Foo2
373+
374+
# error: [too-many-positional-arguments] "Too many positional arguments to bound method `__init__`: expected 0, got 1"
375+
reveal_type(Foo2(42)) # revealed: Foo2
376+
377+
class Foo3(metaclass=abc.ABCMeta):
378+
def __new__(cls) -> "Foo3":
379+
return object.__new__(cls)
380+
381+
def __init__(self, x):
382+
self.x = 42
383+
384+
# error: [missing-argument] "No argument provided for required parameter `x` of bound method `__init__`"
385+
reveal_type(Foo3()) # revealed: Foo3
386+
387+
# error: [too-many-positional-arguments] "Too many positional arguments to function `__new__`: expected 0, got 1"
388+
reveal_type(Foo3(42)) # revealed: Foo3
389+
390+
class Foo4(metaclass=abc.ABCMeta):
391+
def __new__(cls, x) -> "Foo4":
392+
return object.__new__(cls)
393+
394+
def __init__(self):
395+
pass
396+
397+
# error: [missing-argument] "No argument provided for required parameter `x` of function `__new__`"
398+
reveal_type(Foo4()) # revealed: Foo4
399+
400+
# error: [too-many-positional-arguments] "Too many positional arguments to bound method `__init__`: expected 0, got 1"
401+
reveal_type(Foo4(42)) # revealed: Foo4
402+
```
403+
346404
### Lookup of `__new__`
347405

348406
The `__new__` method is always invoked on the class itself, never on the metaclass. This is

0 commit comments

Comments
 (0)