@@ -144,10 +144,13 @@ typedef struct {
144
144
vectorcallfunc vectorcall ;
145
145
} partialobject ;
146
146
147
+ // cast a PyObject pointer PTR to a partialobject pointer (no type checks)
148
+ #define _PyPartialObject_CAST (PTR ) ((partialobject *)(PTR))
149
+
147
150
static void partial_setvectorcall (partialobject * pto );
148
151
static struct PyModuleDef _functools_module ;
149
152
static PyObject *
150
- partial_call (partialobject * pto , PyObject * args , PyObject * kwargs );
153
+ partial_call (PyObject * pto , PyObject * args , PyObject * kwargs );
151
154
152
155
static inline _functools_state *
153
156
get_functools_state_by_type (PyTypeObject * type )
@@ -307,8 +310,9 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
307
310
}
308
311
309
312
static int
310
- partial_clear (partialobject * pto )
313
+ partial_clear (PyObject * self )
311
314
{
315
+ partialobject * pto = _PyPartialObject_CAST (self );
312
316
Py_CLEAR (pto -> fn );
313
317
Py_CLEAR (pto -> args );
314
318
Py_CLEAR (pto -> kw );
@@ -317,8 +321,9 @@ partial_clear(partialobject *pto)
317
321
}
318
322
319
323
static int
320
- partial_traverse (partialobject * pto , visitproc visit , void * arg )
324
+ partial_traverse (PyObject * self , visitproc visit , void * arg )
321
325
{
326
+ partialobject * pto = _PyPartialObject_CAST (self );
322
327
Py_VISIT (Py_TYPE (pto ));
323
328
Py_VISIT (pto -> fn );
324
329
Py_VISIT (pto -> args );
@@ -328,16 +333,16 @@ partial_traverse(partialobject *pto, visitproc visit, void *arg)
328
333
}
329
334
330
335
static void
331
- partial_dealloc (partialobject * pto )
336
+ partial_dealloc (PyObject * self )
332
337
{
333
- PyTypeObject * tp = Py_TYPE (pto );
338
+ PyTypeObject * tp = Py_TYPE (self );
334
339
/* bpo-31095: UnTrack is needed before calling any callbacks */
335
- PyObject_GC_UnTrack (pto );
336
- if (pto -> weakreflist != NULL ) {
337
- PyObject_ClearWeakRefs (( PyObject * ) pto );
340
+ PyObject_GC_UnTrack (self );
341
+ if (_PyPartialObject_CAST ( self ) -> weakreflist != NULL ) {
342
+ PyObject_ClearWeakRefs (self );
338
343
}
339
- (void )partial_clear (pto );
340
- tp -> tp_free (pto );
344
+ (void )partial_clear (self );
345
+ tp -> tp_free (self );
341
346
Py_DECREF (tp );
342
347
}
343
348
@@ -360,14 +365,14 @@ partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto,
360
365
{
361
366
pto -> vectorcall = NULL ;
362
367
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
363
- return _PyObject_MakeTpCall (tstate , (PyObject * )pto ,
364
- args , nargs , kwnames );
368
+ return _PyObject_MakeTpCall (tstate , (PyObject * )pto , args , nargs , kwnames );
365
369
}
366
370
367
371
static PyObject *
368
- partial_vectorcall (partialobject * pto , PyObject * const * args ,
372
+ partial_vectorcall (PyObject * self , PyObject * const * args ,
369
373
size_t nargsf , PyObject * kwnames )
370
374
{
375
+ partialobject * pto = _PyPartialObject_CAST (self );;
371
376
PyThreadState * tstate = _PyThreadState_GET ();
372
377
Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
373
378
@@ -468,15 +473,16 @@ partial_setvectorcall(partialobject *pto)
468
473
* but that is unlikely (why use partial without arguments?),
469
474
* so we don't optimize that */
470
475
else {
471
- pto -> vectorcall = ( vectorcallfunc ) partial_vectorcall ;
476
+ pto -> vectorcall = partial_vectorcall ;
472
477
}
473
478
}
474
479
475
480
476
481
// Not converted to argument clinic, because of `*args, **kwargs` arguments.
477
482
static PyObject *
478
- partial_call (partialobject * pto , PyObject * args , PyObject * kwargs )
483
+ partial_call (PyObject * self , PyObject * args , PyObject * kwargs )
479
484
{
485
+ partialobject * pto = _PyPartialObject_CAST (self );
480
486
assert (PyCallable_Check (pto -> fn ));
481
487
assert (PyTuple_Check (pto -> args ));
482
488
assert (PyDict_Check (pto -> kw ));
@@ -587,8 +593,9 @@ static PyGetSetDef partial_getsetlist[] = {
587
593
};
588
594
589
595
static PyObject *
590
- partial_repr (partialobject * pto )
596
+ partial_repr (PyObject * self )
591
597
{
598
+ partialobject * pto = _PyPartialObject_CAST (self );
592
599
PyObject * result = NULL ;
593
600
PyObject * arglist ;
594
601
PyObject * mod ;
@@ -597,7 +604,7 @@ partial_repr(partialobject *pto)
597
604
PyObject * key , * value ;
598
605
int status ;
599
606
600
- status = Py_ReprEnter (( PyObject * ) pto );
607
+ status = Py_ReprEnter (self );
601
608
if (status != 0 ) {
602
609
if (status < 0 )
603
610
return NULL ;
@@ -608,7 +615,7 @@ partial_repr(partialobject *pto)
608
615
if (arglist == NULL )
609
616
goto done ;
610
617
/* Pack positional arguments */
611
- assert (PyTuple_Check (pto -> args ));
618
+ assert (PyTuple_Check (pto -> args ));
612
619
n = PyTuple_GET_SIZE (pto -> args );
613
620
for (i = 0 ; i < n ; i ++ ) {
614
621
Py_SETREF (arglist , PyUnicode_FromFormat ("%U, %R" , arglist ,
@@ -643,11 +650,11 @@ partial_repr(partialobject *pto)
643
650
Py_DECREF (arglist );
644
651
645
652
done :
646
- Py_ReprLeave (( PyObject * ) pto );
653
+ Py_ReprLeave (self );
647
654
return result ;
648
655
error :
649
656
Py_DECREF (arglist );
650
- Py_ReprLeave (( PyObject * ) pto );
657
+ Py_ReprLeave (self );
651
658
return NULL ;
652
659
}
653
660
@@ -659,16 +666,18 @@ partial_repr(partialobject *pto)
659
666
*/
660
667
661
668
static PyObject *
662
- partial_reduce (partialobject * pto , PyObject * unused )
669
+ partial_reduce (PyObject * self , PyObject * Py_UNUSED ( args ) )
663
670
{
671
+ partialobject * pto = _PyPartialObject_CAST (self );
664
672
return Py_BuildValue ("O(O)(OOOO)" , Py_TYPE (pto ), pto -> fn , pto -> fn ,
665
673
pto -> args , pto -> kw ,
666
674
pto -> dict ? pto -> dict : Py_None );
667
675
}
668
676
669
677
static PyObject *
670
- partial_setstate (partialobject * pto , PyObject * state )
678
+ partial_setstate (PyObject * self , PyObject * state )
671
679
{
680
+ partialobject * pto = _PyPartialObject_CAST (self );
672
681
PyObject * fn , * fnargs , * kw , * dict ;
673
682
674
683
if (!PyTuple_Check (state )) {
@@ -730,8 +739,8 @@ partial_setstate(partialobject *pto, PyObject *state)
730
739
}
731
740
732
741
static PyMethodDef partial_methods [] = {
733
- {"__reduce__" , ( PyCFunction ) partial_reduce , METH_NOARGS },
734
- {"__setstate__" , ( PyCFunction ) partial_setstate , METH_O },
742
+ {"__reduce__" , partial_reduce , METH_NOARGS },
743
+ {"__setstate__" , partial_setstate , METH_O },
735
744
{"__class_getitem__" , Py_GenericAlias ,
736
745
METH_O |METH_CLASS , PyDoc_STR ("See PEP 585" )},
737
746
{NULL , NULL } /* sentinel */
@@ -749,7 +758,7 @@ static PyType_Slot partial_type_slots[] = {
749
758
{Py_tp_methods , partial_methods },
750
759
{Py_tp_members , partial_memberlist },
751
760
{Py_tp_getset , partial_getsetlist },
752
- {Py_tp_descr_get , ( descrgetfunc ) partial_descr_get },
761
+ {Py_tp_descr_get , partial_descr_get },
753
762
{Py_tp_new , partial_new },
754
763
{Py_tp_free , PyObject_GC_Del },
755
764
{0 , 0 }
0 commit comments