@@ -40,19 +40,79 @@ The signature of the `__init__` method is generated based on the classes attribu
4040calls are not valid:
4141
4242``` py
43- # TODO : should be an error: too few arguments
43+ # error: [missing-argument]
4444Person()
4545
46- # TODO : should be an error: too many arguments
46+ # error: [ too- many-positional- arguments]
4747Person(" Eve" , 20 , " too many arguments" )
4848
49- # TODO : should be an error: wrong argument type
49+ # error: [invalid- argument- type]
5050Person(" Eve" , " string instead of int" )
5151
52- # TODO : should be an error: wrong argument types
52+ # error: [invalid-argument-type]
53+ # error: [invalid-argument-type]
5354Person(20 , " Eve" )
5455```
5556
57+ ## Signature of ` __init__ `
58+
59+ TODO: All of the following tests are missing the ` self ` argument in the ` __init__ ` signature.
60+
61+ Declarations in the class body are used to generate the signature of the ` __init__ ` method. If the
62+ attributes are not just declarations, but also bindings, the type inferred from bindings is used as
63+ the default value.
64+
65+ ``` py
66+ from dataclasses import dataclass
67+
68+ @dataclass
69+ class D1 :
70+ x: int
71+ y: str = " default"
72+ z: int | None = 1 + 2
73+
74+ reveal_type(D1.__init__ ) # revealed: (x: int, y: str = Literal["default"], z: int | None = Literal[3]) -> None
75+ ```
76+
77+ This also works if the declaration and binding are split:
78+
79+ ``` py
80+ @dataclass
81+ class D2 :
82+ x: int | None
83+ x = None
84+
85+ reveal_type(D2.__init__ ) # revealed: (x: int | None = None) -> None
86+ ```
87+
88+ Function declarations do not affect the signature of ` __init__ ` :
89+
90+ ``` py
91+ @dataclass
92+ class D3 :
93+ x: int
94+
95+ def y (self ) -> str :
96+ return " "
97+
98+ reveal_type(D3.__init__ ) # revealed: (x: int) -> None
99+ ```
100+
101+ Implicit instance attributes also do not affect the signature of ` __init__ ` :
102+
103+ ``` py
104+ @dataclass
105+ class D4 :
106+ x: int
107+
108+ def f (self , y : str ) -> None :
109+ self .y: str = y
110+
111+ reveal_type(D4(1 ).y) # revealed: str
112+
113+ reveal_type(D4.__init__ ) # revealed: (x: int) -> None
114+ ```
115+
56116## ` @dataclass ` calls with arguments
57117
58118The ` @dataclass ` decorator can take several arguments to customize the existence of the generated
@@ -228,7 +288,8 @@ class Derived(Base):
228288
229289d = Derived(" a" )
230290
231- # TODO : should be an error:
291+ # error: [too-many-positional-arguments]
292+ # error: [invalid-argument-type]
232293Derived(1 , " a" )
233294```
234295
@@ -245,6 +306,9 @@ class Base:
245306class Derived (Base ):
246307 y: str
247308
309+ # TODO : no errors
310+ # error: [too-many-positional-arguments]
311+ # error: [invalid-argument-type]
248312d = Derived(1 , " a" ) # OK
249313
250314reveal_type(d.x) # revealed: int
@@ -292,10 +356,12 @@ class Descriptor:
292356class C :
293357 d: Descriptor = Descriptor()
294358
359+ # TODO : no error
360+ # error: [invalid-argument-type]
295361c = C(1 )
296362reveal_type(c.d) # revealed: str
297363
298- # TODO : should be an error
364+ # error: [invalid-argument-type]
299365C(" a" )
300366```
301367
@@ -316,8 +382,7 @@ import dataclasses
316382class C :
317383 x: str
318384
319- # TODO : should show the proper signature
320- reveal_type(C.__init__ ) # revealed: (*args: Any, **kwargs: Any) -> None
385+ reveal_type(C.__init__ ) # revealed: (x: str) -> None
321386```
322387
323388### Dataclass with custom ` __init__ ` method
@@ -334,6 +399,8 @@ class C:
334399 def __init__ (self , x : int ) -> None :
335400 self .x = str (x)
336401
402+ # TODO : no error
403+ # error: [invalid-argument-type]
337404C(1 ) # OK
338405
339406# TODO : should be an error
@@ -399,8 +466,8 @@ reveal_type(Person.__mro__) # revealed: tuple[Literal[Person], Literal[object]]
399466The generated methods have the following signatures:
400467
401468``` py
402- # TODO : proper signature
403- reveal_type(Person.__init__ ) # revealed: (*args: Any, **kwargs: Any ) -> None
469+ # TODO : `self` is missing here
470+ reveal_type(Person.__init__ ) # revealed: (name: str, age: int | None = None ) -> None
404471
405472reveal_type(Person.__repr__ ) # revealed: def __repr__(self) -> str
406473
0 commit comments