From 06525eaa74a5233132a1604e0db9e8a26253f83c Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Wed, 4 Apr 2018 20:53:34 -0400 Subject: [PATCH 1/2] Add a test for frozen with unhashable field value. Fixed duplicate TestFrozen testcase. --- Lib/test/test_dataclasses.py | 64 +++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 26bfc4e75a001e..81935c5528e495 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -2191,33 +2191,6 @@ def __repr__(self): self.assertEqual(repr(C(0)), 'x') -class TestFrozen(unittest.TestCase): - def test_overwriting_frozen(self): - # frozen uses __setattr__ and __delattr__. - with self.assertRaisesRegex(TypeError, - 'Cannot overwrite attribute __setattr__'): - @dataclass(frozen=True) - class C: - x: int - def __setattr__(self): - pass - - with self.assertRaisesRegex(TypeError, - 'Cannot overwrite attribute __delattr__'): - @dataclass(frozen=True) - class C: - x: int - def __delattr__(self): - pass - - @dataclass(frozen=False) - class C: - x: int - def __setattr__(self, name, value): - self.__dict__['x'] = value * 2 - self.assertEqual(C(10).x, 20) - - class TestEq(unittest.TestCase): def test_no_eq(self): # Test a class with no __eq__ and eq=False. @@ -2672,6 +2645,43 @@ class S(D): self.assertEqual(s.y, 10) self.assertEqual(s.cached, True) + def test_overwriting_frozen(self): + # frozen uses __setattr__ and __delattr__. + with self.assertRaisesRegex(TypeError, + 'Cannot overwrite attribute __setattr__'): + @dataclass(frozen=True) + class C: + x: int + def __setattr__(self): + pass + + with self.assertRaisesRegex(TypeError, + 'Cannot overwrite attribute __delattr__'): + @dataclass(frozen=True) + class C: + x: int + def __delattr__(self): + pass + + @dataclass(frozen=False) + class C: + x: int + def __setattr__(self, name, value): + self.__dict__['x'] = value * 2 + self.assertEqual(C(10).x, 20) + + def test_frozen_hash(self): + @dataclass(frozen=True) + class C: + x: Any + + # If x is immutable, we can compute the hash. + hash(C(3)) + + # If x is mutable, computing the hash is an error. + with self.assertRaisesRegex(TypeError, 'unhashable type'): + hash(C({})) + class TestSlots(unittest.TestCase): def test_simple(self): From 092f9db891034cae35d75dcc264e8ba03298f63b Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Thu, 5 Apr 2018 05:17:09 -0400 Subject: [PATCH 2/2] Improve a comment. --- Lib/test/test_dataclasses.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 81935c5528e495..2c890a2cbe9206 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -2675,7 +2675,8 @@ def test_frozen_hash(self): class C: x: Any - # If x is immutable, we can compute the hash. + # If x is immutable, we can compute the hash. No exception is + # raised. hash(C(3)) # If x is mutable, computing the hash is an error.