Skip to content

Commit 7c936b0

Browse files
committed
gh-150069: Test frozen dataclass and properties interaction
1 parent ba0aca3 commit 7c936b0

1 file changed

Lines changed: 70 additions & 1 deletion

File tree

Lib/test/test_dataclasses/__init__.py

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3328,35 +3328,104 @@ def test_non_frozen_normal_derived(self):
33283328
class D:
33293329
x: int
33303330
y: int = 10
3331+
z: int = 0
3332+
3333+
@property
3334+
def readonly(self) -> int:
3335+
return self.x
3336+
3337+
@property
3338+
def prop(self) -> int:
3339+
return self.z
3340+
3341+
@prop.setter
3342+
def prop(self, val: int) -> None:
3343+
object.__setattr__(self, 'z', val)
3344+
3345+
@prop.deleter
3346+
def prop(self) -> None:
3347+
object.__setattr__(self, 'z', 0)
3348+
3349+
d = D(5)
3350+
self.assertEqual(d.x, 5)
3351+
self.assertEqual(d.y, 10)
3352+
self.assertEqual(d.z, 0)
3353+
self.assertEqual(d.readonly, 5)
3354+
self.assertEqual(d.prop, 0)
3355+
3356+
with self.assertRaises(FrozenInstanceError):
3357+
d.x = 5
3358+
with self.assertRaises(FrozenInstanceError):
3359+
d.readonly = 5
3360+
with self.assertRaises(FrozenInstanceError):
3361+
d.z = 5
3362+
with self.assertRaises(FrozenInstanceError):
3363+
d.prop = 5
3364+
with self.assertRaises(FrozenInstanceError):
3365+
del d.prop
3366+
3367+
self.assertEqual(d.x, 5)
3368+
self.assertEqual(d.y, 10)
3369+
self.assertEqual(d.z, 0)
3370+
self.assertEqual(d.readonly, 5)
3371+
self.assertEqual(d.prop, 0)
33313372

33323373
class S(D):
33333374
pass
33343375

33353376
s = S(3)
33363377
self.assertEqual(s.x, 3)
33373378
self.assertEqual(s.y, 10)
3379+
self.assertEqual(s.z, 0)
3380+
self.assertEqual(s.readonly, 3)
3381+
self.assertEqual(s.prop, 0)
3382+
# Can set new attrs:
33383383
s.cached = True
3384+
# Can mutate them:
3385+
s.cached = False
3386+
3387+
# Can also change writable properties:
3388+
with self.assertRaises(AttributeError) as cm:
3389+
s.readonly = 5
3390+
self.assertNotIsInstance(cm.exception, FrozenInstanceError)
3391+
s.prop = 1
3392+
self.assertEqual(s.x, 3)
3393+
self.assertEqual(s.readonly, 3)
3394+
self.assertEqual(s.prop, 1)
3395+
self.assertEqual(s.z, 1)
33393396

33403397
# But can't change the frozen attributes.
33413398
with self.assertRaises(FrozenInstanceError):
33423399
s.x = 5
33433400
with self.assertRaises(FrozenInstanceError):
33443401
s.y = 5
3402+
with self.assertRaises(FrozenInstanceError):
3403+
s.z = 5
33453404
self.assertEqual(s.x, 3)
33463405
self.assertEqual(s.y, 10)
3347-
self.assertEqual(s.cached, True)
3406+
self.assertEqual(s.z, 1)
3407+
self.assertIs(s.cached, False)
33483408

33493409
with self.assertRaises(FrozenInstanceError):
33503410
del s.x
33513411
self.assertEqual(s.x, 3)
33523412
with self.assertRaises(FrozenInstanceError):
33533413
del s.y
33543414
self.assertEqual(s.y, 10)
3415+
with self.assertRaises(AttributeError) as cm:
3416+
del s.readonly
3417+
self.assertNotIsInstance(cm.exception, FrozenInstanceError)
3418+
self.assertEqual(s.x, 3)
3419+
self.assertEqual(s.readonly, 3)
33553420
del s.cached
33563421
self.assertNotHasAttr(s, 'cached')
33573422
with self.assertRaises(AttributeError) as cm:
33583423
del s.cached
33593424
self.assertNotIsInstance(cm.exception, FrozenInstanceError)
3425+
del s.prop
3426+
self.assertEqual(s.z, 0)
3427+
self.assertEqual(s.prop, 0)
3428+
del s.prop
33603429

33613430
def test_non_frozen_normal_derived_from_empty_frozen(self):
33623431
@dataclass(frozen=True)

0 commit comments

Comments
 (0)