[New-bugs-announce] [issue36650] Cached method implementation no longer works on Python 3.7.3

Jason R. Coombs report at bugs.python.org
Wed Apr 17 14:45:43 EDT 2019


New submission from Jason R. Coombs <jaraco at jaraco.com>:

In [this ticket](https://github.com/jaraco/jaraco.functools/issues/12), I learned that [jaraco.functools.method_cache](https://github.com/jaraco/jaraco.functools/blob/6b32ee0dfd3e7c88f99e88cd87c35fa9b76f261f/jaraco/functools.py#L109-L180) no longer works on Python 3.7.3.

A distilled version of what's not working is this example:

```
>>> import jaraco.functools
>>> class MyClass:
...   calls = 0
...   @jaraco.functools.method_cache
...   def call_me_maybe(self, val):
...     self.calls += 1
...     return val
... 
>>> a = MyClass()
>>> a.call_me_maybe(0)
0
>>> a.call_me_maybe(0)
0
>>> a.calls
2
```

The second call to the cached function is missing the cache even though the parameters to the function are the same.


```
>>> a.call_me_maybe
<functools._lru_cache_wrapper object at 0x107eb2df0>
>>> a.call_me_maybe.cache_info()
CacheInfo(hits=0, misses=2, maxsize=128, currsize=2)
```

Here's a further distilled example not relying on any code from jaraco.functools:

```
>>> def method_cache(method):
...     def wrapper(self, *args, **kwargs):
...             # it's the first call, replace the method with a cached, bound method
...             bound_method = functools.partial(method, self)
...             cached_method = functools.lru_cache()(bound_method)
...             setattr(self, method.__name__, cached_method)
...             return cached_method(*args, **kwargs)
...     return wrapper
... 
>>> import functools
>>> class MyClass:
...   calls = 0
...   @method_cache
...   def call_me_maybe(self, val):
...     self.calls += 1
...     return val
... 
>>> a = MyClass()
>>> a.call_me_maybe(0)
0
>>> a.call_me_maybe(0)
0
>>> a.calls
2
```

I was not able to replicate the issue with a simple lru_cache on a partial object:

```
>>> def func(a, b):
...   global calls
...   calls += 1
... 
>>> import functools
>>> cached = functools.lru_cache()(functools.partial(func, 'a'))
>>> calls = 0
>>> cached(0)
>>> cached(0)
>>> calls
1
```

Suggesting that there's some interaction with the instance attribute and the caching functionality.

I suspect the issue arose as a result of changes in issue35780.

----------
assignee: rhettinger
keywords: 3.7regression
messages: 340429
nosy: jaraco, rhettinger
priority: normal
severity: normal
status: open
title: Cached method implementation no longer works on Python 3.7.3

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue36650>
_______________________________________


More information about the New-bugs-announce mailing list