#9107: Nested class name mangling can be wrong in case of double nesting
------------------------------+---------------------------------------------
       Reporter:  hivert      |         Owner:  nthiery     
           Type:  defect      |        Status:  needs_review
       Priority:  major       |     Milestone:  sage-5.0    
      Component:  categories  |    Resolution:              
       Keywords:              |   Work issues:              
Report Upstream:  N/A         |     Reviewers:              
        Authors:  Simon King  |     Merged in:              
   Dependencies:  #12808      |      Stopgaps:              
------------------------------+---------------------------------------------
Changes (by {'newvalue': u'Simon King', 'oldvalue': ''}):

  * status:  new => needs_review
  * author:  => Simon King


Comment:

 I think the attached patch solves the problem. I get:
 {{{
 sage: class Bla(UniqueRepresentation):
 ....:     class Bla1(UniqueRepresentation):
 ....:         class Bla11:
 ....:             pass
 ....:     class Bla2:
 ....:         class Bla21:
 ....:             pass
 ....:
 sage: Bla.Bla1.Bla11
 <class __main__.Bla.Bla1.Bla11 at 0x46e7808>
 }}}

 The change is in `modify_for_nested_pickle`, which is called recursively.
 The idea is that the function should have an extra argument `first_run`,
 that is True by default. If the extra argument is False, then it is
 assumed that it is not applied for the first time.

 Here: Since Bla.Bla1 is an instance of `NestedClassMetaclass`,
 `modify_for_nested_pickle` is called on `Bla.Bla1.Bla11`, resulting in
 `Bla.Bla1.Bla11.__name__=='Bla1.Bla11'`. However, since Bla is an instance
 of `NestedClassMetaclass` as well, the function is applied to `Bla.Bla1`
 and thus recursively to `Bla.Bla1.Bla11` another time.

 Now, without my patch, in the second run, `modify_for_nested_pickle` would
 be confused by the fact that `Bla.Bla1.__dict__` lists `Bla.Bla1.Bla11`
 under the name `Bla11`, but `Bla11.__name__=='Bla1.Bla11'`. With my patch,
 `modify_for_nested_pickle` expects exactly that naming scheme, and is thus
 changing `Bla.Bla1.Bla11.__name__` into `"Bla.Bla1.Bla11"`.

 Much !BlaBla, but I think it works...

 '''__Potential problems__'''

 {{{
 sage: module = sys.modules['__main__']
 sage: getattr(module, 'Bla1.Bla11')
 <class __main__.Bla.Bla1.Bla11 at 0x46e7808>
 sage: getattr(module, 'Bla.Bla1.Bla11')
 <class __main__.Bla.Bla1.Bla11 at 0x46e7808>
 }}}
 Hence, Bla.Bla1.Bla11 is listed in the module under two different names.
 If you think it is bad, then one could probably modify the function when
 first_run is false, such that the name given in the first run is erased
 from the module.

 Moreover, the reviewer will likely find a speed regression, when
 excessively creating nested unique representations. But that's hardly
 realistic...

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/9107#comment:3>
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