Skip to content
This repository was archived by the owner on Feb 1, 2023. It is now read-only.

Commit d6cf85b

Browse files
author
Release Manager
committed
Trac #31182: Mutability class and pickling
If the class `Mutability` is used as mixin for mutability features, the pickling goes wrong (see [https://trac.sagemath.org/ticket/30261#comment:9 here]). An attempt using this mixin class after #30281, still throws a pickling test error, e.g. in #30310: {{{ File "src/sage/manifolds/chart_func.py", line 2944, in sage.manifolds.chart_func.MultiCoordFunction.__init__ Failed example: TestSuite(f).run() Expected nothing Got: Failure in _test_pickling: Traceback (most recent call last): File "sage/misc/persist.pyx", line 291, in sage.misc.persist.dumps (build/cythonized/sage/misc/persist.c:4284) return obj.dumps(compress) File "sage/structure/sage_object.pyx", line 476, in sage.structure.sage_object.SageObject.dumps (build/cythonized/sage/structure/sage_object.c:3790) return _base_dumps(self, compress=compress) File "sage/misc/persist.pyx", line 264, in sage.misc.persist._base_dumps (build/cythonized/sage/misc/persist.c:4012) gherkin = SagePickler.dumps(obj) File "sage/misc/persist.pyx", line 771, in sage.misc.persist.SagePickler.dumps (build/cythonized/sage/misc/persist.c:6801) pickler.dump(obj) TypeError: cannot pickle 'MultiCoordFunction' object <BLANKLINE> During handling of the above exception, another exception occurred: <BLANKLINE> Traceback (most recent call last): File "/home/michi/Projekte/sage-devel/local/lib/python3.8/site- packages/sage/misc/sage_unittest.py", line 297, in run test_method(tester=tester) File "sage/structure/sage_object.pyx", line 647, in sage.structure.sage_object.SageObject._test_pickling (build/cythonized/sage/structure/sage_object.c:5007) tester.assertEqual(loads(dumps(self)), self) File "sage/misc/persist.pyx", line 293, in sage.misc.persist.dumps (build/cythonized/sage/misc/persist.c:4337) return _base_dumps(obj, compress=compress) File "sage/misc/persist.pyx", line 264, in sage.misc.persist._base_dumps (build/cythonized/sage/misc/persist.c:4012) gherkin = SagePickler.dumps(obj) File "sage/misc/persist.pyx", line 771, in sage.misc.persist.SagePickler.dumps (build/cythonized/sage/misc/persist.c:6801) pickler.dump(obj) TypeError: cannot pickle 'MultiCoordFunction' object ------------------------------------------------------------ The following tests failed: _test_pickling }}} I found out that a non-cythonized alternative works without errors. URL: https://trac.sagemath.org/31182 Reported by: gh-mjungmath Ticket author(s): Michael Jung Reviewer(s): Travis Scrimshaw
2 parents 7dfb05a + 6cbd1fd commit d6cf85b

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

build/pkgs/configure/checksums.ini

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
tarball=configure-VERSION.tar.gz
2-
sha1=1fd3cc5d2e70fb51853371b2e2c1847d33cb5a78
3-
md5=b7d6186f022fd3a535e3f7b242b0ccd1
4-
cksum=3654751019
2+
sha1=fef34790261a068805f603750635668a09abd0b5
3+
md5=3af901a6c4bcdaf50e1233277375c2e4
4+
cksum=1293784084
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
a4fc17efd8cd7e07f4b63a54db2fe0a60d0d2dc1
1+
b8db1adc405725c00f73645fcda9012d15ab5589

src/sage/structure/mutability.pyx

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,71 @@ cdef class Mutability:
177177
"""
178178
return not self._is_immutable
179179

180+
def __getstate__(self):
181+
r"""
182+
Get the current state of ``self`` including the mutability status.
183+
184+
TESTS::
185+
186+
sage: class A(SageObject, Mutability):
187+
....: def __init__(self, val):
188+
....: self._val = val
189+
....: def change(self, val):
190+
....: self._require_mutable()
191+
....: self._val = val
192+
....: def __hash__(self):
193+
....: self._require_immutable()
194+
....: return hash(self._val)
195+
sage: a = A(4)
196+
sage: a.__dict__
197+
{'_val': 4}
198+
sage: a.__getstate__()
199+
{'_is_immutable': False, '_val': 4}
200+
sage: a.__reduce__() # indirect doctest
201+
(<function _reconstructor at ...>,
202+
(<class '__main__.A'>,
203+
<class 'sage.structure.sage_object.SageObject'>,
204+
<sage.structure.sage_object.SageObject object at ...>),
205+
{'_is_immutable': False, '_val': 4})
206+
207+
"""
208+
state = getattr(self, '__dict__', {})
209+
state['_is_immutable'] = self._is_immutable
210+
return state
211+
212+
def __setstate__(self, state):
213+
r"""
214+
Set the state of ``self`` from the dictionary ``state`` including the
215+
mutability status.
216+
217+
TESTS::
218+
219+
sage: class A(SageObject, Mutability):
220+
....: def __init__(self, val):
221+
....: self._val = val
222+
....: def change(self, val):
223+
....: self._require_mutable()
224+
....: self._val = val
225+
....: def __hash__(self):
226+
....: self._require_immutable()
227+
....: return hash(self._val)
228+
sage: a = A(4)
229+
sage: a.is_immutable()
230+
False
231+
sage: d = a.__getstate__(); d
232+
{'_is_immutable': False, '_val': 4}
233+
sage: d['_is_immutable'] = True
234+
sage: a.__setstate__(d)
235+
sage: a.is_immutable()
236+
True
237+
sage: a.__getstate__()
238+
{'_is_immutable': True, '_val': 4}
239+
240+
"""
241+
if hasattr(self, '__dict__'):
242+
self.__dict__ = state
243+
self._is_immutable = state['_is_immutable']
244+
180245
##########################################################################
181246
## Method decorators for mutating methods resp. methods that assume immutability
182247

0 commit comments

Comments
 (0)