Skip to content

gh-106303: Use _PyObject_LookupAttr() instead of PyObject_GetAttr() #106304

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

Merged
merged 2 commits into from
Jul 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Include/internal/pycore_global_objects_fini_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Include/internal/pycore_global_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(__lshift__)
STRUCT_FOR_ID(__lt__)
STRUCT_FOR_ID(__main__)
STRUCT_FOR_ID(__match_args__)
STRUCT_FOR_ID(__matmul__)
STRUCT_FOR_ID(__missing__)
STRUCT_FOR_ID(__mod__)
Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_runtime_init_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Include/internal/pycore_unicodeobject_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 5 additions & 10 deletions Objects/funcobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -942,17 +942,12 @@ PyTypeObject PyFunction_Type = {
static int
functools_copy_attr(PyObject *wrapper, PyObject *wrapped, PyObject *name)
{
PyObject *value = PyObject_GetAttr(wrapped, name);
if (value == NULL) {
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
PyErr_Clear();
return 0;
}
return -1;
PyObject *value;
int res = _PyObject_LookupAttr(wrapped, name, &value);
if (value != NULL) {
Copy link
Member

Choose a reason for hiding this comment

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

How about adding an assert before reassignment?

assert(res > 0);

Copy link
Member Author

Choose a reason for hiding this comment

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

This was not necessary in many other cases where a similar idiom is used.

res = PyObject_SetAttr(wrapper, name, value);
Py_DECREF(value);
}

int res = PyObject_SetAttr(wrapper, name, value);
Py_DECREF(value);
return res;
}

Expand Down
16 changes: 6 additions & 10 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,8 @@ match_class_attr(PyThreadState *tstate, PyObject *subject, PyObject *type,
}
return NULL;
}
PyObject *attr = PyObject_GetAttr(subject, name);
if (attr == NULL && _PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
_PyErr_Clear(tstate);
}
PyObject *attr;
(void)_PyObject_LookupAttr(subject, name, &attr);
return attr;
}

Expand Down Expand Up @@ -456,7 +454,9 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type,
// First, the positional subpatterns:
if (nargs) {
int match_self = 0;
match_args = PyObject_GetAttrString(type, "__match_args__");
if (_PyObject_LookupAttr(type, &_Py_ID(__match_args__), &match_args) < 0) {
goto fail;
}
if (match_args) {
if (!PyTuple_CheckExact(match_args)) {
const char *e = "%s.__match_args__ must be a tuple (got %s)";
Expand All @@ -466,8 +466,7 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type,
goto fail;
}
}
else if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
_PyErr_Clear(tstate);
else {
// _Py_TPFLAGS_MATCH_SELF is only acknowledged if the type does not
// define __match_args__. This is natural behavior for subclasses:
// it's as if __match_args__ is some "magic" value that is lost as
Expand All @@ -476,9 +475,6 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type,
match_self = PyType_HasFeature((PyTypeObject*)type,
_Py_TPFLAGS_MATCH_SELF);
}
else {
goto fail;
}
assert(PyTuple_CheckExact(match_args));
Py_ssize_t allowed = match_self ? 1 : PyTuple_GET_SIZE(match_args);
if (allowed < nargs) {
Expand Down