- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 684
Closed
Closed
Copy link
Milestone
Description
The following happens both with Sage's MonoDict and with Python's weakref.WeakKeyDictionary:
from sage.structure.coerce_dict import MonoDict
M = MonoDict(11)
class A: pass
a = A()
prev = a
for i in range(1000):
    newA = A()
    M[prev] = newA
    prev = newA
len(M)
del a
Exception RuntimeError: 'maximum recursion depth exceeded while calling a Python object' in <sage.structure.coerce_dict.MonoDictEraser object at 0x5a13788> ignored
Replace M = MonoDict(11) by M = weakref.WeakKeyDictionary(), and you get essentially the same error:
sage: del a
Exception RuntimeError: 'maximum recursion depth exceeded while calling a Python object' in <function remove at 0x5f9d578> ignored
However, a weakref.WeakValueDictionary seems safe:
sage: class A: pass
sage: M = weakref.WeakValueDictionary()
sage: a = A()
....: prev = a
....: for i in range(1000):
....:     newA = A()
....:     M[newA] = prev
....:     prev = newA
....:     
sage: len(M)
1000
sage: del a
sage: len(M)
0
even though the recursive deletion of dictionary items seems similar.
Aim of this ticket: Make it so that the erasers of MonoDict and TripleDict are not recursively called and thus the dreaded 'maximum recursion depth exceeded ... ignored' finally vanishes.
Component: performance
Author: Simon King
Reviewer: Volker Braun
Merged: sage-5.12.beta4
Issue created by migration from https://trac.sagemath.org/ticket/15069