Skip to content

Commit 25fd87a

Browse files
[3.11] pythongh-106303: Use _PyObject_LookupAttr() instead of PyObject_GetAttr() (pythonGH-106304)
It simplifies and speed up the code.. (cherry picked from commit 93d292c) Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 769b7d2 commit 25fd87a

File tree

4 files changed

+13
-20
lines changed

4 files changed

+13
-20
lines changed

Include/internal/pycore_global_strings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ struct _Py_global_strings {
142142
STRUCT_FOR_ID(__lshift__)
143143
STRUCT_FOR_ID(__lt__)
144144
STRUCT_FOR_ID(__main__)
145+
STRUCT_FOR_ID(__match_args__)
145146
STRUCT_FOR_ID(__matmul__)
146147
STRUCT_FOR_ID(__missing__)
147148
STRUCT_FOR_ID(__mod__)

Include/internal/pycore_runtime_init.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,7 @@ extern "C" {
765765
INIT_ID(__lshift__), \
766766
INIT_ID(__lt__), \
767767
INIT_ID(__main__), \
768+
INIT_ID(__match_args__), \
768769
INIT_ID(__matmul__), \
769770
INIT_ID(__missing__), \
770771
INIT_ID(__mod__), \

Objects/funcobject.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -801,17 +801,12 @@ PyTypeObject PyFunction_Type = {
801801
static int
802802
functools_copy_attr(PyObject *wrapper, PyObject *wrapped, PyObject *name)
803803
{
804-
PyObject *value = PyObject_GetAttr(wrapped, name);
805-
if (value == NULL) {
806-
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
807-
PyErr_Clear();
808-
return 0;
809-
}
810-
return -1;
804+
PyObject *value;
805+
int res = _PyObject_LookupAttr(wrapped, name, &value);
806+
if (value != NULL) {
807+
res = PyObject_SetAttr(wrapper, name, value);
808+
Py_DECREF(value);
811809
}
812-
813-
int res = PyObject_SetAttr(wrapper, name, value);
814-
Py_DECREF(value);
815810
return res;
816811
}
817812

Python/ceval.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,10 +1001,8 @@ match_class_attr(PyThreadState *tstate, PyObject *subject, PyObject *type,
10011001
}
10021002
return NULL;
10031003
}
1004-
PyObject *attr = PyObject_GetAttr(subject, name);
1005-
if (attr == NULL && _PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
1006-
_PyErr_Clear(tstate);
1007-
}
1004+
PyObject *attr;
1005+
(void)_PyObject_LookupAttr(subject, name, &attr);
10081006
return attr;
10091007
}
10101008

@@ -1039,7 +1037,9 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type,
10391037
// First, the positional subpatterns:
10401038
if (nargs) {
10411039
int match_self = 0;
1042-
match_args = PyObject_GetAttrString(type, "__match_args__");
1040+
if (_PyObject_LookupAttr(type, &_Py_ID(__match_args__), &match_args) < 0) {
1041+
goto fail;
1042+
}
10431043
if (match_args) {
10441044
if (!PyTuple_CheckExact(match_args)) {
10451045
const char *e = "%s.__match_args__ must be a tuple (got %s)";
@@ -1049,8 +1049,7 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type,
10491049
goto fail;
10501050
}
10511051
}
1052-
else if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
1053-
_PyErr_Clear(tstate);
1052+
else {
10541053
// _Py_TPFLAGS_MATCH_SELF is only acknowledged if the type does not
10551054
// define __match_args__. This is natural behavior for subclasses:
10561055
// it's as if __match_args__ is some "magic" value that is lost as
@@ -1059,9 +1058,6 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type,
10591058
match_self = PyType_HasFeature((PyTypeObject*)type,
10601059
_Py_TPFLAGS_MATCH_SELF);
10611060
}
1062-
else {
1063-
goto fail;
1064-
}
10651061
assert(PyTuple_CheckExact(match_args));
10661062
Py_ssize_t allowed = match_self ? 1 : PyTuple_GET_SIZE(match_args);
10671063
if (allowed < nargs) {

0 commit comments

Comments
 (0)