-
Notifications
You must be signed in to change notification settings - Fork 38
Deserialize by using __new__ (rebased 73) #82
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
Conversation
The doctests weren't being run and had bitrotted. Make them work again.
This fixes `CoverageWarning: Couldn't parse Python file '.../tests/badsyntax.py' (couldnt-parse)`. Based on a change by Oldřich Jedlička.
Using of the class constructor and passing it the args values is not always correct, the custom parameters could be different to the args actually recorded by the built-in Exception class. Try to use the __new__ to create class instance and initialize the args attribute afterwards to prevent calling constructor with wrong arguments. Other instance attributes are initialized in a standard way by pickle module, so this way the reconstruction of the exception is complete. Subclasses of OSError are known exceptions to this, because they initialize read-only attributes from the constructor argument values, so usage of the __new__ factory method leads to lost values of those read-only attributes. Fixes: #65 Signed-off-by: Oldřich Jedlička <[email protected]>
Signed-off-by: Oldřich Jedlička <[email protected]>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #82 +/- ##
==========================================
+ Coverage 89.45% 96.80% +7.35%
==========================================
Files 4 9 +5
Lines 275 564 +289
Branches 46 46
==========================================
+ Hits 246 546 +300
+ Misses 18 14 -4
+ Partials 11 4 -7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
I finally got to test this and the result is different from my patch. Compare the original exception (shortened): deserialized with your fix: and deserialized with my version of the fix: |
|
According to the source code it is important what is being set: https://github.com/python/cpython/blob/main/Objects/exceptions.c#L2286 |
|
Huh, what version of python is that? |
|
It is 3.11.9. The difference is in the def test_oserror():
try:
raise OSError(2, 'err', 3, None, 5)
except Exception as e:
exc = e
str_output = str(exc)
tblib.pickling_support.install(exc)
exc = pickle.loads(pickle.dumps(exc))
assert isinstance(exc, OSError)
assert exc.errno == 2
assert exc.strerror == 'err'
assert exc.filename == 3
assert exc.filename2 == 5
assert exc.__traceback__ is not None
assert str_output == str(exc)
def test_real_oserror():
try:
import os
os.open('non-existing-file', os.O_RDONLY)
exc = None
except Exception as e:
exc = e
str_output = str(exc)
tblib.pickling_support.install(exc)
exc = pickle.loads(pickle.dumps(exc))
assert isinstance(exc, OSError)
assert exc.errno == 2
assert str_output == str(exc) |
|
I am on Windows. The issue is that the Py_None and NULL are two different values, so setting the attribute values to None does not respect the original NULL value. |
Closes #73. Closes #65.