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.
