#13394: Write a WeakValueDictionary with safer key removal
-------------------------------------+-------------------------------------
       Reporter:  nbruin             |        Owner:  rlm
           Type:  enhancement        |       Status:  needs_review
       Priority:  major              |    Milestone:  sage-5.13
      Component:  memleak            |   Resolution:
       Keywords:                     |    Merged in:
        Authors:  Simon King         |    Reviewers:
Report Upstream:  None of the above  |  Work issues:
  - read trac for reasoning.         |       Commit:
         Branch:                     |  fab0ed4112b9f798e2690f4c885b57cd711ea698
  u/SimonKing/ticket/13394           |     Stopgaps:
   Dependencies:                     |
-------------------------------------+-------------------------------------

Comment (by SimonKing):

 Replying to [comment:42 nbruin]:
 > Two notes:
 >  - hash values are `long`. You're using `int` for them in your code in
 some places.

 I thought so, too. However,
 {{{
 sage: type(hash(ZZ))
 <type 'int'>
 }}}
 and that's why I chose `int` in my code.

 >  - I think you might be going overboard a bit with the iteration
 protection. Python dictionaries (and lists) are clearly documented as not
 safe to mutate while iterating over them.

 Yes, but there should be an error and not a crash, in this case. Moreover,
 there should be no error if there is no iteration attempted by the user.
 And it seems to me that an iteration is detected where the user does not
 iterate.

 > Weak dictionaries are a little different because you never know if
 there's a callback triggered by a GC, so iterating over a weak dict would
 never be safe. However, I think the ''only'' thing to be guarded against
 is callbacks during iteration (so just defer them and execute them when
 the guard goes down again). Any other mutation is just for the user to
 live with.

 Yes, but I think the situation here looks different. I really can not see
 any iteration in the examples that fail for me. Hence, I thought there
 might something else going on, which motivated my question on the details
 of the callback function.

 With the current commit, the callback function protects its own internal
 iteration against other callbacks happening at the same time. Now, assume
 there is the callback of a value `v_0`, and we want to assign some value
 `D[k]=v` ''without'' iteration.

 Question: Is it possible that some lines of `D.__setitem__(k,v)` are
 executed, then some lines of the callback for `v_0` are executed, and then
 further lines of `D.__setitem__(k,v)` are executed, before finally the
 callback for `v_0` finishes?

 If the answer is "yes", then I know the problem:
 - `D.__setitem__(k,v)` starts
 - the callback for `v_0` starts, enters the iteration context, but does
 not exit the context yet
 - `D.__setitem__(k,v)` continues, and tests whether the dictionary is in
 an iteration context. Answer is "yes", and so an error is raised.

 Can this happen?

--
Ticket URL: <http://trac.sagemath.org/ticket/13394#comment:43>
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 unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to