Message308978
Using the following decorator to memoize a function causes the interpreter to segfault on exit if any exceptions were stored in the cache. Changing the bad line to instead store copy.copy(e) makes the problem go away.
Almost certainly some kind of problem with the GC of the traceback not happening at the moment the interpreter expects it, but I haven't had time to investigate any more deeply yet.
def memoize(keyFunc=lambda x: x, cacheExceptions: bool=True):
def wrapper(func):
return _Memo(func, keyFunc, cacheExceptions)
return wrapper
class _Memo(object):
def __init__(self, func, keyFunc, cacheExceptions: bool) -> None:
self.func = func
self.keyFunc = keyFunc
self.cacheExceptions = cacheExceptions
self.lock = threading.Lock()
self.cache = {}
def __call__(self, *args, **kwargs) -> Any:
key = self.keyFunc(*args, **kwargs)
assert isinstance(key, collections.Hashable)
with self.lock:
if key in self.cache:
value = self.cache[key]
if isinstance(value, BaseException):
raise value
return value
try:
result = self.func(*args, **kwargs)
except BaseException as e:
if self.cacheExceptions:
with self.lock:
self.cache[key] = e # BAD LINE
six.reraise(*sys.exc_info())
else:
with self.lock:
self.cache[key] = result
return result |
|
Date |
User |
Action |
Args |
2017-12-24 02:27:03 | zunger | set | recipients:
+ zunger |
2017-12-24 02:27:03 | zunger | set | messageid: <1514082423.32.0.213398074469.issue32421@psf.upfronthosting.co.za> |
2017-12-24 02:27:03 | zunger | link | issue32421 messages |
2017-12-24 02:27:00 | zunger | create | |
|