Dear c-level python specialists,

Nested classes in python are really handy, and work pretty well,
except for a bug in pickling:

Let's define a nested class:

        sage: class Bla:                                                      
        ....:     class Ble:                                                  
        ....:         pass                                                    
        ....:

Let's fake Bla is defined in a module, not in the interpreter:

        sage: import __main__   
        sage: __main__.Bla = Bla

Dumping an element of Bla works just fine:
        sage: x = Bla()
        sage: dumps(x)
        
"x\x9ck`\xd2H\x8e\x8f\xcfM\xcc\xcc\x8b\x8f\xe7r\xcaI\xe4*d\xcc/d\xaa-dN\xd2\x03\x00v\xe3\x08'"

But dumping an element of Bla.Ble breaks:

        sage: x = Bla.Ble()
        sage: dumps(x)
        
---------------------------------------------------------------------------
        PicklingError                             Traceback (most recent call 
last)

        
/home/nthiery/.sage/temp/zephyr/23765/_home_nthiery__sage_init_sage_0.py in 
<module>()

        
/opt/sage/local/lib/python2.5/site-packages/sage/structure/sage_object.so in 
sage.structure.sage_object.dumps (sage/structure/sage_object.c:5539)()

        PicklingError: Can't pickle __main__.Ble: attribute lookup __main__.Ble 
failed
        > 
/opt/sage-3.4.rc0/devel/sage-combinat/sage/sage_object.pyx(571)sage.structure.sage_object.dumps
 (sage/structure/sage_object.c:5539)()
        
---------------------------------------------------------------------------


The reason behind this is twofold:

First, the name of the class is improperly set:

        sage: Bla.Ble
        <class __main__.Ble at 0xb1e7c98c>
        sage: Bla.Ble.__name__
        'Ble'

(which btw probably breaks other tools around)

Well, let's work around this:

        sage: Bla.Ble.__name__ = "Bla.Ble"

But then, a second problem: the code of cPickle (around line 1977)
tries to lookup the attribute "Bla.Ble" in __main__, instead of
successively looking up "Bla" in __main__, and then "Ble" in the result:


        sage: dumps(Bla.Ble)
        
---------------------------------------------------------------------------
        PicklingError                             Traceback (most recent call 
last)
        
/home/nthiery/.sage/temp/zephyr/23765/_home_nthiery__sage_init_sage_0.py in 
<module>()
        
/opt/sage/local/lib/python2.5/site-packages/sage/structure/sage_object.so in 
sage.structure.sage_object.dumps (sage/structure/sage_object.c:5539)()
        PicklingError: Can't pickle __main__.Bla.Ble: attribute lookup 
__main__.Bla.Ble failed
        > 
/opt/sage-3.4.rc0/devel/sage-combinat/sage/sage_object.pyx(571)sage.structure.sage_object.dumps
 (sage/structure/sage_object.c:5539)()


It would take me a couple hours to learn the syntax to write c-code
for python modules. Could any of the experts out there write me a
2-line patch upon cPickle:1977 to do the right thing (i.e. split
__name__, and make the attribute lookup for each bit)? Just a draft
will be fine; I am fine with reading and simple debuging.

Thanks in advance!

Best regards,
                                Nicolas

Here is the broken code:

        mod = PyImport_ImportModule(module_str);
        if (mod == NULL) {
                cPickle_ErrFormat(PicklingError,
                                  "Can't pickle %s: import of module %s "
                                  "failed",
                                  "OS", args, module);
                goto finally;
        }
        ############### HERE ####################
        klass = PyObject_GetAttrString(mod, name_str);
        if (klass == NULL) {
                cPickle_ErrFormat(PicklingError,
                                  "Can't pickle %s: attribute lookup %s.%s "
                                  "failed",
                                  "OSS", args, module, global_name);
                goto finally;
        }

--
Nicolas M. ThiƩry "Isil" <nthi...@users.sf.net>
http://Nicolas.Thiery.name/

--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to sage-devel@googlegroups.com
To unsubscribe from this group, send email to 
sage-devel-unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URLs: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---

Reply via email to