@@ -97,11 +97,7 @@ ListSubtype_New( PyTypeObject* subtype, Py_ssize_t size )
9797 return PyErr_NoMemory (); // LCOV_EXCL_LINE (memory error)
9898 memset ( op->ob_item , 0 , nbytes );
9999 }
100- #if PY_VERSION_HEX >= 0x03090000
101100 Py_SET_SIZE ( op, size );
102- #else
103- Py_SIZE ( op ) = size;
104- #endif
105101 op->allocated = size;
106102 return ptr.release ();
107103}
@@ -133,12 +129,14 @@ class AtomListHandler
133129 return cppy::incref ( Py_None );
134130 }
135131
136- PyObject* insert ( PyObject* args )
132+ PyObject* insert ( PyObject*const * args, Py_ssize_t nargsf )
137133 {
138- Py_ssize_t index;
139- PyObject* value;
140- if ( !PyArg_ParseTuple ( args, " nO:insert" , &index, &value ) )
141- return 0 ;
134+ if ( PyVectorcall_NARGS (nargsf) != 2 || !PyLong_Check ( args[0 ] ) )
135+ return cppy::type_error (" signature is insert(index: int, value: Any)" );
136+ Py_ssize_t index = PyLong_AsSsize_t ( args[0 ] );
137+ if ( PyErr_Occurred () )
138+ return 0 ; // out of range
139+ PyObject* value = args[1 ];
142140 cppy::ptr valptr ( validate_single ( value ) );
143141 if ( !valptr )
144142 return 0 ;
@@ -248,7 +246,10 @@ class AtomListHandler
248246 PyObject* val = vd->full_validate ( atm, Py_None, b );
249247 if ( !val )
250248 return 0 ;
251- PyList_SET_ITEM ( templist.get (), i, cppy::incref ( val ) );
249+ PyList_SET_ITEM ( templist.get (), i, val );
250+ // b is a borrowed reference but PyList_SET_ITEM does not decrement
251+ // the refcount of the replaced object so it must be released here
252+ Py_DECREF ( b );
252253 }
253254 item = templist;
254255 }
@@ -288,11 +289,7 @@ int AtomList_clear( AtomList* self )
288289int AtomList_traverse ( AtomList* self, visitproc visit, void * arg )
289290{
290291 Py_VISIT ( self->validator );
291- #if PY_VERSION_HEX >= 0x03090000
292- // This was not needed before Python 3.9 (Python issue 35810 and 40217)
293292 Py_VISIT (Py_TYPE (self));
294- #endif
295- // PyList_type is not heap allocated so it does visit the type
296293 return PyList_Type.tp_traverse ( pyobject_cast ( self ), visit, arg );
297294}
298295
@@ -315,9 +312,9 @@ AtomList_append( AtomList* self, PyObject* value )
315312
316313
317314PyObject*
318- AtomList_insert ( AtomList* self, PyObject* args )
315+ AtomList_insert ( AtomList* self, PyObject*const * args, Py_ssize_t nargsf )
319316{
320- return AtomListHandler ( self ).insert ( args );
317+ return AtomListHandler ( self ).insert ( args, nargsf );
321318}
322319
323320
@@ -384,7 +381,7 @@ PyDoc_STRVAR( a_extend_doc,
384381
385382static PyMethodDef AtomList_methods[] = {
386383 { " append" , ( PyCFunction )AtomList_append, METH_O, a_append_doc },
387- { " insert" , ( PyCFunction )AtomList_insert, METH_VARARGS , a_insert_doc },
384+ { " insert" , ( PyCFunction )AtomList_insert, METH_FASTCALL , a_insert_doc },
388385 { " extend" , ( PyCFunction )AtomList_extend, METH_O, a_extend_doc },
389386 { " __reduce_ex__" , ( PyCFunction )AtomList_reduce_ex, METH_O, " " },
390387 { 0 } /* sentinel */
@@ -550,7 +547,7 @@ init_containerlistchange()
550547 return false ; // LCOV_EXCL_LINE (failed interned string creation)
551548 }
552549 PySStr::__delitem__str = PyUnicode_InternFromString ( " __delitem__" );
553- if ( !PySStr::typestr )
550+ if ( !PySStr::__delitem__str )
554551 {
555552 return false ; // LCOV_EXCL_LINE (failed interned string creation)
556553 }
@@ -664,10 +661,10 @@ class AtomCListHandler : public AtomListHandler
664661 return res.release ();
665662 }
666663
667- PyObject* insert ( PyObject* args )
664+ PyObject* insert ( PyObject*const * args, Py_ssize_t nargsf )
668665 {
669666 Py_ssize_t size = PyList_GET_SIZE ( m_list.get () );
670- cppy::ptr res ( AtomListHandler::insert ( args ) );
667+ cppy::ptr res ( AtomListHandler::insert ( args, nargsf ) );
671668 if ( !res )
672669 return 0 ;
673670 if ( observer_check () )
@@ -678,10 +675,10 @@ class AtomCListHandler : public AtomListHandler
678675 if ( PyDict_SetItem ( c.get (), PySStr::operationstr, PySStr::insertstr ) != 0 )
679676 return 0 ;
680677 // if the superclass call succeeds, then this is safe.
681- Py_ssize_t where = PyLong_AsSsize_t ( PyTuple_GET_ITEM ( args, 0 ) );
678+ PyObject* index = args[0 ];
679+ Py_ssize_t where = PyLong_AsSsize_t ( index );
682680 clip_index ( where, size );
683- cppy::ptr index ( PyLong_FromSsize_t ( where ) );
684- if ( PyDict_SetItem ( c.get (), PySStr::indexstr, index.get () ) != 0 )
681+ if ( PyDict_SetItem ( c.get (), PySStr::indexstr, index ) != 0 )
685682 return 0 ;
686683 if ( PyDict_SetItem ( c.get (), PySStr::itemstr, m_validated.get () ) != 0 )
687684 return 0 ;
@@ -711,12 +708,11 @@ class AtomCListHandler : public AtomListHandler
711708 return res.release ();
712709 }
713710
714- PyObject* pop ( PyObject* args )
711+ PyObject* pop ( PyObject*const * args, Py_ssize_t nargsf )
715712 {
716713 Py_ssize_t size = PyList_GET_SIZE ( m_list.get () );
717- int nargs = (int )PyTuple_GET_SIZE ( args);
718- PyObject **stack = &PyTuple_GET_ITEM (args, 0 );
719- cppy::ptr res ( ListMethods::pop ( m_list.get (), stack, nargs ) );
714+ const int nargs = PyVectorcall_NARGS (nargsf);
715+ cppy::ptr res ( ListMethods::pop ( m_list.get (), args, nargs ) );
720716 if ( !res )
721717 return 0 ;
722718 if ( observer_check () )
@@ -728,11 +724,13 @@ class AtomCListHandler : public AtomListHandler
728724 return 0 ;
729725 // if the superclass call succeeds, then this is safe.
730726 Py_ssize_t i = -1 ;
731- if ( PyTuple_GET_SIZE ( args ) == 1 )
732- i = PyLong_AsSsize_t ( PyTuple_GET_ITEM ( args, 0 ) );
727+ if ( nargs == 1 )
728+ i = PyLong_AsSsize_t ( args[ 0 ] );
733729 if ( i < 0 )
734730 i += size;
735731 cppy::ptr index ( PyLong_FromSsize_t ( i ) );
732+ if ( !index )
733+ return 0 ; // LCOV_EXCL_LINE
736734 if ( PyDict_SetItem ( c.get (), PySStr::indexstr, index.get () ) != 0 )
737735 return 0 ;
738736 if ( PyDict_SetItem ( c.get (), PySStr::itemstr, res.get () ) != 0 )
@@ -1053,9 +1051,9 @@ AtomCList_append( AtomCList* self, PyObject* value )
10531051
10541052
10551053PyObject*
1056- AtomCList_insert ( AtomCList* self, PyObject* args )
1054+ AtomCList_insert ( AtomCList* self, PyObject*const * args, Py_ssize_t nargsf )
10571055{
1058- return AtomCListHandler ( self ).insert ( args );
1056+ return AtomCListHandler ( self ).insert ( args, nargsf );
10591057}
10601058
10611059
@@ -1067,9 +1065,9 @@ AtomCList_extend( AtomCList* self, PyObject* value )
10671065
10681066
10691067PyObject*
1070- AtomCList_pop ( AtomCList* self, PyObject* args )
1068+ AtomCList_pop ( AtomCList* self, PyObject*const * args, Py_ssize_t nargsf )
10711069{
1072- return AtomCListHandler ( self ).pop ( args );
1070+ return AtomCListHandler ( self ).pop ( args, nargsf );
10731071}
10741072
10751073
@@ -1144,9 +1142,9 @@ cmp(x, y) -> -1, 0, 1");
11441142static PyMethodDef
11451143AtomCList_methods[] = {
11461144 { " append" , ( PyCFunction )AtomCList_append, METH_O, c_append_doc },
1147- { " insert" , ( PyCFunction )AtomCList_insert, METH_VARARGS , c_insert_doc },
1145+ { " insert" , ( PyCFunction )AtomCList_insert, METH_FASTCALL , c_insert_doc },
11481146 { " extend" , ( PyCFunction )AtomCList_extend, METH_O, c_extend_doc },
1149- { " pop" , ( PyCFunction )AtomCList_pop, METH_VARARGS , c_pop_doc },
1147+ { " pop" , ( PyCFunction )AtomCList_pop, METH_FASTCALL , c_pop_doc },
11501148 { " remove" , ( PyCFunction )AtomCList_remove, METH_O, c_remove_doc },
11511149 { " reverse" , ( PyCFunction )AtomCList_reverse, METH_NOARGS, c_reverse_doc },
11521150 { " sort" , ( PyCFunction )AtomCList_sort, METH_VARARGS | METH_KEYWORDS, c_sort_doc },
0 commit comments