1212 All rights reserved.
1313*/
1414
15- /* partial object **********************************************************/
16-
17- typedef struct {
18- PyObject_HEAD
19- PyObject * fn ;
20- PyObject * args ;
21- PyObject * kw ;
22- PyObject * dict ; /* __dict__ */
23- PyObject * weakreflist ; /* List of weak references */
24- vectorcallfunc vectorcall ;
25- } partialobject ;
26-
2715typedef struct _functools_state {
2816 /* this object is used delimit args and keywords in the cache keys */
2917 PyObject * kwd_mark ;
@@ -40,6 +28,19 @@ get_functools_state(PyObject *module)
4028 return (_functools_state * )state ;
4129}
4230
31+
32+ /* partial object **********************************************************/
33+
34+ typedef struct {
35+ PyObject_HEAD
36+ PyObject * fn ;
37+ PyObject * args ;
38+ PyObject * kw ;
39+ PyObject * dict ; /* __dict__ */
40+ PyObject * weakreflist ; /* List of weak references */
41+ vectorcallfunc vectorcall ;
42+ } partialobject ;
43+
4344static void partial_setvectorcall (partialobject * pto );
4445static struct PyModuleDef _functools_module ;
4546static PyObject *
@@ -781,13 +782,16 @@ typedef struct lru_cache_object {
781782 PyObject * func ;
782783 Py_ssize_t maxsize ;
783784 Py_ssize_t misses ;
785+ /* the kwd_mark is used delimit args and keywords in the cache keys */
786+ PyObject * kwd_mark ;
787+ PyTypeObject * lru_list_elem_type ;
784788 PyObject * cache_info_type ;
785789 PyObject * dict ;
786790 PyObject * weakreflist ;
787791} lru_cache_object ;
788792
789793static PyObject *
790- lru_cache_make_key (_functools_state * state , PyObject * args ,
794+ lru_cache_make_key (PyObject * kwd_mark , PyObject * args ,
791795 PyObject * kwds , int typed )
792796{
793797 PyObject * key , * keyword , * value ;
@@ -827,8 +831,8 @@ lru_cache_make_key(_functools_state *state, PyObject *args,
827831 PyTuple_SET_ITEM (key , key_pos ++ , item );
828832 }
829833 if (kwds_size ) {
830- Py_INCREF (state -> kwd_mark );
831- PyTuple_SET_ITEM (key , key_pos ++ , state -> kwd_mark );
834+ Py_INCREF (kwd_mark );
835+ PyTuple_SET_ITEM (key , key_pos ++ , kwd_mark );
832836 for (pos = 0 ; PyDict_Next (kwds , & pos , & keyword , & value );) {
833837 Py_INCREF (keyword );
834838 PyTuple_SET_ITEM (key , key_pos ++ , keyword );
@@ -872,12 +876,7 @@ infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwd
872876{
873877 PyObject * result ;
874878 Py_hash_t hash ;
875- _functools_state * state ;
876- state = get_functools_state_by_type (Py_TYPE (self ));
877- if (state == NULL ) {
878- return NULL ;
879- }
880- PyObject * key = lru_cache_make_key (state , args , kwds , self -> typed );
879+ PyObject * key = lru_cache_make_key (self -> kwd_mark , args , kwds , self -> typed );
881880 if (!key )
882881 return NULL ;
883882 hash = PyObject_Hash (key );
@@ -977,13 +976,8 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
977976 lru_list_elem * link ;
978977 PyObject * key , * result , * testresult ;
979978 Py_hash_t hash ;
980- _functools_state * state ;
981979
982- state = get_functools_state_by_type (Py_TYPE (self ));
983- if (state == NULL ) {
984- return NULL ;
985- }
986- key = lru_cache_make_key (state , args , kwds , self -> typed );
980+ key = lru_cache_make_key (self -> kwd_mark , args , kwds , self -> typed );
987981 if (!key )
988982 return NULL ;
989983 hash = PyObject_Hash (key );
@@ -1038,7 +1032,7 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
10381032 {
10391033 /* Cache is not full, so put the result in a new link */
10401034 link = (lru_list_elem * )PyObject_New (lru_list_elem ,
1041- state -> lru_list_elem_type );
1035+ self -> lru_list_elem_type );
10421036 if (link == NULL ) {
10431037 Py_DECREF (key );
10441038 Py_DECREF (result );
@@ -1149,6 +1143,7 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
11491143 lru_cache_object * obj ;
11501144 Py_ssize_t maxsize ;
11511145 PyObject * (* wrapper )(lru_cache_object * , PyObject * , PyObject * );
1146+ _functools_state * state ;
11521147 static char * keywords [] = {"user_function" , "maxsize" , "typed" ,
11531148 "cache_info_type" , NULL };
11541149
@@ -1164,6 +1159,11 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
11641159 return NULL ;
11651160 }
11661161
1162+ state = get_functools_state_by_type (type );
1163+ if (state == NULL ) {
1164+ return NULL ;
1165+ }
1166+
11671167 /* select the caching function, and make/inc maxsize_O */
11681168 if (maxsize_O == Py_None ) {
11691169 wrapper = infinite_lru_cache_wrapper ;
@@ -1203,6 +1203,10 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
12031203 obj -> func = func ;
12041204 obj -> misses = obj -> hits = 0 ;
12051205 obj -> maxsize = maxsize ;
1206+ Py_INCREF (state -> kwd_mark );
1207+ obj -> kwd_mark = state -> kwd_mark ;
1208+ Py_INCREF (state -> lru_list_elem_type );
1209+ obj -> lru_list_elem_type = state -> lru_list_elem_type ;
12061210 Py_INCREF (cache_info_type );
12071211 obj -> cache_info_type = cache_info_type ;
12081212 obj -> dict = NULL ;
@@ -1238,6 +1242,8 @@ lru_cache_tp_clear(lru_cache_object *self)
12381242 lru_list_elem * list = lru_cache_unlink_list (self );
12391243 Py_CLEAR (self -> func );
12401244 Py_CLEAR (self -> cache );
1245+ Py_CLEAR (self -> kwd_mark );
1246+ Py_CLEAR (self -> lru_list_elem_type );
12411247 Py_CLEAR (self -> cache_info_type );
12421248 Py_CLEAR (self -> dict );
12431249 lru_cache_clear_list (list );
@@ -1330,6 +1336,8 @@ lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
13301336 }
13311337 Py_VISIT (self -> func );
13321338 Py_VISIT (self -> cache );
1339+ Py_VISIT (self -> kwd_mark );
1340+ Py_VISIT (self -> lru_list_elem_type );
13331341 Py_VISIT (self -> cache_info_type );
13341342 Py_VISIT (self -> dict );
13351343 return 0 ;
0 commit comments