On Tuesday, November 19, 2013 11:57:35 AM UTC-8, mmarco wrote:
>
> I didn't add any dictionary on my code. Maybe it is a problem with using 
> an auxiliar polynomial ring as an atribute?
>
 
In any situation where the hash depends on `__repr__` and `__repr__` 
requires attributes that are set only at the `setstate` phase of unpickling 
(and this tends to describe the default situation for parents in sage), you 
will have a problem pickling a circular structure involving dictionaries. 
Circular structures in sage are now basically part of the design. It's true 
that caching routines are particularly prone to producing such cycles, but 
they are not the only source.

The issue might be relatively easily solved on the level of 
sage.structure.category_object.CategoryObject. It implements a cached 
__hash__ method, with a cache that gets initialized in its __cinit__ 
anyway. The same class already has a custom __setstate__. We could augment 
that with a custom __reduce_ex__ which could generate code to initialize 
the hash cache upon pickle construction. Then, during the rest of the 
pickle process, the hash would simply be looked up from the cache rather 
than (failed to be) computed from repr.

The real issue is actually a little further up the chain already: 
sage.structure.sage_object.SageObject already has a custom __hash__ which 
uses repr, but without a cache.

Really, if you write a python class with a custom hash and equality testing 
and you want to provide pickling support, then you have to ensure that the 
construction call that gets constructed by `__reduce_ex__` already 
reinstates enough information on the object to make hash and equality 
testing work. Otherwise your object cannot be pickled in circular 
structures involving dictionaries.

Incidentally, the fact that sage.structure.category_object.SageObject 
provides a __hash__ but not an equality test is a little worrisome: hash 
and equality should really go hand-in-hand. It means that by default, 
SageObject equality is the same as identity and at least that can be 
determined without any initialization. But in that case using the "id" as 
hash would be much better (but probably not upon inheritance).

So, while pickling and early-reinstating the CategoryObject._hash attribute 
would help in some cases, one would probably still run into trouble for 
subclasses that declare their own equality test, which would likely refer 
to attributes only reinstated by setstate.

-- 
You received this message because you are subscribed to the Google Groups 
"sage-devel" 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-devel.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to