@@ -231,7 +231,7 @@ def test_inheret_numbers_slots(self):
231
231
}
232
232
233
233
static PyObject* B_has_add_slot(PyObject* cls) {
234
- return ( &B_Type)->tp_as_number != NULL && (&B_Type)->tp_as_number->nb_add != NULL ? Py_True : Py_False;
234
+ return Py_NewRef(( &B_Type)->tp_as_number != NULL && (&B_Type)->tp_as_number->nb_add != NULL ? Py_True : Py_False) ;
235
235
}
236
236
237
237
''' ,
@@ -282,7 +282,7 @@ def test_inheret_numbers_slots(self):
282
282
}
283
283
284
284
static PyObject* E_has_add_slot(PyObject* cls) {
285
- return ( &E_Type)->tp_as_number != NULL && (&E_Type)->tp_as_number->nb_add != NULL ? Py_True : Py_False;
285
+ return Py_NewRef(( &E_Type)->tp_as_number != NULL && (&E_Type)->tp_as_number->nb_add != NULL ? Py_True : Py_False) ;
286
286
}
287
287
''' ,
288
288
tp_methods = '''{"create_E", (PyCFunction)create_E, METH_NOARGS | METH_CLASS, ""},
@@ -668,7 +668,7 @@ def ignore_test_float_subclass(self):
668
668
return new_fp(PyLong_AsLong(l) + PyLong_AsLong(r));
669
669
}
670
670
}
671
- return Py_NotImplemented;
671
+ return Py_NewRef( Py_NotImplemented) ;
672
672
}
673
673
""" ,
674
674
cmembers = "PyFloatObject base;" ,
@@ -716,42 +716,146 @@ def test_custom_basicsize(self):
716
716
'''
717
717
Py_ssize_t global_basicsize = -1;
718
718
719
- static PyObject* get_basicsize(PyObject* self, PyObject* is_graalpython) {
720
- // The basicsize will be the struct's size plus a pointer to the object's dict and weaklist.
721
- // Graalpython does currently not implement the weaklist, so do not add in this case.
722
- if (PyObject_IsTrue(is_graalpython)) {
723
- return PyLong_FromSsize_t(global_basicsize + sizeof(PyObject*));
724
- } else {
725
- return PyLong_FromSsize_t(global_basicsize + 2 * sizeof(PyObject*));
726
- }
719
+ static PyObject* get_basicsize(PyObject* self, PyObject* ignored) {
720
+ return PyLong_FromSsize_t(global_basicsize + 2 * sizeof(PyObject*));
727
721
}
728
722
''' ,
729
723
cmembers = '''long long field0;
730
724
int field1;
731
725
''' ,
732
- tp_methods = '{"get_basicsize", (PyCFunction)get_basicsize, METH_O , ""}' ,
726
+ tp_methods = '{"get_basicsize", (PyCFunction)get_basicsize, METH_NOARGS , ""}' ,
733
727
post_ready_code = "global_basicsize = TestCustomBasicsizeType.tp_basicsize;"
734
728
)
735
729
class TestCustomBasicsizeSubclass (TestCustomBasicsize ):
736
730
pass
737
731
738
732
obj = TestCustomBasicsizeSubclass ()
739
733
740
- # TODO pass False as soon as we implement 'tp_weaklistoffset'
741
- expected_basicsize = obj .get_basicsize (GRAALPYTHON )
734
+ expected_basicsize = obj .get_basicsize ()
742
735
actual_basicsize = TestCustomBasicsizeSubclass .__basicsize__
743
736
assert expected_basicsize == actual_basicsize , "expected = %s, actual = %s" % (expected_basicsize , actual_basicsize )
744
737
738
+ def test_tp_basicsize (self ):
739
+ TpBasicsize1Type = CPyExtType ("TpBasicsize1" ,
740
+ '''
741
+ int vv = 0;
742
+
743
+ static PyObject* set_values(PyObject* oself) {
744
+ TpBasicsize1Object * self = (TpBasicsize1Object *) oself;
745
+ for (int i = 0; i < 20; i++) {
746
+ self->f[i] = vv++;
747
+ }
748
+ Py_RETURN_NONE;
749
+ }
750
+ static PyObject* get_values(PyObject* self, PyObject* idx) {
751
+ int i = (int)PyNumber_AsSsize_t(idx, NULL);
752
+ return PyLong_FromLong(((TpBasicsize1Object *) self)->f[i]);
753
+ }
754
+ ''' ,
755
+ tp_methods = '''
756
+ {"set_values", (PyCFunction)set_values, METH_NOARGS, NULL},
757
+ {"get_value", (PyCFunction)get_values, METH_O, NULL}
758
+ ''' ,
759
+ cmembers = 'Py_ssize_t f[20];' ,
760
+ )
761
+
762
+ TpBasicsize2Type = CPyExtType ("TpBasicsize2" ,
763
+ '''
764
+ int vvv = 0;
765
+
766
+ static PyObject* set_values(PyObject* oself) {
767
+ TpBasicsize2Object * self = (TpBasicsize2Object *) oself;
768
+ for (int i = 0; i < 10; i++) {
769
+ self->f[i] = vvv++;
770
+ }
771
+ Py_RETURN_NONE;
772
+ }
773
+ static PyObject* get_values(PyObject* self, PyObject* idx) {
774
+ int i = (int)PyNumber_AsSsize_t(idx, NULL);
775
+ return PyLong_FromLong(((TpBasicsize2Object *) self)->f[i]);
776
+ }
777
+ ''' ,
778
+ tp_methods = '''
779
+ {"set_values", (PyCFunction)set_values, METH_NOARGS, NULL},
780
+ {"get_value", (PyCFunction)get_values, METH_O, NULL}
781
+ ''' ,
782
+ cmembers = 'Py_ssize_t f[10];' ,
783
+ )
784
+
785
+ TpBasicsize3Type = CPyExtType ("TpBasicsize3" ,
786
+ '''
787
+ ''' ,
788
+ cmembers = '' ,
789
+ )
790
+
791
+ try :
792
+ class Foo (TpBasicsize2Type , TpBasicsize1Type ):
793
+ pass
794
+ except TypeError :
795
+ pass
796
+ else :
797
+ assert False , "should raise: TypeError: multiple bases have instance lay-out conflict"
798
+
799
+ class Foo (TpBasicsize3Type , TpBasicsize1Type ):
800
+ pass
801
+
802
+ assert Foo .__base__ == TpBasicsize1Type
803
+ assert Foo .__basicsize__ == 192 , "Foo.__basicsize__ %d != 192" % Foo .__basicsize__
804
+ objs = [Foo () for i in range (5 )]
805
+ for foo in objs :
806
+ foo .set_values ()
807
+ vv = 0
808
+ for foo in objs :
809
+ for i in range (20 ):
810
+ assert foo .get_value (i ) == vv
811
+ vv += 1
812
+
813
+ class Foo (TpBasicsize2Type , TpBasicsize3Type ):
814
+ pass
815
+
816
+ assert Foo .__base__ == TpBasicsize2Type
817
+ assert Foo .__basicsize__ == 112 , "Foo.__basicsize__ %d != 112" % Foo .__basicsize__
818
+ objs = [Foo () for i in range (5 )]
819
+ for foo in objs :
820
+ foo .set_values ()
821
+ vvv = 0
822
+ for foo in objs :
823
+ for i in range (10 ):
824
+ assert foo .get_value (i ) == vvv , "Failed"
825
+ vvv += 1
826
+
827
+ def test_new_inherited_from_dominant_base (self ):
828
+ DominantBase = CPyExtType (
829
+ 'DominantBase' ,
830
+ '''
831
+ PyObject* base_new(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
832
+ return Py_NewRef(Py_Ellipsis);
833
+ }
834
+ ''' ,
835
+ cmembers = 'int foo; int bar;' ,
836
+ tp_new = 'base_new' ,
837
+ )
838
+ assert DominantBase () is Ellipsis
839
+
840
+ WeakBase = CPyExtType ('WeakBase' )
841
+
842
+ class Subclass (WeakBase , DominantBase ):
843
+ pass
844
+
845
+ # In CPython 3.10, Subclass.__new__ is WeakBase.__new__, but Subclass.tp_new is DominantBase.tp_new
846
+
847
+ assert Subclass () is Ellipsis
848
+
745
849
def test_descrget (self ):
746
850
TestDescrGet = CPyExtType (
747
851
"TestDescrGet" ,
748
852
'''
749
853
PyObject* testdescr_get(PyObject* self, PyObject* obj, PyObject* type) {
750
854
if (obj == NULL) {
751
- obj = Py_Ellipsis;
855
+ obj = Py_NewRef( Py_Ellipsis) ;
752
856
}
753
857
if (type == NULL) {
754
- type = Py_Ellipsis;
858
+ type = Py_NewRef( Py_Ellipsis) ;
755
859
}
756
860
return Py_BuildValue("OOO", self, obj, type);
757
861
}
@@ -1248,7 +1352,7 @@ def compile_module(self, name):
1248
1352
// this will free the tuple
1249
1353
Py_DECREF(object);
1250
1354
1251
- return Py_None ;
1355
+ Py_RETURN_NONE ;
1252
1356
}
1253
1357
''' ,
1254
1358
arguments = ["PyObject* element" ],
0 commit comments