12
12
All rights reserved.
13
13
*/
14
14
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
-
27
15
typedef struct _functools_state {
28
16
/* this object is used delimit args and keywords in the cache keys */
29
17
PyObject * kwd_mark ;
@@ -40,6 +28,19 @@ get_functools_state(PyObject *module)
40
28
return (_functools_state * )state ;
41
29
}
42
30
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
+
43
44
static void partial_setvectorcall (partialobject * pto );
44
45
static struct PyModuleDef _functools_module ;
45
46
static PyObject *
@@ -781,13 +782,16 @@ typedef struct lru_cache_object {
781
782
PyObject * func ;
782
783
Py_ssize_t maxsize ;
783
784
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 ;
784
788
PyObject * cache_info_type ;
785
789
PyObject * dict ;
786
790
PyObject * weakreflist ;
787
791
} lru_cache_object ;
788
792
789
793
static PyObject *
790
- lru_cache_make_key (_functools_state * state , PyObject * args ,
794
+ lru_cache_make_key (PyObject * kwd_mark , PyObject * args ,
791
795
PyObject * kwds , int typed )
792
796
{
793
797
PyObject * key , * keyword , * value ;
@@ -827,8 +831,8 @@ lru_cache_make_key(_functools_state *state, PyObject *args,
827
831
PyTuple_SET_ITEM (key , key_pos ++ , item );
828
832
}
829
833
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 );
832
836
for (pos = 0 ; PyDict_Next (kwds , & pos , & keyword , & value );) {
833
837
Py_INCREF (keyword );
834
838
PyTuple_SET_ITEM (key , key_pos ++ , keyword );
@@ -872,12 +876,7 @@ infinite_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwd
872
876
{
873
877
PyObject * result ;
874
878
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 );
881
880
if (!key )
882
881
return NULL ;
883
882
hash = PyObject_Hash (key );
@@ -977,13 +976,8 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
977
976
lru_list_elem * link ;
978
977
PyObject * key , * result , * testresult ;
979
978
Py_hash_t hash ;
980
- _functools_state * state ;
981
979
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 );
987
981
if (!key )
988
982
return NULL ;
989
983
hash = PyObject_Hash (key );
@@ -1038,7 +1032,7 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
1038
1032
{
1039
1033
/* Cache is not full, so put the result in a new link */
1040
1034
link = (lru_list_elem * )PyObject_New (lru_list_elem ,
1041
- state -> lru_list_elem_type );
1035
+ self -> lru_list_elem_type );
1042
1036
if (link == NULL ) {
1043
1037
Py_DECREF (key );
1044
1038
Py_DECREF (result );
@@ -1149,6 +1143,7 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1149
1143
lru_cache_object * obj ;
1150
1144
Py_ssize_t maxsize ;
1151
1145
PyObject * (* wrapper )(lru_cache_object * , PyObject * , PyObject * );
1146
+ _functools_state * state ;
1152
1147
static char * keywords [] = {"user_function" , "maxsize" , "typed" ,
1153
1148
"cache_info_type" , NULL };
1154
1149
@@ -1164,6 +1159,11 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1164
1159
return NULL ;
1165
1160
}
1166
1161
1162
+ state = get_functools_state_by_type (type );
1163
+ if (state == NULL ) {
1164
+ return NULL ;
1165
+ }
1166
+
1167
1167
/* select the caching function, and make/inc maxsize_O */
1168
1168
if (maxsize_O == Py_None ) {
1169
1169
wrapper = infinite_lru_cache_wrapper ;
@@ -1203,6 +1203,10 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw)
1203
1203
obj -> func = func ;
1204
1204
obj -> misses = obj -> hits = 0 ;
1205
1205
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 ;
1206
1210
Py_INCREF (cache_info_type );
1207
1211
obj -> cache_info_type = cache_info_type ;
1208
1212
obj -> dict = NULL ;
@@ -1238,6 +1242,8 @@ lru_cache_tp_clear(lru_cache_object *self)
1238
1242
lru_list_elem * list = lru_cache_unlink_list (self );
1239
1243
Py_CLEAR (self -> func );
1240
1244
Py_CLEAR (self -> cache );
1245
+ Py_CLEAR (self -> kwd_mark );
1246
+ Py_CLEAR (self -> lru_list_elem_type );
1241
1247
Py_CLEAR (self -> cache_info_type );
1242
1248
Py_CLEAR (self -> dict );
1243
1249
lru_cache_clear_list (list );
@@ -1330,6 +1336,8 @@ lru_cache_tp_traverse(lru_cache_object *self, visitproc visit, void *arg)
1330
1336
}
1331
1337
Py_VISIT (self -> func );
1332
1338
Py_VISIT (self -> cache );
1339
+ Py_VISIT (self -> kwd_mark );
1340
+ Py_VISIT (self -> lru_list_elem_type );
1333
1341
Py_VISIT (self -> cache_info_type );
1334
1342
Py_VISIT (self -> dict );
1335
1343
return 0 ;
0 commit comments