@@ -541,14 +541,19 @@ def __del__(self):
541
541
self .assertEqual (new_type_refcnt , sys .getrefcount (A ))
542
542
543
543
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 })
549
554
550
- inst = _testcapi . HeapCTypeWithDict ()
551
- self .assertEqual ({}, inst .__dict__ )
555
+ inst = cls ()
556
+ self .assertEqual ({}, inst .__dict__ )
552
557
553
558
def test_heaptype_with_managed_dict (self ):
554
559
inst = _testcapi .HeapCTypeWithManagedDict ()
@@ -585,10 +590,15 @@ def test_heaptype_with_negative_dict(self):
585
590
self .assertEqual ({}, inst .__dict__ )
586
591
587
592
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 )
592
602
593
603
def test_heaptype_with_managed_weakref (self ):
594
604
inst = _testcapi .HeapCTypeWithManagedWeakref ()
@@ -730,45 +740,56 @@ class Base(metaclass=metaclass):
730
740
self .assertIsInstance (sub , metaclass )
731
741
732
742
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 ):
733
748
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
740
755
741
756
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 ):
742
762
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
746
766
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
750
770
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
755
775
756
- inst = C3 ()
757
- inst .append (0 )
758
- str (inst .__dict__ )
776
+ inst = C3 ()
777
+ inst .append (0 )
778
+ str (inst .__dict__ )
759
779
760
- inst = C4 ()
761
- inst .append (0 )
762
- str (inst .__weakref__ )
780
+ inst = C4 ()
781
+ inst .append (0 )
782
+ str (inst .__weakref__ )
763
783
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
772
793
773
794
def test_pytype_fromspec_with_repeated_slots (self ):
774
795
for variant in range (2 ):
@@ -1272,6 +1293,53 @@ def test_heaptype_relative_members_errors(self):
1272
1293
SystemError , r"PyMember_SetOne used with Py_RELATIVE_OFFSET" ):
1273
1294
instance .set_memb_relative (0 )
1274
1295
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
+
1275
1343
def test_pyobject_getitemdata_error (self ):
1276
1344
"""Test PyObject_GetItemData fails on unsupported types"""
1277
1345
with self .assertRaises (TypeError ):
0 commit comments