@@ -541,14 +541,19 @@ def __del__(self):
541541 self .assertEqual (new_type_refcnt , sys .getrefcount (A ))
542542
543543 def test_heaptype_with_dict (self ):
544- inst = _testcapi .HeapCTypeWithDict ()
545- inst .foo = 42
546- self .assertEqual (inst .foo , 42 )
547- self .assertEqual (inst .dictobj , inst .__dict__ )
548- self .assertEqual (inst .dictobj , {"foo" : 42 })
544+ for cls in (
545+ _testcapi .HeapCTypeWithDict ,
546+ _testlimitedcapi .HeapCTypeWithRelativeDict ,
547+ ):
548+ with self .subTest (cls = cls ):
549+ inst = cls ()
550+ inst .foo = 42
551+ self .assertEqual (inst .foo , 42 )
552+ self .assertEqual (inst .dictobj , inst .__dict__ )
553+ self .assertEqual (inst .dictobj , {"foo" : 42 })
549554
550- inst = _testcapi . HeapCTypeWithDict ()
551- self .assertEqual ({}, inst .__dict__ )
555+ inst = cls ()
556+ self .assertEqual ({}, inst .__dict__ )
552557
553558 def test_heaptype_with_managed_dict (self ):
554559 inst = _testcapi .HeapCTypeWithManagedDict ()
@@ -585,10 +590,15 @@ def test_heaptype_with_negative_dict(self):
585590 self .assertEqual ({}, inst .__dict__ )
586591
587592 def test_heaptype_with_weakref (self ):
588- inst = _testcapi .HeapCTypeWithWeakref ()
589- ref = weakref .ref (inst )
590- self .assertEqual (ref (), inst )
591- self .assertEqual (inst .weakreflist , ref )
593+ for cls in (
594+ _testcapi .HeapCTypeWithWeakref ,
595+ _testlimitedcapi .HeapCTypeWithRelativeWeakref ,
596+ ):
597+ with self .subTest (cls = cls ):
598+ inst = cls ()
599+ ref = weakref .ref (inst )
600+ self .assertEqual (ref (), inst )
601+ self .assertEqual (inst .weakreflist , ref )
592602
593603 def test_heaptype_with_managed_weakref (self ):
594604 inst = _testcapi .HeapCTypeWithManagedWeakref ()
@@ -730,45 +740,56 @@ class Base(metaclass=metaclass):
730740 self .assertIsInstance (sub , metaclass )
731741
732742 def test_multiple_inheritance_ctypes_with_weakref_or_dict (self ):
743+ for weakref_cls in (_testcapi .HeapCTypeWithWeakref ,
744+ _testlimitedcapi .HeapCTypeWithRelativeWeakref ):
745+ for dict_cls in (_testcapi .HeapCTypeWithDict ,
746+ _testlimitedcapi .HeapCTypeWithRelativeDict ):
747+ with self .subTest (weakref_cls = weakref_cls , dict_cls = dict_cls ):
733748
734- with self .assertRaises (TypeError ):
735- class Both1 (_testcapi . HeapCTypeWithWeakref , _testcapi . HeapCTypeWithDict ):
736- pass
737- with self .assertRaises (TypeError ):
738- class Both2 (_testcapi . HeapCTypeWithDict , _testcapi . HeapCTypeWithWeakref ):
739- pass
749+ with self .assertRaises (TypeError ):
750+ class Both1 (weakref_cls , dict_cls ):
751+ pass
752+ with self .assertRaises (TypeError ):
753+ class Both2 (dict_cls , weakref_cls ):
754+ pass
740755
741756 def test_multiple_inheritance_ctypes_with_weakref_or_dict_and_other_builtin (self ):
757+ for dict_cls in (_testcapi .HeapCTypeWithDict ,
758+ _testlimitedcapi .HeapCTypeWithRelativeDict ):
759+ for weakref_cls in (_testcapi .HeapCTypeWithWeakref ,
760+ _testlimitedcapi .HeapCTypeWithRelativeWeakref ):
761+ with self .subTest (dict_cls = dict_cls , weakref_cls = weakref_cls ):
742762
743- with self .assertRaises (TypeError ):
744- class C1 (_testcapi . HeapCTypeWithDict , list ):
745- pass
763+ with self .assertRaises (TypeError ):
764+ class C1 (dict_cls , list ):
765+ pass
746766
747- with self .assertRaises (TypeError ):
748- class C2 (_testcapi . HeapCTypeWithWeakref , list ):
749- pass
767+ with self .assertRaises (TypeError ):
768+ class C2 (weakref_cls , list ):
769+ pass
750770
751- class C3 (_testcapi .HeapCTypeWithManagedDict , list ):
752- pass
753- class C4 (_testcapi .HeapCTypeWithManagedWeakref , list ):
754- pass
771+ class C3 (_testcapi .HeapCTypeWithManagedDict , list ):
772+ pass
773+ class C4 (_testcapi .HeapCTypeWithManagedWeakref , list ):
774+ pass
755775
756- inst = C3 ()
757- inst .append (0 )
758- str (inst .__dict__ )
776+ inst = C3 ()
777+ inst .append (0 )
778+ str (inst .__dict__ )
759779
760- inst = C4 ()
761- inst .append (0 )
762- str (inst .__weakref__ )
780+ inst = C4 ()
781+ inst .append (0 )
782+ str (inst .__weakref__ )
763783
764- for cls in (_testcapi .HeapCTypeWithManagedDict , _testcapi .HeapCTypeWithManagedWeakref ):
765- for cls2 in (_testcapi .HeapCTypeWithDict , _testcapi .HeapCTypeWithWeakref ):
766- class S (cls , cls2 ):
767- pass
768- class B1 (C3 , cls ):
769- pass
770- class B2 (C4 , cls ):
771- pass
784+ for cls in (_testcapi .HeapCTypeWithManagedDict ,
785+ _testcapi .HeapCTypeWithManagedWeakref ):
786+ for cls2 in (dict_cls , weakref_cls ):
787+ class S (cls , cls2 ):
788+ pass
789+ class B1 (C3 , cls ):
790+ pass
791+ class B2 (C4 , cls ):
792+ pass
772793
773794 def test_pytype_fromspec_with_repeated_slots (self ):
774795 for variant in range (2 ):
@@ -1272,6 +1293,53 @@ def test_heaptype_relative_members_errors(self):
12721293 SystemError , r"PyMember_SetOne used with Py_RELATIVE_OFFSET" ):
12731294 instance .set_memb_relative (0 )
12741295
1296+ def test_heaptype_relative_special_members_errors (self ):
1297+ for member_name in "__vectorcalloffset__" , "__dictoffset__" , "__weaklistoffset__" :
1298+ with self .subTest (member_name = member_name ):
1299+ with self .assertRaisesRegex (
1300+ SystemError ,
1301+ r"With Py_RELATIVE_OFFSET, basicsize must be negative." ):
1302+ _testlimitedcapi .make_heaptype_with_member (
1303+ basicsize = sys .getsizeof (object ()) + 100 ,
1304+ add_relative_flag = True ,
1305+ member_name = member_name ,
1306+ member_offset = 0 ,
1307+ member_type = _testlimitedcapi .Py_T_PYSSIZET ,
1308+ member_flags = _testlimitedcapi .Py_READONLY ,
1309+ )
1310+ with self .assertRaisesRegex (
1311+ SystemError ,
1312+ r"Member offset out of range \(0\.\.-basicsize\)" ):
1313+ _testlimitedcapi .make_heaptype_with_member (
1314+ basicsize = - 8 ,
1315+ add_relative_flag = True ,
1316+ member_name = member_name ,
1317+ member_offset = - 1 ,
1318+ member_type = _testlimitedcapi .Py_T_PYSSIZET ,
1319+ member_flags = _testlimitedcapi .Py_READONLY ,
1320+ )
1321+ with self .assertRaisesRegex (
1322+ SystemError ,
1323+ r"type of %s must be Py_T_PYSSIZET" % member_name ):
1324+ _testlimitedcapi .make_heaptype_with_member (
1325+ basicsize = - 100 ,
1326+ add_relative_flag = True ,
1327+ member_name = member_name ,
1328+ member_offset = 0 ,
1329+ member_flags = _testlimitedcapi .Py_READONLY ,
1330+ )
1331+ with self .assertRaisesRegex (
1332+ SystemError ,
1333+ r"flags for %s must be " % member_name ):
1334+ _testlimitedcapi .make_heaptype_with_member (
1335+ basicsize = - 100 ,
1336+ add_relative_flag = True ,
1337+ member_name = member_name ,
1338+ member_offset = 0 ,
1339+ member_type = _testlimitedcapi .Py_T_PYSSIZET ,
1340+ member_flags = 0 ,
1341+ )
1342+
12751343 def test_pyobject_getitemdata_error (self ):
12761344 """Test PyObject_GetItemData fails on unsupported types"""
12771345 with self .assertRaises (TypeError ):
0 commit comments