-
-
Notifications
You must be signed in to change notification settings - Fork 33.5k
gh-141732: Fix ExceptionGroup repr changing when original exception sequence is mutated
#141736
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
base: main
Are you sure you want to change the base?
Conversation
|
Thanks. We don't make user-visible changes to builtin types without a PEP, so this PR cannot be merged as is. We could document current behaviour (i.e., don't mutate the list) if it's not clear from the docs and then consider if we want to change it. If we do want to change it, maybe it should be to make a shallow copy of the list rather than make it a tuple (so the repr/str won't change and break existing code that relies on current behaviour). |
Thanks for the quick response! That all makes sense. Just to clarify - is c87b66b not a very similar change in this release without a PEP? But maybe I'm missing something :) |
|
If you implement |
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This reverts commit 4801399.
What if we did this only for the funky case where the sequence is not a list or tuple? |
Sounds like a great compromise! Just implemented now. |
|
I can also add some documentation to let users know that |
|
Maybe not go into details, because this is an implementation detail, but could add a comment to the effect that while the exceptions may be any sequence, tuples and lists can be processed more efficiently by the implementation. |
Done. I also noted that tuples are more efficient here than lists (this is because a new list has to be created in the repr if the original sequence was a list). |
Misc/NEWS.d/next/Core_and_Builtins/2025-11-19-16-40-24.gh-issue-141732.PTetqp.rst
Outdated
Show resolved
Hide resolved
|
I would be good to update all the examples in our docs to follow the "best practice" of using tuples. People will get the right thing when they copy-paste. Could you create an issue about the doc change? |
Misc/NEWS.d/next/Core_and_Builtins/2025-11-19-16-40-24.gh-issue-141732.PTetqp.rst
Outdated
Show resolved
Hide resolved
| * So we use the actual exceptions tuple for accuracy, but make it look like the | ||
| * original exception sequence if possible, for backwards compatibility. */ | ||
| if (PyList_Check(PyTuple_GET_ITEM(self->args, 1))) { | ||
| PyObject *exceptions_list = PySequence_List(self->excs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to check the result of PySequence_List even though we've already run a PyList_Check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Because the errors are not only on the type.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
|
|
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
| PyBaseExceptionGroupObject *self = PyBaseExceptionGroupObject_CAST(op); | ||
| assert(self->msg); | ||
|
|
||
| PyObject *exceptions_str = Py_XNewRef(self->excs_str); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead:
PyObject *exception_str = NULL;
if (!self->excs_str) {
exception_str = ...
}
else {
exception_str = Py_NewRef(self->excs_str);
}
assert(exception_str != NULL);
/* format */
Py_DECREF(exception_str);It's not faster, but I think it's clearer to the reader. Up to you to make the change though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't sure so I attempted to clarify with a comment instead. Happy to do something different if that's preferable :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem wasn't the comment but rather the fact that we are using Py_XNewRef and then checking its result instead of first checking whethe Py_NewRef could be called.
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
|
Currently we're using |
| error: | ||
| return NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we only have a return NULL; you could remove the goto and inline evreything.
BaseExceptionGroup.__repr__now overridesBaseException.__repr__, using the group'sexceptiontuple instead of the mutable argument passed in.ComplexExtendsException(a private macro inObjects/exceptions.c) now has a parameter to modify the exception's__repr__and not just its__str__.ExceptionGrouprepr is misleading if original exception sequence is mutated #141732📚 Documentation preview 📚: https://cpython-previews--141736.org.readthedocs.build/