@@ -28,7 +28,6 @@ typedef struct _functools_state {
28
28
/* this object is used delimit args and keywords in the cache keys */
29
29
PyObject * kwd_mark ;
30
30
PyTypeObject * partial_type ;
31
- PyTypeObject * lru_cache_type ;
32
31
PyTypeObject * keyobject_type ;
33
32
PyTypeObject * lru_list_elem_type ;
34
33
} _functools_state ;
@@ -67,15 +66,13 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
67
66
return NULL ;
68
67
}
69
68
70
- _functools_state * state = get_functools_state_by_type (type );
71
- if (state == NULL ) {
72
- return NULL ;
73
- }
74
-
75
69
pargs = pkw = NULL ;
76
70
func = PyTuple_GET_ITEM (args , 0 );
77
- if (Py_IS_TYPE (func , state -> partial_type )
78
- && type == state -> partial_type ) {
71
+ if (Py_TYPE (func )-> tp_new == partial_new ) {
72
+ // The type of "func" might not be exactly the same type object
73
+ // as "type", but if it is called using partial_new, it must have the
74
+ // same memory layout (fn, args and kw members).
75
+ // We can use its underlying function directly and merge the arguments.
79
76
partialobject * part = (partialobject * )func ;
80
77
if (part -> dict == NULL ) {
81
78
pargs = part -> args ;
@@ -555,19 +552,15 @@ keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds)
555
552
{
556
553
PyObject * object ;
557
554
keyobject * result ;
558
- _functools_state * state ;
559
555
static char * kwargs [] = {"obj" , NULL };
560
556
561
557
if (!PyArg_ParseTupleAndKeywords (args , kwds , "O:K" , kwargs , & object ))
562
558
return NULL ;
563
559
564
- state = get_functools_state_by_type ( Py_TYPE (ko ));
565
- if (state == NULL ) {
560
+ result = PyObject_New ( keyobject , Py_TYPE (ko ));
561
+ if (result == NULL ) {
566
562
return NULL ;
567
563
}
568
- result = PyObject_New (keyobject , state -> keyobject_type );
569
- if (!result )
570
- return NULL ;
571
564
Py_INCREF (ko -> cmp );
572
565
result -> cmp = ko -> cmp ;
573
566
Py_INCREF (object );
@@ -584,13 +577,8 @@ keyobject_richcompare(PyObject *ko, PyObject *other, int op)
584
577
PyObject * compare ;
585
578
PyObject * answer ;
586
579
PyObject * stack [2 ];
587
- _functools_state * state ;
588
580
589
- state = get_functools_state_by_type (Py_TYPE (ko ));
590
- if (state == NULL ) {
591
- return NULL ;
592
- }
593
- if (!Py_IS_TYPE (other , state -> keyobject_type )) {
581
+ if (!Py_IS_TYPE (other , Py_TYPE (ko ))) {
594
582
PyErr_Format (PyExc_TypeError , "other argument must be K instance" );
595
583
return NULL ;
596
584
}
@@ -1437,12 +1425,13 @@ _functools_exec(PyObject *module)
1437
1425
return -1 ;
1438
1426
}
1439
1427
1440
- state -> lru_cache_type = ( PyTypeObject * ) PyType_FromModuleAndSpec (module ,
1428
+ PyObject * lru_cache_type = PyType_FromModuleAndSpec (module ,
1441
1429
& lru_cache_type_spec , NULL );
1442
- if (state -> lru_cache_type == NULL ) {
1430
+ if (lru_cache_type == NULL ) {
1443
1431
return -1 ;
1444
1432
}
1445
- if (PyModule_AddType (module , state -> lru_cache_type ) < 0 ) {
1433
+ if (PyModule_AddType (module , (PyTypeObject * )lru_cache_type ) < 0 ) {
1434
+ Py_DECREF (lru_cache_type );
1446
1435
return -1 ;
1447
1436
}
1448
1437
@@ -1473,7 +1462,6 @@ _functools_traverse(PyObject *module, visitproc visit, void *arg)
1473
1462
_functools_state * state = get_functools_state (module );
1474
1463
Py_VISIT (state -> kwd_mark );
1475
1464
Py_VISIT (state -> partial_type );
1476
- Py_VISIT (state -> lru_cache_type );
1477
1465
Py_VISIT (state -> keyobject_type );
1478
1466
Py_VISIT (state -> lru_list_elem_type );
1479
1467
return 0 ;
@@ -1485,7 +1473,6 @@ _functools_clear(PyObject *module)
1485
1473
_functools_state * state = get_functools_state (module );
1486
1474
Py_CLEAR (state -> kwd_mark );
1487
1475
Py_CLEAR (state -> partial_type );
1488
- Py_CLEAR (state -> lru_cache_type );
1489
1476
Py_CLEAR (state -> keyobject_type );
1490
1477
Py_CLEAR (state -> lru_list_elem_type );
1491
1478
return 0 ;
0 commit comments