-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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
Exception that calls super().__init__
breaks copy.copy
#125782
Comments
__init__
breaks copy.copy
super().__init__
breaks copy.copy
Your code would have |
no? import copy
class MyException(Exception):
def __init__(self, x):
# no call to super().__init__()
self.x = x
my_exc = MyException(5)
my_copy = copy.copy(my_exc)
assert my_copy.x == 5 and it's not just copying the attributes. If you add a |
Yeah, this looks like a bug. Confirmed it on the main branch. Thank you for the report! |
I suspect this is an issue with |
copy uses the pickle protocol to reduce the object to a state tuple and then create a new object from that state tuple.
Based on https://docs.python.org/3/library/pickle.html#object.__reduce__, this is saying: "call MyException with no arguments, then pass
So I don't think this is copy.copy's fault. BaseException assumes that an exception object can be constructed from its It looks like BaseException accepts args in both Unfortunately it seems some exceptions such as
Even if CPython were to fix all examples of this internally, there's no way to know how much user code might be relying on the fact that copying/unpickling an exception calls |
That's a manifestation of the fact that BaseException saves the args on both |
I'm sorry for my mistake. |
Bug report
Bug description:
For some reason calling
Exception.__init__
breakscopy.copy
s ability to detectargs
. The following codegives
Removing the
super().__init__()
line makes everything work as expected, but given that it's generally seen as good practice to callsuper().__init__()
in child classes, and you may be working with a more complex class structure, this seems like pretty bad behavior.I haven't dug deep enough into
copy.copy
orBaseException.__init__
to decide which one deserves the blame.For the reason why I want to copy exceptions, see python-trio/flake8-async#298
CPython versions tested on:
3.9, 3.10, 3.11, 3.12, 3.13, 3.14
Operating systems tested on:
Linux
The text was updated successfully, but these errors were encountered: