Ticket #5986 (closed defect: fixed)
[with patch, positive review] Workaround mishandled nested classes in Python and cPickle
| Reported by: | nthiery | Owned by: | nthiery |
|---|---|---|---|
| Priority: | major | Milestone: | sage-4.2 |
| Component: | misc | Keywords: | pickling, nested classes |
| Cc: | sage-combinat, cwitty | Author(s): | Craig Citro, Nicolas M. Thiéry |
| Report Upstream: | Reviewer(s): | Robert Bradshaw | |
| Merged in: | sage-4.2.alpha0 | Work issues: |
Description (last modified by nthiery) (diff)
With the python code below::
class A:
class B:
pass
Python 2.6 erroneously set the B.name to "B" instead of "A.B".
Furthermore, upon pickling (here in save_global) *and* unpickling (in load_global) a class with name "A.B" in a module mod, the standard cPickle module searches for "A.B" in mod.dict instead of looking up "A" and then "B" in the result.
This patch works around this by a patch to cPickle.c (in fact a copy of it in the Sage source tree; see #5985) which fixes the name for B to its appropriate value A.B, and inserts 'A.B' = A.B in mod.dict (hacky, but seems to work) the first time A.B is pickled, and fixes load_global to implement a proper lookup upon unpickling.
It also ensures that sage/interfaces/sage0.py uses loads/dumps from sage_object rather than calling directly cPickle.loads/dumps (+1 by cwitty on this change)
Python source experts are more than welcome to rework/rewrite this patch!

