Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
bpo-38530: Offer suggestions on AttributeError#16856
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
c9c85b561d510bdbd88f0a3dd16ac76030371e876645061e4File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -62,6 +62,12 @@ typedef struct { | ||
| PyObject *value; | ||
| } PyStopIterationObject; | ||
| typedef struct { | ||
| PyException_HEAD | ||
| PyObject *obj; | ||
| PyObject *name; | ||
| } PyAttributeErrorObject; | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://www.python.org/dev/peps/pep-0473/ was rejected because it was too broad, but this PR adds a single exception, which sounds ok according to the resolution: https://mail.python.org/pipermail/python-dev/2019-March/156692.html My main worry is the risk of creating "more" and "worse" exception cycles, but Pablo says that it sounds unlikely: https://bugs.python.org/issue38530#msg354975 | ||
| /* Compatibility typedefs */ | ||
| typedef PyOSErrorObject PyEnvironmentErrorObject; | ||
| #ifdef MS_WINDOWS | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| When printing :exc:`AttributeError`, :c:func:`PyErr_Display` will offer | ||
| suggestions of simmilar attribute names in the object that the exception was | ||
| raised from. Patch by Pablo Galindo |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1338,9 +1338,76 @@ SimpleExtendsException(PyExc_NameError, UnboundLocalError, | ||
| /* | ||
| * AttributeError extends Exception | ||
| */ | ||
| SimpleExtendsException(PyExc_Exception, AttributeError, | ||
| "Attribute not found."); | ||
| static int | ||
| AttributeError_init(PyAttributeErrorObject *self, PyObject *args, PyObject *kwds) | ||
| { | ||
| static char *kwlist[] = {"name", "obj", NULL}; | ||
| PyObject *name = NULL; | ||
| PyObject *obj = NULL; | ||
| if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) { | ||
| return -1; | ||
| } | ||
| PyObject *empty_tuple = PyTuple_New(0); | ||
| if (!empty_tuple) { | ||
| return -1; | ||
| } | ||
| if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:AttributeError", kwlist, | ||
| &name, &obj)) { | ||
pablogsal marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| Py_DECREF(empty_tuple); | ||
| return -1; | ||
| } | ||
| Py_DECREF(empty_tuple); | ||
| Py_XINCREF(name); | ||
| Py_XSETREF(self->name, name); | ||
| Py_XINCREF(obj); | ||
| Py_XSETREF(self->obj, obj); | ||
| return 0; | ||
| } | ||
| static int | ||
| AttributeError_clear(PyAttributeErrorObject *self) | ||
| { | ||
| Py_CLEAR(self->obj); | ||
| Py_CLEAR(self->name); | ||
| return BaseException_clear((PyBaseExceptionObject *)self); | ||
| } | ||
| static void | ||
| AttributeError_dealloc(PyAttributeErrorObject *self) | ||
| { | ||
| _PyObject_GC_UNTRACK(self); | ||
| AttributeError_clear(self); | ||
| Py_TYPE(self)->tp_free((PyObject *)self); | ||
| } | ||
| static int | ||
| AttributeError_traverse(PyAttributeErrorObject *self, visitproc visit, void *arg) | ||
| { | ||
| Py_VISIT(self->obj); | ||
| Py_VISIT(self->name); | ||
| return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); | ||
| } | ||
| static PyMemberDef AttributeError_members[] = { | ||
| {"name", T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")}, | ||
| {"obj", T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")}, | ||
| {NULL} /* Sentinel */ | ||
| }; | ||
| static PyMethodDef AttributeError_methods[] = { | ||
| {NULL} /* Sentinel */ | ||
| }; | ||
| ComplexExtendsException(PyExc_Exception, AttributeError, | ||
| AttributeError, 0, | ||
| AttributeError_methods, AttributeError_members, | ||
| 0, BaseException_str, "Attribute not found."); | ||
| /* | ||
| * SyntaxError extends Exception | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.