From 8f6eccdc64cab735c47620fea948e64b19f83684 Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Tue, 20 Mar 2018 22:00:23 -0400 Subject: bpo-32896: Fix error when subclassing a dataclass with a field that uses a default_factory (GH-6170) Fix the way that new annotations in a class are detected. --- Lib/test/test_dataclasses.py | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'Lib/test/test_dataclasses.py') diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index db03ec1925f..9b5aad25745 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -1147,6 +1147,55 @@ class TestCase(unittest.TestCase): C().x self.assertEqual(factory.call_count, 2) + def test_default_factory_derived(self): + # See bpo-32896. + @dataclass + class Foo: + x: dict = field(default_factory=dict) + + @dataclass + class Bar(Foo): + y: int = 1 + + self.assertEqual(Foo().x, {}) + self.assertEqual(Bar().x, {}) + self.assertEqual(Bar().y, 1) + + @dataclass + class Baz(Foo): + pass + self.assertEqual(Baz().x, {}) + + def test_intermediate_non_dataclass(self): + # Test that an intermediate class that defines + # annotations does not define fields. + + @dataclass + class A: + x: int + + class B(A): + y: int + + @dataclass + class C(B): + z: int + + c = C(1, 3) + self.assertEqual((c.x, c.z), (1, 3)) + + # .y was not initialized. + with self.assertRaisesRegex(AttributeError, + 'object has no attribute'): + c.y + + # And if we again derive a non-dataclass, no fields are added. + class D(C): + t: int + d = D(4, 5) + self.assertEqual((d.x, d.z), (4, 5)) + + def x_test_classvar_default_factory(self): # XXX: it's an error for a ClassVar to have a factory function @dataclass -- cgit v1.2.3