[Python-checkins] gh-106303: Use _PyObject_LookupAttr() instead of PyObject_GetAttr() (GH-106304)
serhiy-storchaka
webhook-mailer at python.org
Sun Jul 9 08:27:07 EDT 2023
https://github.com/python/cpython/commit/93d292c2b3f8e85ef562c37f59678c639b9b8fcb
commit: 93d292c2b3f8e85ef562c37f59678c639b9b8fcb
branch: main
author: Serhiy Storchaka <storchaka at gmail.com>
committer: serhiy-storchaka <storchaka at gmail.com>
date: 2023-07-09T15:27:03+03:00
summary:
gh-106303: Use _PyObject_LookupAttr() instead of PyObject_GetAttr() (GH-106304)
It simplifies and speed up the code.
files:
M Include/internal/pycore_global_objects_fini_generated.h
M Include/internal/pycore_global_strings.h
M Include/internal/pycore_runtime_init_generated.h
M Include/internal/pycore_unicodeobject_generated.h
M Objects/funcobject.c
M Python/ceval.c
diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h
index f85207b4bde29..6d50ffd0a02f1 100644
--- a/Include/internal/pycore_global_objects_fini_generated.h
+++ b/Include/internal/pycore_global_objects_fini_generated.h
@@ -668,6 +668,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lshift__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lt__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__main__));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__match_args__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__matmul__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__missing__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__mod__));
diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h
index 3c9c12202ba1b..bb1fb13f342fc 100644
--- a/Include/internal/pycore_global_strings.h
+++ b/Include/internal/pycore_global_strings.h
@@ -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__)
diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h
index 9a28368a124ce..2d66647438b19 100644
--- a/Include/internal/pycore_runtime_init_generated.h
+++ b/Include/internal/pycore_runtime_init_generated.h
@@ -663,6 +663,7 @@ extern "C" {
INIT_ID(__lshift__), \
INIT_ID(__lt__), \
INIT_ID(__main__), \
+ INIT_ID(__match_args__), \
INIT_ID(__matmul__), \
INIT_ID(__missing__), \
INIT_ID(__mod__), \
diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h
index 9e13a9491b7da..59f40075f9398 100644
--- a/Include/internal/pycore_unicodeobject_generated.h
+++ b/Include/internal/pycore_unicodeobject_generated.h
@@ -315,6 +315,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
string = &_Py_ID(__main__);
assert(_PyUnicode_CheckConsistency(string, 1));
_PyUnicode_InternInPlace(interp, &string);
+ string = &_Py_ID(__match_args__);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ _PyUnicode_InternInPlace(interp, &string);
string = &_Py_ID(__matmul__);
assert(_PyUnicode_CheckConsistency(string, 1));
_PyUnicode_InternInPlace(interp, &string);
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index f43e3a2787b84..a8a9ee2b9bad4 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -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) {
+ res = PyObject_SetAttr(wrapper, name, value);
+ Py_DECREF(value);
}
-
- int res = PyObject_SetAttr(wrapper, name, value);
- Py_DECREF(value);
return res;
}
diff --git a/Python/ceval.c b/Python/ceval.c
index 1b8650a650412..da1135549a255 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -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;
}
@@ -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)";
@@ -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
@@ -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) {
More information about the Python-checkins
mailing list