Content-Length: 397664 | pFad | http://github.com/python/cpython/pull/136770/commits/951e0a112e3e8b97e984f0a833537e984bbd2b53

0D gh-74185: repr() of ImportError now contains attributes name and path by Yoav11 · Pull Request #136770 · python/cpython · GitHub
Skip to content

gh-74185: repr() of ImportError now contains attributes name and path #136770

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

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cb764d9
bpo-29999: repr() of ImportError now contains attributes name and path.
serhiy-storchaka Apr 5, 2017
db41c7d
Use GitHub Actions version of Bedevere
arhadthedev Feb 12, 2023
1caeb91
Add the news entry back
arhadthedev Feb 13, 2023
7f29270
Remove an accidentally included untracked file
arhadthedev Feb 13, 2023
c80e056
first commit
ynir3 Jul 19, 2025
126be20
add test_ModuleNotFoundError_repr_with_failed_import
ynir3 Jul 19, 2025
4a97f5c
add test_ModuleNotFoundError_repr_with_failed_import
ynir3 Jul 19, 2025
852da8c
add blurb
ynir3 Jul 19, 2025
6ab7362
add noqa:F401
ynir3 Jul 19, 2025
12c2293
remove whitespace
ynir3 Jul 19, 2025
a53da37
fix trailing-whitespace
ynir3 Jul 19, 2025
5b6d626
use ComplexExtendsException
ynir3 Jul 19, 2025
951e0a1
return to non-macro style
ynir3 Jul 19, 2025
8fbfd18
use modern field initializers
ynir3 Jul 19, 2025
458bcd0
remove un-necessary casts
ynir3 Jul 19, 2025
fa2f884
use PyUnicodeWriter
ynir3 Jul 19, 2025
35a6a29
fix trailing whitespace
ynir3 Jul 19, 2025
6e416c6
reduce nesting
ynir3 Jul 19, 2025
aa75f6a
use PyUnicdodeWriter_Format and if statement braces
ynir3 Jul 19, 2025
8b5e4ed
indentation
ynir3 Jul 19, 2025
28545e5
move decref
ynir3 Jul 19, 2025
4f63193
check baseException_repr failure, add 3.15rst
ynir3 Jul 20, 2025
62a479b
Merge branch 'main' into importerror-repr
Yoav11 Jul 20, 2025
25f3d42
fix chr c input
ynir3 Jul 20, 2025
a45ed75
move tests, edit rst wording
ynir3 Jul 20, 2025
69e7305
Merge branch 'main' into importerror-repr
Yoav11 Jul 20, 2025
9c09cd0
edit blurb
ynir3 Jul 20, 2025
ca0e2a4
edit blurb
ynir3 Jul 20, 2025
b0d7f4a
Merge branch 'main' into importerror-repr
Yoav11 Jul 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
return to non-macro style
  • Loading branch information
ynir3 committed Jul 19, 2025
commit 951e0a112e3e8b97e984f0a833537e984bbd2b53
39 changes: 26 additions & 13 deletions Objects/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -1865,21 +1865,23 @@ ImportError_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
}

static PyObject *
ImportError_repr(PyImportErrorObject *self)
ImportError_repr(PyObject *self)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there other exceptions that will benefit from having keywords in their reprs? AFAICT, the keywords are only rendered if they were passed to the constructor as keyword arguments. In particular, we could make a generic repr helper for that which takes into account them, something like:

static PyObject *
repr_with_keywords(PyObject *exc, const char * const *kwlist)
{
	/* format using kwlist[i]=getattr(exc, kwlist[i]) 
     * with kwlist NULL-terminated */
}

Its usage would be

static char *kwlist[] = {"name", "path", NULL};
repr_with_keywords(exc, kwlist)

Copy link
Member

@picnixz picnixz Jul 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, let's hold off this idea as I don't know if it can be useful. But this can be worth investigating instead of storing the given keywords explicitly.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes - AFAIK only ImportError and ModuleNotFoundError (which hinnerits this functionality as per the tests) have optional arguments ? but makes sense to me that if other exception types in the future have optionals then we could extract this out.

Copy link
Member

@picnixz picnixz Jul 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but let's do it in a follow-up PR so that we can revert the helper commit more easily. Also it depends on whether we would store the keywords passed to the constructor (this is #11580)

{
int hasargs = PyTuple_GET_SIZE(((PyBaseExceptionObject *)self)->args) != 0;
PyObject *r = BaseException_repr((PyObject *)self);
if (r && (self->name || self->path)) {
PyObject *r = BaseException_repr(self);
PyImportErrorObject *exc = PyImportErrorObject_CAST(self);

if (r && (exc->name || exc->path)) {
/* remove ')' */
Py_SETREF(r, PyUnicode_Substring(r, 0, PyUnicode_GET_LENGTH(r) - 1));
if (r && self->name) {
if (r && exc->name) {
Py_SETREF(r, PyUnicode_FromFormat("%U%sname=%R",
r, hasargs ? ", " : "", self->name));
r, hasargs ? ", " : "", exc->name));
hasargs = 1;
}
if (r && self->path) {
if (r && exc->path) {
Py_SETREF(r, PyUnicode_FromFormat("%U%spath=%R",
r, hasargs ? ", " : "", self->path));
r, hasargs ? ", " : "", exc->path));
}
if (r) {
Py_SETREF(r, PyUnicode_FromFormat("%U)", r));
Expand All @@ -1905,12 +1907,23 @@ static PyMethodDef ImportError_methods[] = {
{NULL}
};

ComplexExtendsException(PyExc_Exception, ImportError,
ImportError, 0 /* new */,
ImportError_methods, ImportError_members,
0 /* getset */, ImportError_str,
"Import can't find module, or can't find name in "
"module.");
static PyTypeObject _PyExc_ImportError = {
PyVarObject_HEAD_INIT(NULL, 0)
"ImportError",
sizeof(PyImportErrorObject), 0,
(destructor)ImportError_dealloc, 0, 0, 0, 0,
ImportError_repr, 0, 0, 0, 0, 0,
ImportError_str, 0, 0, 0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
PyDoc_STR("Import can't find module, or can't find name in "
"module."),
(traverseproc)ImportError_traverse,
(inquiry)ImportError_clear, 0, 0, 0, 0, ImportError_methods,
ImportError_members, 0, &_PyExc_Exception,
0, 0, 0, offsetof(PyImportErrorObject, dict),
(initproc)ImportError_init,
};
PyObject *PyExc_ImportError = (PyObject *)&_PyExc_ImportError;

/*
* ModuleNotFoundError extends ImportError
Expand Down
Loading








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/python/cpython/pull/136770/commits/951e0a112e3e8b97e984f0a833537e984bbd2b53

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy