mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
bpo-43977: Properly update the tp_flags of existing subclasses when their parents are registered (GH-26864)
(cherry picked from commit ca2009d72a
)
Co-authored-by: Brandt Bucher <brandt@python.org>
This commit is contained in:
parent
8bec9fb92f
commit
88970125e7
4 changed files with 129 additions and 34 deletions
|
@ -24,7 +24,43 @@ class TestCompiler(unittest.TestCase):
|
|||
|
||||
class TestInheritance(unittest.TestCase):
|
||||
|
||||
def test_multiple_inheritance(self):
|
||||
@staticmethod
|
||||
def check_sequence_then_mapping(x):
|
||||
match x:
|
||||
case [*_]:
|
||||
return "seq"
|
||||
case {}:
|
||||
return "map"
|
||||
|
||||
@staticmethod
|
||||
def check_mapping_then_sequence(x):
|
||||
match x:
|
||||
case {}:
|
||||
return "map"
|
||||
case [*_]:
|
||||
return "seq"
|
||||
|
||||
def test_multiple_inheritance_mapping(self):
|
||||
class C:
|
||||
pass
|
||||
class M1(collections.UserDict, collections.abc.Sequence):
|
||||
pass
|
||||
class M2(C, collections.UserDict, collections.abc.Sequence):
|
||||
pass
|
||||
class M3(collections.UserDict, C, list):
|
||||
pass
|
||||
class M4(dict, collections.abc.Sequence, C):
|
||||
pass
|
||||
self.assertEqual(self.check_sequence_then_mapping(M1()), "map")
|
||||
self.assertEqual(self.check_sequence_then_mapping(M2()), "map")
|
||||
self.assertEqual(self.check_sequence_then_mapping(M3()), "map")
|
||||
self.assertEqual(self.check_sequence_then_mapping(M4()), "map")
|
||||
self.assertEqual(self.check_mapping_then_sequence(M1()), "map")
|
||||
self.assertEqual(self.check_mapping_then_sequence(M2()), "map")
|
||||
self.assertEqual(self.check_mapping_then_sequence(M3()), "map")
|
||||
self.assertEqual(self.check_mapping_then_sequence(M4()), "map")
|
||||
|
||||
def test_multiple_inheritance_sequence(self):
|
||||
class C:
|
||||
pass
|
||||
class S1(collections.UserList, collections.abc.Mapping):
|
||||
|
@ -35,32 +71,60 @@ class TestInheritance(unittest.TestCase):
|
|||
pass
|
||||
class S4(collections.UserList, dict, C):
|
||||
pass
|
||||
class M1(collections.UserDict, collections.abc.Sequence):
|
||||
self.assertEqual(self.check_sequence_then_mapping(S1()), "seq")
|
||||
self.assertEqual(self.check_sequence_then_mapping(S2()), "seq")
|
||||
self.assertEqual(self.check_sequence_then_mapping(S3()), "seq")
|
||||
self.assertEqual(self.check_sequence_then_mapping(S4()), "seq")
|
||||
self.assertEqual(self.check_mapping_then_sequence(S1()), "seq")
|
||||
self.assertEqual(self.check_mapping_then_sequence(S2()), "seq")
|
||||
self.assertEqual(self.check_mapping_then_sequence(S3()), "seq")
|
||||
self.assertEqual(self.check_mapping_then_sequence(S4()), "seq")
|
||||
|
||||
def test_late_registration_mapping(self):
|
||||
class Parent:
|
||||
pass
|
||||
class M2(C, collections.UserDict, collections.abc.Sequence):
|
||||
class ChildPre(Parent):
|
||||
pass
|
||||
class M3(collections.UserDict, C, list):
|
||||
class GrandchildPre(ChildPre):
|
||||
pass
|
||||
class M4(dict, collections.abc.Sequence, C):
|
||||
collections.abc.Mapping.register(Parent)
|
||||
class ChildPost(Parent):
|
||||
pass
|
||||
def f(x):
|
||||
match x:
|
||||
case []:
|
||||
return "seq"
|
||||
case {}:
|
||||
return "map"
|
||||
def g(x):
|
||||
match x:
|
||||
case {}:
|
||||
return "map"
|
||||
case []:
|
||||
return "seq"
|
||||
for Seq in (S1, S2, S3, S4):
|
||||
self.assertEqual(f(Seq()), "seq")
|
||||
self.assertEqual(g(Seq()), "seq")
|
||||
for Map in (M1, M2, M3, M4):
|
||||
self.assertEqual(f(Map()), "map")
|
||||
self.assertEqual(g(Map()), "map")
|
||||
class GrandchildPost(ChildPost):
|
||||
pass
|
||||
self.assertEqual(self.check_sequence_then_mapping(Parent()), "map")
|
||||
self.assertEqual(self.check_sequence_then_mapping(ChildPre()), "map")
|
||||
self.assertEqual(self.check_sequence_then_mapping(GrandchildPre()), "map")
|
||||
self.assertEqual(self.check_sequence_then_mapping(ChildPost()), "map")
|
||||
self.assertEqual(self.check_sequence_then_mapping(GrandchildPost()), "map")
|
||||
self.assertEqual(self.check_mapping_then_sequence(Parent()), "map")
|
||||
self.assertEqual(self.check_mapping_then_sequence(ChildPre()), "map")
|
||||
self.assertEqual(self.check_mapping_then_sequence(GrandchildPre()), "map")
|
||||
self.assertEqual(self.check_mapping_then_sequence(ChildPost()), "map")
|
||||
self.assertEqual(self.check_mapping_then_sequence(GrandchildPost()), "map")
|
||||
|
||||
def test_late_registration_sequence(self):
|
||||
class Parent:
|
||||
pass
|
||||
class ChildPre(Parent):
|
||||
pass
|
||||
class GrandchildPre(ChildPre):
|
||||
pass
|
||||
collections.abc.Sequence.register(Parent)
|
||||
class ChildPost(Parent):
|
||||
pass
|
||||
class GrandchildPost(ChildPost):
|
||||
pass
|
||||
self.assertEqual(self.check_sequence_then_mapping(Parent()), "seq")
|
||||
self.assertEqual(self.check_sequence_then_mapping(ChildPre()), "seq")
|
||||
self.assertEqual(self.check_sequence_then_mapping(GrandchildPre()), "seq")
|
||||
self.assertEqual(self.check_sequence_then_mapping(ChildPost()), "seq")
|
||||
self.assertEqual(self.check_sequence_then_mapping(GrandchildPost()), "seq")
|
||||
self.assertEqual(self.check_mapping_then_sequence(Parent()), "seq")
|
||||
self.assertEqual(self.check_mapping_then_sequence(ChildPre()), "seq")
|
||||
self.assertEqual(self.check_mapping_then_sequence(GrandchildPre()), "seq")
|
||||
self.assertEqual(self.check_mapping_then_sequence(ChildPost()), "seq")
|
||||
self.assertEqual(self.check_mapping_then_sequence(GrandchildPost()), "seq")
|
||||
|
||||
|
||||
class TestPatma(unittest.TestCase):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue