#12313: Fix yet another memory leak caused by caching of coercion data
-------------------------------------------------+--------------------------
       Reporter:  SimonKing                      |         Owner:               
                                        
           Type:  defect                         |        Status:  
positive_review                                      
       Priority:  major                          |     Milestone:  sage-pending 
                                        
      Component:  memleak                        |    Resolution:               
                                        
       Keywords:  coercion weak dictionary       |   Work issues:               
                                        
Report Upstream:  N/A                            |     Reviewers:  Simon King, 
Jean-Pierre Flori, John Perry, Nils Bruin
        Authors:  Simon King, Jean-Pierre Flori  |     Merged in:               
                                        
   Dependencies:  #715, #11521, #12215, #13746   |      Stopgaps:               
                                        
-------------------------------------------------+--------------------------

Comment (by nbruin):

 Unfortunately, doctests don't all succeed for me. I've built 5.6rc0 from
 scratch and applied #12215 and #12313. I get a SIGFPE in
 {{{
  ./sage -t -force_lib devel/sage/sage/schemes/elliptic_curves/heegner.py
 }}}
 gdb:
 {{{
 Program received signal SIGFPE, Arithmetic exception.
 __pyx_pf_4sage_9structure_11coerce_dict_16TripleDictEraser_2__call__
 (__pyx_v_r=<optimized out>,
     __pyx_v_self=<optimized out>) at sage/structure/coerce_dict.c:1107
 1107      __pyx_t_10 = PyList_GET_ITEM(__pyx_t_1, (__pyx_v_h %
 PyList_GET_SIZE(__pyx_t_4)));
 (gdb) l
 1102     */
 1103      __pyx_t_1 = __pyx_v_self->D->buckets;
 1104      __Pyx_INCREF(__pyx_t_1);
 1105      __pyx_t_4 = __pyx_v_self->D->buckets;
 1106      __Pyx_INCREF(__pyx_t_4);
 1107      __pyx_t_10 = PyList_GET_ITEM(__pyx_t_1, (__pyx_v_h %
 PyList_GET_SIZE(__pyx_t_4)));
 (gdb) p PyString_AsString(PyObject_Repr(__pyx_t_4))
 $4 = 0xd5090e4 "None"
 }}}
 So at this point `self.D.buckets==None`. Doing list-type transactions
 using non-error checking macros is probably not a good idea. This code
 corresponds to `structure/coerce_dict.pyx:121`. Apparently, a callback is
 happening while the dictionary itself is already being torn down!

 A traceback indeed shows that this is all happening as part of a garbage
 collection of a TripleDict (I think that's what frame 15
 indicates),ironically, triggered by the allocation of a new TripleDict.
 I'm including rather a lot of the backtrace, because frame 100 is already
 in the sage library: Apparently, some operations easily trigger 100 level
 deep stacks!
 {{{
 (gdb) bt
 #0  __pyx_pf_4sage_9structure_11coerce_dict_16TripleDictEraser_2__call__
 (__pyx_v_r=<optimized out>,
     __pyx_v_self=<optimized out>) at sage/structure/coerce_dict.c:1107
 #1  __pyx_pw_4sage_9structure_11coerce_dict_16TripleDictEraser_3__call__
 (__pyx_v_self=0xb4f17c0,
     __pyx_args=<optimized out>, __pyx_kwds=<optimized out>) at
 sage/structure/coerce_dict.c:966
 #2  0x00007ffff7c6f403 in PyObject_Call (func=0xb4f17c0, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #3  0x00007ffff7c6fcf0 in PyObject_CallFunctionObjArgs
 (callable=0xb4f17c0) at Objects/abstract.c:2760
 #4  0x00007ffff7cd7b91 in handle_callback (callback=0xb4f17c0,
 ref=<optimized out>) at Objects/weakrefobject.c:881
 #5  PyObject_ClearWeakRefs (object=<optimized out>) at
 Objects/weakrefobject.c:965
 #6  0x00007fffea42e0e8 in
 __pyx_tp_dealloc_4sage_9structure_15category_object_CategoryObject
 (o=0x7843e30)
     at sage/structure/category_object.c:8990
 #7  0x00007ffff7cc7b76 in subtype_dealloc (self=0x7843e30) at
 Objects/typeobject.c:1014
 #8  0x00007ffff7cc4fa3 in tupledealloc (op=0xc1518d0) at
 Objects/tupleobject.c:220
 #9  0x00007ffff7cc4fa3 in tupledealloc (op=0xc455c30) at
 Objects/tupleobject.c:220
 #10 0x00007ffff7ca905f in dict_dealloc (mp=0x7856310) at
 Objects/dictobject.c:985
 #11 0x00007ffff7cc7bc4 in subtype_dealloc (self=0xbdf2f10) at
 Objects/typeobject.c:999
 #12 0x00007fffe90f8cc7 in
 __pyx_tp_dealloc_4sage_10categories_7functor_Functor (o=0xa7e09d0)
     at sage/categories/functor.c:3209
 #13 0x00007ffff7c9bb5a in list_dealloc (op=0xbbede60) at
 Objects/listobject.c:309
 #14 0x00007ffff7c9bb5a in list_dealloc (op=0xb771170) at
 Objects/listobject.c:309
 #15 0x00007fffe9dee8df in
 __pyx_tp_clear_4sage_9structure_11coerce_dict_TripleDict (o=0xb8d73b0)
     at sage/structure/coerce_dict.c:5921
 #16 0x00007ffff7d4b637 in delete_garbage (old=0x7ffff7fe19e0,
 collectable=0x7fffffff80f0) at Modules/gcmodule.c:769
 #17 collect (generation=2) at Modules/gcmodule.c:930
 #18 0x00007ffff7d4c1a8 in collect_generations () at Modules/gcmodule.c:996
 #19 _PyObject_GC_Malloc (basicsize=<optimized out>) at
 Modules/gcmodule.c:1457
 #20 _PyObject_GC_Malloc (basicsize=<optimized out>) at
 Modules/gcmodule.c:1439
 #21 0x00007ffff7cc7c19 in PyType_GenericAlloc (type=0x7fffea004d00,
 nitems=0) at Objects/typeobject.c:753
 #22 0x00007fffe9dee7ef in
 __pyx_tp_new_4sage_9structure_11coerce_dict_TripleDict (t=<optimized out>,
 a=<optimized out>,
     k=<optimized out>) at sage/structure/coerce_dict.c:5881
 #23 0x00007ffff7ccbd83 in type_call (type=0x7fffea004d00, args=0xf507d0,
 kwds=0x0) at Objects/typeobject.c:721
 #24 0x00007ffff7c6f403 in PyObject_Call (func=0x7fffea004d00,
 arg=<optimized out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #25 0x00007fffea65da43 in
 __pyx_f_4sage_9structure_6parent_6Parent_init_coerce
 (__pyx_v_self=0x5083a80,
     __pyx_optional_args=<optimized out>) at sage/structure/parent.c:5765
 #26 0x00007fffea8a00ff in
 __pyx_f_4sage_9structure_10parent_old_6Parent_init_coerce
 (__pyx_v_self=<optimized out>,
     __pyx_optional_args=<optimized out>) at
 sage/structure/parent_old.c:1634
 #27 0x00007fffea8a6cc4 in
 __pyx_pf_4sage_9structure_10parent_old_6Parent___init__
 (__pyx_v_category=0x7ffff7fc6840,
     __pyx_v_embeddings=0x1038908, __pyx_v_actions=0x10388c0,
 __pyx_v_coerce_from=0x10381b8, __pyx_v_self=0x5083a80)
     at sage/structure/parent_old.c:1329
 #28 __pyx_pw_4sage_9structure_10parent_old_6Parent_1__init__
 (__pyx_v_self=0x5083a80, __pyx_args=<optimized out>,
     __pyx_kwds=0x508bf00) at sage/structure/parent_old.c:1297
 #29 0x00007ffff7cc664c in wrap_init (self=<optimized out>, args=<optimized
 out>, wrapped=<optimized out>,
     kwds=<optimized out>) at Objects/typeobject.c:4719
 #30 0x00007ffff7c6f403 in PyObject_Call (func=0xd30f710, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #31 0x00007ffff7d0cc97 in PyEval_CallObjectWithKeywords (func=0xd30f710,
 arg=0x7ffff7bbb050, kw=<optimized out>)
     at Python/ceval.c:3890
 #32 0x00007ffff7c86e69 in wrapperdescr_call (descr=<optimized out>,
 args=0x7ffff7bbb050, kwds=0x508bf00)
     at Objects/descrobject.c:306
 #33 0x00007ffff7c6f403 in PyObject_Call (func=0xfc0960, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #34 0x00007fffeaab5269 in
 __pyx_pf_4sage_9structure_11parent_base_14ParentWithBase___init__ (
     __pyx_v_category=0x7ffff7fc6840, __pyx_v_embeddings=0x1038908,
 __pyx_v_actions=0x10388c0,
     __pyx_v_coerce_from=0x10381b8, __pyx_v_base=0x8593c60,
 __pyx_v_self=0x5083a80) at sage/structure/parent_base.c:1258
 ---Type <return> to continue, or q <return> to quit---
 #35 __pyx_pw_4sage_9structure_11parent_base_14ParentWithBase_1__init__
 (__pyx_v_self=0x5083a80,
     __pyx_args=<optimized out>, __pyx_kwds=<optimized out>) at
 sage/structure/parent_base.c:1221
 #36 0x00007ffff7cc664c in wrap_init (self=<optimized out>, args=<optimized
 out>, wrapped=<optimized out>,
     kwds=<optimized out>) at Objects/typeobject.c:4719
 #37 0x00007ffff7c6f403 in PyObject_Call (func=0xd30f6d0, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #38 0x00007ffff7d0cc97 in PyEval_CallObjectWithKeywords (func=0xd30f6d0,
 arg=0xd2f7d90, kw=<optimized out>)
     at Python/ceval.c:3890
 #39 0x00007ffff7c86e69 in wrapperdescr_call (descr=<optimized out>,
 args=0xd2f7d90, kwds=0x508bde0)
     at Objects/descrobject.c:306
 #40 0x00007ffff7c6f403 in PyObject_Call (func=0x1033320, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #41 0x00007fffe746a727 in
 __pyx_pf_4sage_9structure_11parent_gens_14ParentWithGens___init__ (
     __pyx_v_category=0x7ffff7fc6840, __pyx_v_normalize=<optimized out>,
 __pyx_v_names=0x7ffff7fc6840,
     __pyx_v_base=0x8593c60, __pyx_v_self=0x5083a80) at
 sage/structure/parent_gens.c:2781
 #42 __pyx_pw_4sage_9structure_11parent_gens_14ParentWithGens_1__init__
 (__pyx_v_self=0x5083a80,
     __pyx_args=<optimized out>, __pyx_kwds=<optimized out>) at
 sage/structure/parent_gens.c:2697
 #43 0x00007ffff7cc664c in wrap_init (self=<optimized out>, args=<optimized
 out>, wrapped=<optimized out>,
     kwds=<optimized out>) at Objects/typeobject.c:4719
 #44 0x00007ffff7c6f403 in PyObject_Call (func=0xd29f0d0, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #45 0x00007ffff7d0cc97 in PyEval_CallObjectWithKeywords (func=0xd29f0d0,
 arg=0xd2a2290, kw=<optimized out>)
     at Python/ceval.c:3890
 #46 0x00007ffff7c86e69 in wrapperdescr_call (descr=<optimized out>,
 args=0xd2a2290, kwds=0x0)
     at Objects/descrobject.c:306
 #47 0x00007ffff7c6f403 in PyObject_Call (func=0x1033cd0, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #48 0x00007ffff7d1124d in do_call (nk=<optimized out>, na=<optimized out>,
 pp_stack=0x7fffffff8830, func=0x1033cd0)
     at Python/ceval.c:4239
 #49 call_function (oparg=<optimized out>, pp_stack=0x7fffffff8830) at
 Python/ceval.c:4044
 #50 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at
 Python/ceval.c:2666
 #51 0x00007ffff7d14275 in PyEval_EvalCodeEx (co=<optimized out>,
 globals=<optimized out>, locals=<optimized out>,
     args=<optimized out>, argcount=5, kws=0x7ffff7bbb068, kwcount=0,
 defs=0x1c61bf0, defcount=2, closure=0x0)
     at Python/ceval.c:3253
 #52 0x00007ffff7c97273 in function_call (func=0x1db1488, arg=0xd1b27d0,
 kw=0x50af1a0) at Objects/funcobject.c:526
 #53 0x00007ffff7c6f403 in PyObject_Call (func=0x1db1488, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #54 0x00007ffff7c7cb4f in instancemethod_call (func=0x1db1488,
 arg=0xd1b27d0, kw=0x50af1a0) at Objects/classobject.c:2578
 #55 0x00007ffff7c6f403 in PyObject_Call (func=0xd2d7230, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #56 0x00007ffff7ccffd0 in slot_tp_init (self=0x5083a80, args=0xd1de100,
 kwds=0x50af1a0) at Objects/typeobject.c:5663
 #57 0x00007ffff7ccbdc8 in type_call (type=<optimized out>, args=0xd1de100,
 kwds=0x50af1a0) at Objects/typeobject.c:737
 #58 0x00007fffed3f5766 in
 __pyx_pf_4sage_4misc_19classcall_metaclass_typecall
 (__pyx_v_opts=0x50af1a0,
     __pyx_v_args=0xd1de100, __pyx_v_cls=0x1ee43a0, __pyx_self=<optimized
 out>) at sage/misc/classcall_metaclass.c:1294
 #59 __pyx_pw_4sage_4misc_19classcall_metaclass_1typecall
 (__pyx_self=<optimized out>, __pyx_args=<optimized out>,
     __pyx_kwds=<optimized out>) at sage/misc/classcall_metaclass.c:1257
 #60 0x00007ffff7d12198 in ext_do_call (nk=0, na=<optimized out>,
 flags=<optimized out>, pp_stack=0x7fffffff8e60,
     func=0x995c20) at Python/ceval.c:4331
 #61 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at
 Python/ceval.c:2705
 #62 0x00007ffff7d14275 in PyEval_EvalCodeEx (co=<optimized out>,
 globals=<optimized out>, locals=<optimized out>,
     args=<optimized out>, argcount=5, kws=0x7ffff7bbb068, kwcount=0,
 defs=0x0, defcount=0, closure=0x0)
     at Python/ceval.c:3253
 #63 0x00007ffff7c97273 in function_call (func=0x99d050, arg=0xd1d4710,
 kw=0x6004d00) at Objects/funcobject.c:526
 #64 0x00007ffff7c6f403 in PyObject_Call (func=0x99d050, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 ---Type <return> to continue, or q <return> to quit---
 #65 0x00007fffed816e8d in
 __pyx_pf_4sage_4misc_9cachefunc_18WeakCachedFunction_2__call__
 (__pyx_v_kwds=0x6004d00,
     __pyx_v_args=0xd1d4710, __pyx_v_self=0x919f30) at
 sage/misc/cachefunc.c:5080
 #66 __pyx_pw_4sage_4misc_9cachefunc_18WeakCachedFunction_3__call__
 (__pyx_v_self=0x919f30, __pyx_args=0xd1d4710,
     __pyx_kwds=<optimized out>) at sage/misc/cachefunc.c:4888
 #67 0x00007ffff7c6f403 in PyObject_Call (func=0x919f30, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #68 0x00007ffff7d1124d in do_call (nk=<optimized out>, na=<optimized out>,
 pp_stack=0x7fffffff9220, func=0x919f30)
     at Python/ceval.c:4239
 #69 call_function (oparg=<optimized out>, pp_stack=0x7fffffff9220) at
 Python/ceval.c:4044
 #70 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at
 Python/ceval.c:2666
 #71 0x00007ffff7d14275 in PyEval_EvalCodeEx (co=<optimized out>,
 globals=<optimized out>, locals=<optimized out>,
     args=<optimized out>, argcount=4, kws=0xd2ff608, kwcount=1,
 defs=0x1bf4968, defcount=2, closure=0x0)
     at Python/ceval.c:3253
 #72 0x00007ffff7c97273 in function_call (func=0x1db1140, arg=0xd2caaa0,
 kw=0x6456560) at Objects/funcobject.c:526
 #73 0x00007ffff7c6f403 in PyObject_Call (func=0x1db1140, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #74 0x00007fffed3f4a13 in
 __pyx_pf_4sage_4misc_19classcall_metaclass_18ClasscallMetaclass_2__call__
 (
     __pyx_v_opts=0x6456560, __pyx_v_args=0xd2a4690, __pyx_v_cls=0x1ee43a0)
 at sage/misc/classcall_metaclass.c:932
 #75
 __pyx_pw_4sage_4misc_19classcall_metaclass_18ClasscallMetaclass_3__call__
 (__pyx_v_cls=0x1ee43a0,
     __pyx_args=0xd2a4690, __pyx_kwds=<optimized out>) at
 sage/misc/classcall_metaclass.c:872
 #76 0x00007ffff7c6f403 in PyObject_Call (func=0x1ee43a0, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #77 0x00007fffd42b707d in
 __pyx_f_4sage_6matrix_20matrix_integer_dense_20Matrix_integer_dense__mod_int_c
 (
     __pyx_v_self=0xd2725f0, __pyx_v_p=19) at
 sage/matrix/matrix_integer_dense.c:13674
 #78 0x00007fffd429678a in
 __pyx_pf_4sage_6matrix_20matrix_integer_dense_20Matrix_integer_dense_46_mod_int
 (
     __pyx_v_modulus=0xbbe8390, __pyx_v_self=0xd2725f0) at
 sage/matrix/matrix_integer_dense.c:13277
 #79
 __pyx_pw_4sage_6matrix_20matrix_integer_dense_20Matrix_integer_dense_47_mod_int
 (__pyx_v_self=0xd2725f0,
     __pyx_v_modulus=0xbbe8390) at sage/matrix/matrix_integer_dense.c:13196
 #80 0x00007ffff7c6f403 in PyObject_Call (func=0xd2967a0, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #81 0x00007fffd3c13807 in
 
__pyx_pf_4sage_6matrix_21matrix_rational_dense_21Matrix_rational_dense_56change_ring
 (
     __pyx_v_R=<optimized out>, __pyx_v_self=0xd302398) at
 sage/matrix/matrix_rational_dense.c:14605
 #82
 
__pyx_pw_4sage_6matrix_21matrix_rational_dense_21Matrix_rational_dense_57change_ring
 (__pyx_v_self=0xd302398,
     __pyx_v_R=<optimized out>) at
 sage/matrix/matrix_rational_dense.c:14120
 #83 0x00007ffff7d13158 in call_function (oparg=<optimized out>,
 pp_stack=0x7fffffff9710) at Python/ceval.c:4009
 #84 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at
 Python/ceval.c:2666
 #85 0x00007ffff7d133cb in fast_function (nk=<optimized out>, na=2,
 n=<optimized out>, pp_stack=0x7fffffff9870,
     func=0x195a398) at Python/ceval.c:4107
 #86 call_function (oparg=<optimized out>, pp_stack=0x7fffffff9870) at
 Python/ceval.c:4042
 #87 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>) at
 Python/ceval.c:2666
 #88 0x00007ffff7d14275 in PyEval_EvalCodeEx (co=<optimized out>,
 globals=<optimized out>, locals=<optimized out>,
     args=<optimized out>, argcount=2, kws=0x0, kwcount=0, defs=0x0,
 defcount=0, closure=0x0) at Python/ceval.c:3253
 #89 0x00007ffff7c9717c in function_call (func=0x195a230, arg=0xd3122d8,
 kw=0x0) at Objects/funcobject.c:526
 #90 0x00007ffff7c6f403 in PyObject_Call (func=0x195a230, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #91 0x00007ffff7c7cb4f in instancemethod_call (func=0x195a230,
 arg=0xd3122d8, kw=0x0) at Objects/classobject.c:2578
 #92 0x00007ffff7c6f403 in PyObject_Call (func=0xd2a49b0, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #93 0x00007fffd62ed50b in
 __pyx_pf_4sage_5rings_13residue_field_19ResidueFieldFactory_2create_object
 (
     __pyx_v_key=<optimized out>, __pyx_self=<optimized out>,
 __pyx_v_self=<optimized out>,
     __pyx_v_version=<optimized out>, __pyx_v_kwds=<optimized out>) at
 sage/rings/residue_field.c:5002
 #94
 __pyx_pw_4sage_5rings_13residue_field_19ResidueFieldFactory_3create_object
 (__pyx_self=<optimized out>,
     __pyx_args=<optimized out>, __pyx_kwds=<optimized out>) at
 sage/rings/residue_field.c:4295
 #95 0x00007ffff7c6f403 in PyObject_Call (func=0x1c8c1a0, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 ---Type <return> to continue, or q <return> to quit---
 #96 0x00007ffff7c7cb4f in instancemethod_call (func=0x1c8c1a0,
 arg=0xd2a4370, kw=0x64430f0) at Objects/classobject.c:2578
 #97 0x00007ffff7c6f403 in PyObject_Call (func=0xd2faa50, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #98 0x00007fffdec2d5d6 in
 __pyx_f_4sage_9structure_7factory_13UniqueFactory_get_object
 (__pyx_v_self=0x1c8e0a8,
     __pyx_v_version=0x162df50, __pyx_v_key=0xd0378c0,
 __pyx_v_extra_args=0x64430f0, __pyx_skip_dispatch=<optimized out>)
     at sage/structure/factory.c:1311
 #99 0x00007fffdec2cb70 in
 __pyx_pf_4sage_9structure_7factory_13UniqueFactory_4__call__
 (__pyx_v_kwds=0x64430f0,
     __pyx_v_args=0xd30f1d0, __pyx_v_self=0x1c8e0a8) at
 sage/structure/factory.c:1119
 #100 __pyx_pw_4sage_9structure_7factory_13UniqueFactory_5__call__
 (__pyx_v_self=0x1c8e0a8, __pyx_args=0xd30f1d0,
     __pyx_kwds=<optimized out>) at sage/structure/factory.c:987
 #101 0x00007ffff7c6f403 in PyObject_Call (func=0x1c8e0a8, arg=<optimized
 out>, kw=<optimized out>)
     at Objects/abstract.c:2529
 #102 0x00007ffff7d1124d in do_call (nk=<optimized out>, na=<optimized
 out>, pp_stack=0x7fffffffa360, func=0x1c8e0a8)
     at Python/ceval.c:4239
 }}}
 Anyway, I had originally thought that callbacks in these situations would
 be collected and discarded, but apparently we have a scenario here that's
 not detected by the python GC. If my diagnosis is correct, we should not
 assume that attributes on `self.D` are still valid in `TripleDictEraser`,
 which surprises me a bit. It's easily checked of course: If
 `self.D.buckets` is `None`, we don't have to do anything. Relevant code:
 {{{
 static int
 __pyx_tp_clear_4sage_9structure_11coerce_dict_TripleDict(PyObject *o) {
   struct __pyx_obj_4sage_9structure_11coerce_dict_TripleDict *p = (struct
 __pyx_obj_4sage_9structure_11coerce_dict_TripleDict *)o;
   PyObject* tmp;
   tmp = ((PyObject*)p->buckets);
   p->buckets = Py_None; Py_INCREF(Py_None);
   Py_XDECREF(tmp);
   tmp = ((PyObject*)p->_refcache);
   p->_refcache = ((PyObject*)Py_None); Py_INCREF(Py_None);
   Py_XDECREF(tmp);
   tmp = ((PyObject*)p->eraser);
   p->eraser = ((struct
 __pyx_obj_4sage_9structure_11coerce_dict_TripleDictEraser *)Py_None);
 Py_INCREF(Py_None);
   Py_XDECREF(tmp);
   return 0;
 }
 }}}
 so indeed, `D.buckets` is set to `None` before `D.buckets` is deleted. I'm
 surprised that this deletion (of something that is garbage, so the eraser,
 which has an indirect strong link to it, must be garbage as well)
 apparently can still trigger a callback. It wouldn't surprise me if we
 could engineer this into something that would be considered a bug in
 Python. Anyway, to be safe, check that self.D.buckets is still alive
 before we do something with it! (either that or my sage/python build is
 seriously screwed and I'm seeing something that shouldn't happen).

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/12313#comment:266>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sage-trac?hl=en.

Reply via email to