New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
REG: sympy 1.9 breaks unpickling for symbols stored with sympy 1.8 #22241
Comments
To be clear what you mean is that a pickle created with sympy 1.8 can not be unpickled with sympy 1.9. Is that correct? |
Yes, exactly. |
I'm not sure how easy this is to fix. There are a few related problems. One is that Symbol uses diff --git a/sympy/core/symbol.py b/sympy/core/symbol.py
index fa43635..be57d45 100644
--- a/sympy/core/symbol.py
+++ b/sympy/core/symbol.py
@@ -201,7 +201,7 @@ class Symbol(AtomicExpr, Boolean):
is_comparable = False
- __slots__ = ('name',)
is_Symbol = True
is_symbol = True Does that fix all the problems for yt? It's probably not the right fix for sympy because it allows arbitrary attribute assignment on symbols which I think is deliberately disallowed. |
Pinging @Xarthisius who has admin rights on the server where we're seeing this error. |
I didn't consider cross-version pickling compatibility when making #21260. It's not clear (to me) what should be expected for portability with pickle. The pickling protocols are quite complicated to implement. It isn't clear to me how Here any pickle made with SymPy 1.8 was pickled using the The original issue #21121 (comment) was I think due to the fact that Maybe it's enough to implement diff --git a/sympy/core/symbol.py b/sympy/core/symbol.py
index fa43635..60783be 100644
--- a/sympy/core/symbol.py
+++ b/sympy/core/symbol.py
@@ -303,6 +303,10 @@ def __new_stage2__(cls, name, **assumptions):
def __getnewargs_ex__(self):
return ((self.name,), self.assumptions0)
+ def __setstate__(self, state):
+ for name, value in state.items():
+ setattr(self, name, value)
+
def _hashable_content(self):
# Note: user-specified assumptions not hashed, just derived ones
return (self.name,) + tuple(sorted(self.assumptions0.items())) I think that maybe means that SymPy 1.9 can unpickle both the old and the new pickles but the new pickles will still use the |
I've opened #22245 which I think fixes this. It makes it possible to unpickle pickles created by either SymPy 1.8 or 1.9. I've also tested that the new pickles created in SymPy 1.9 can be unpickled by SymPy 1.8. If we were to release that fix in 1.9.1 then with the exception of 1.9 the pickles from all versions of SymPy would be compatible with each other. Note that old pickles would still be subject to the bug in #21260 I've only tested this in simple cases so it would be good if someone could check that this actually fixes the problem for yt. |
Unfortunately we will not be able to test your patch thoroughly any time soon, but I believe your simple cases testing should be sufficient. I'm hoping it can be considered for a bug fix release |
I think it can be considered for a bugfix release. I was expecting more bug reports but so far this is the only reported regression for 1.9. |
Excellent, thanks for your transparency and responsiveness. I appreciate it. |
I haven't seen any other regression reports so I'm preparing a release to fix this. I'm not sure when I will find time to actually put it out though. |
Great, no rush on our side. Thank you ! |
The 4.0.2 release of Yt disables sympy-1.9 because of this issue, which makes Yt unbuildable on systems with sympy-1.9 Any chance to resolve this? |
This is an unfortunate side effect that we didn't anticipate on the yt side, I'm sorry about that ! If there's a way we can resolve this from the yt side that we haven't thought of I'll be happy to help with it. |
A SymPy 1.10 release is imminent. |
@yurivict we ended up patching this limitation away in the conda-forge version of yt 4.0.2, you could just do the same thing for FreeBSD. For full context the issue we had with sympy 1.9 was specifically encountered in the context of our CI, where previously validated results were stored as pickle files. Yt users were not actually affected. |
I think that another similar problem slipped in sympy
|
I think the fix is the same as before it's just that apparently it should be added to Basic rather than Symbol: diff --git a/sympy/core/basic.py b/sympy/core/basic.py
index fc6b6fe..f156959 100644
--- a/sympy/core/basic.py
+++ b/sympy/core/basic.py
@@ -132,6 +132,10 @@ def copy(self):
def __getnewargs__(self):
return self.args
+ def __setstate__(self, state):
+ for name, value in state.items():
+ setattr(self, name, value)
+
def __getstate__(self):
return None
I would like to know if that can be tested to see that it does make everything work in yt though. In the case of Symbol there is an attribute import pickle
import sympy as sp
from sympy import S
from packaging.version import Version
SP_VERSION = Version(sp.__version__)
PFILE = "/tmp/x.pickle"
if SP_VERSION < Version("1.9"):
with open(PFILE, "wb") as fh:
pickle.dump(S(2), fh)
with open(PFILE, "rb") as fh:
x_ = pickle.load(fh) |
Thank you for your promptly response. I can't speak for the team but right now I'm not sure anyone with the necessary admin permissions has time to try it extensively. import pickle
from unyt import unyt_array
import sympy as sp
from sympy import S
from packaging.version import Version
SP_VERSION = Version(sp.__version__)
PFILE = "/tmp/x.pickle"
if SP_VERSION < Version("1.9"):
with open(PFILE, "wb") as fh:
pickle.dump(unyt_array([1, 2], "cm"), fh)
with open(PFILE, "rb") as fh:
x_ = pickle.load(fh) Also, I can confirm that your proposed patch fixes it ! |
I opened a PR against master which seems to pass the existing tests. If another reason arises to make 1.10.1 release then I'll put that in. Otherwise I want unyt to test this because my previous attempt wasn't fully tested and now turns out not to have fixed everything. |
The PR: #23217 |
Thanks a lot. I'll propose a test in unyt itself, which should be run against the dev version of sympy to alleviate your maintenance burden. |
I also confirm that #23217 fixes my test |
I've just released SymPy 1.10.1. Can you confirm if that resolves this issue? |
All good ! I've checked that both unyt and yt CI were compatible. Thank you so much, I'll close ! |
Thanks for testing! |
The new version of sympy breaks yt's CI (https://tests.yt-project.org/job/yt_py38_latest_deps/386/)
Here's a minimal example to reproduce the issue we're facing.
I first ran this script using sympy 1.8, then upgraded to 1.9 and ran it again
output:
I see in sympy 1.9's release notes that there have been some changes related to pickling, however I see no mention of this kind of breaking change so I'm assuming that it wasn't intended. I'll try to bisect to the exact commit/PR that broke this.
The text was updated successfully, but these errors were encountered: