@@ -147,6 +147,33 @@ def __init__(self, a: bool) -> None: ...
147147 """ ,
148148 )
149149
150+ def test_init_unknown_base (self ):
151+ self .CheckWithErrors ("""
152+ import dataclasses
153+ from foo import Base # pytype: disable=import-error
154+ @dataclasses.dataclass
155+ class A(Base):
156+ x: int
157+ A(x=42)
158+ A(x="wrong") # wrong-arg-types
159+ A(x=42, y="from_base")
160+ A(42, "from_base")
161+ """ )
162+
163+ def test_init_dynamic_base (self ):
164+ self .CheckWithErrors ("""
165+ import dataclasses
166+ class Base:
167+ _HAS_DYNAMIC_ATTRIBUTES = True
168+ @dataclasses.dataclass
169+ class A(Base):
170+ x: int
171+ A(x=42)
172+ A(x="wrong") # wrong-arg-types
173+ A(x=42, y="from_base")
174+ A(42, "from_base")
175+ """ )
176+
150177 def test_field (self ):
151178 ty = self .Infer ("""
152179 from typing import List
@@ -968,6 +995,31 @@ class C:
968995 errors , {"e" : ["Expected" , "str" , "Actual" , "int" ]}
969996 )
970997
998+ def test_replace_unknown_base (self ):
999+ self .CheckWithErrors ("""
1000+ import dataclasses
1001+ from foo import Base # pytype: disable=import-error
1002+ @dataclasses.dataclass
1003+ class A(Base):
1004+ x: int
1005+ a = A(x=42)
1006+ dataclasses.replace(a, x="wrong") # wrong-arg-types
1007+ dataclasses.replace(a, y="from_base")
1008+ """ )
1009+
1010+ def test_replace_dynamic_base (self ):
1011+ self .CheckWithErrors ("""
1012+ import dataclasses
1013+ class Base:
1014+ _HAS_DYNAMIC_ATTRIBUTES = True
1015+ @dataclasses.dataclass
1016+ class A(Base):
1017+ x: int
1018+ a = A(x=42)
1019+ dataclasses.replace(a, x="wrong") # wrong-arg-types
1020+ dataclasses.replace(a, y="from_base")
1021+ """ )
1022+
9711023
9721024class TestPyiDataclass (test_base .BaseTest ):
9731025 """Tests for @dataclasses in pyi files."""
@@ -1718,6 +1770,57 @@ def f(x, y):
17181770 print("not matched")
17191771 """ )
17201772
1773+ def test_inheritance (self ):
1774+ with self .DepTree ([(
1775+ "foo.pyi" ,
1776+ """
1777+ import dataclasses
1778+ @dataclasses.dataclass
1779+ class Point:
1780+ x: float
1781+ y: float
1782+
1783+ class OtherPoint(Point):
1784+ ...
1785+ """ ,
1786+ )]):
1787+ self .Check ("""
1788+ import foo
1789+ def f(x, y):
1790+ p = foo.OtherPoint(x, y)
1791+ match p:
1792+ case foo.OtherPoint(x, y):
1793+ print(f"({x}, {y})")
1794+ case _:
1795+ print("not matched")
1796+ """ )
1797+
1798+ def test_kw_only (self ):
1799+ with self .DepTree ([(
1800+ "foo.pyi" ,
1801+ """
1802+ import dataclasses
1803+ @dataclasses.dataclass
1804+ class Point:
1805+ x: float
1806+ _: dataclasses.KW_ONLY
1807+ y: float
1808+
1809+ class PointWithKwOnly(Point):
1810+ ...
1811+ """ ,
1812+ )]):
1813+ self .CheckWithErrors ("""
1814+ import foo
1815+ def f(x, y):
1816+ p = foo.PointWithKwOnly(x, y=y)
1817+ match p:
1818+ case foo.PointWithKwOnly(x, y): # match-error
1819+ print(f"({x}, {y})")
1820+ case _:
1821+ print("not matched")
1822+ """ )
1823+
17211824
17221825if __name__ == "__main__" :
17231826 test_base .main ()
0 commit comments