aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Modules/_abc.c
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2022-02-08 13:39:07 -0700
committerGitHub <noreply@github.com>2022-02-08 13:39:07 -0700
commit81c72044a181dbbfbf689d7a977d0d99090f26a8 (patch)
tree14329746bd6f179cf2ae7c9818e1ae881eb46360 /Modules/_abc.c
parentc018d3037b5b62e6d48d5985d1a37b91762fbffb (diff)
downloadcpython-81c72044a181dbbfbf689d7a977d0d99090f26a8.tar.gz
cpython-81c72044a181dbbfbf689d7a977d0d99090f26a8.zip
bpo-46541: Replace core use of _Py_IDENTIFIER() with statically initialized global objects. (gh-30928)
We're no longer using _Py_IDENTIFIER() (or _Py_static_string()) in any core CPython code. It is still used in a number of non-builtin stdlib modules. The replacement is: PyUnicodeObject (not pointer) fields under _PyRuntimeState, statically initialized as part of _PyRuntime. A new _Py_GET_GLOBAL_IDENTIFIER() macro facilitates lookup of the fields (along with _Py_GET_GLOBAL_STRING() for non-identifier strings). https://bugs.python.org/issue46541#msg411799 explains the rationale for this change. The core of the change is in: * (new) Include/internal/pycore_global_strings.h - the declarations for the global strings, along with the macros * Include/internal/pycore_runtime_init.h - added the static initializers for the global strings * Include/internal/pycore_global_objects.h - where the struct in pycore_global_strings.h is hooked into _PyRuntimeState * Tools/scripts/generate_global_objects.py - added generation of the global string declarations and static initializers I've also added a --check flag to generate_global_objects.py (along with make check-global-objects) to check for unused global strings. That check is added to the PR CI config. The remainder of this change updates the core code to use _Py_GET_GLOBAL_IDENTIFIER() instead of _Py_IDENTIFIER() and the related _Py*Id functions (likewise for _Py_GET_GLOBAL_STRING() instead of _Py_static_string()). This includes adding a few functions where there wasn't already an alternative to _Py*Id(), replacing the _Py_Identifier * parameter with PyObject *. The following are not changed (yet): * stop using _Py_IDENTIFIER() in the stdlib modules * (maybe) get rid of _Py_IDENTIFIER(), etc. entirely -- this may not be doable as at least one package on PyPI using this (private) API * (maybe) intern the strings during runtime init https://bugs.python.org/issue46541
Diffstat (limited to 'Modules/_abc.c')
-rw-r--r--Modules/_abc.c49
1 files changed, 21 insertions, 28 deletions
diff --git a/Modules/_abc.c b/Modules/_abc.c
index a0439618120..641d6198d1f 100644
--- a/Modules/_abc.c
+++ b/Modules/_abc.c
@@ -4,8 +4,9 @@
#endif
#include "Python.h"
-#include "pycore_object.h" // _PyType_GetSubclasses()
#include "pycore_moduleobject.h" // _PyModule_GetState()
+#include "pycore_object.h" // _PyType_GetSubclasses()
+#include "pycore_runtime.h" // _Py_ID()
#include "clinic/_abc.c.h"
/*[clinic input]
@@ -16,15 +17,6 @@ module _abc
PyDoc_STRVAR(_abc__doc__,
"Module contains faster C implementation of abc.ABCMeta");
-_Py_IDENTIFIER(__abstractmethods__);
-_Py_IDENTIFIER(__class__);
-_Py_IDENTIFIER(__dict__);
-_Py_IDENTIFIER(__abc_tpflags__);
-_Py_IDENTIFIER(__bases__);
-_Py_IDENTIFIER(_abc_impl);
-_Py_IDENTIFIER(__subclasscheck__);
-_Py_IDENTIFIER(__subclasshook__);
-
typedef struct {
PyTypeObject *_abc_data_type;
unsigned long long abc_invalidation_counter;
@@ -122,7 +114,7 @@ static _abc_data *
_get_impl(PyObject *module, PyObject *self)
{
_abcmodule_state *state = get_abc_state(module);
- PyObject *impl = _PyObject_GetAttrId(self, &PyId__abc_impl);
+ PyObject *impl = PyObject_GetAttr(self, &_Py_ID(_abc_impl));
if (impl == NULL) {
return NULL;
}
@@ -311,7 +303,7 @@ compute_abstract_methods(PyObject *self)
PyObject *ns = NULL, *items = NULL, *bases = NULL; // Py_XDECREF()ed on error.
/* Stage 1: direct abstract methods. */
- ns = _PyObject_GetAttrId(self, &PyId___dict__);
+ ns = PyObject_GetAttr(self, &_Py_ID(__dict__));
if (!ns) {
goto error;
}
@@ -355,7 +347,7 @@ compute_abstract_methods(PyObject *self)
}
/* Stage 2: inherited abstract methods. */
- bases = _PyObject_GetAttrId(self, &PyId___bases__);
+ bases = PyObject_GetAttr(self, &_Py_ID(__bases__));
if (!bases) {
goto error;
}
@@ -368,8 +360,8 @@ compute_abstract_methods(PyObject *self)
PyObject *item = PyTuple_GET_ITEM(bases, pos); // borrowed
PyObject *base_abstracts, *iter;
- if (_PyObject_LookupAttrId(item, &PyId___abstractmethods__,
- &base_abstracts) < 0) {
+ if (_PyObject_LookupAttr(item, &_Py_ID(__abstractmethods__),
+ &base_abstracts) < 0) {
goto error;
}
if (base_abstracts == NULL) {
@@ -409,7 +401,7 @@ compute_abstract_methods(PyObject *self)
}
}
- if (_PyObject_SetAttrId(self, &PyId___abstractmethods__, abstracts) < 0) {
+ if (PyObject_SetAttr(self, &_Py_ID(__abstractmethods__), abstracts) < 0) {
goto error;
}
@@ -448,7 +440,7 @@ _abc__abc_init(PyObject *module, PyObject *self)
if (data == NULL) {
return NULL;
}
- if (_PyObject_SetAttrId(self, &PyId__abc_impl, data) < 0) {
+ if (PyObject_SetAttr(self, &_Py_ID(_abc_impl), data) < 0) {
Py_DECREF(data);
return NULL;
}
@@ -459,7 +451,8 @@ _abc__abc_init(PyObject *module, PyObject *self)
* their special status w.r.t. pattern matching. */
if (PyType_Check(self)) {
PyTypeObject *cls = (PyTypeObject *)self;
- PyObject *flags = _PyDict_GetItemIdWithError(cls->tp_dict, &PyId___abc_tpflags__);
+ PyObject *flags = PyDict_GetItemWithError(cls->tp_dict,
+ &_Py_ID(__abc_tpflags__));
if (flags == NULL) {
if (PyErr_Occurred()) {
return NULL;
@@ -477,7 +470,7 @@ _abc__abc_init(PyObject *module, PyObject *self)
}
((PyTypeObject *)self)->tp_flags |= (val & COLLECTION_FLAGS);
}
- if (_PyDict_DelItemId(cls->tp_dict, &PyId___abc_tpflags__) < 0) {
+ if (PyDict_DelItem(cls->tp_dict, &_Py_ID(__abc_tpflags__)) < 0) {
return NULL;
}
}
@@ -593,7 +586,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
return NULL;
}
- subclass = _PyObject_GetAttrId(instance, &PyId___class__);
+ subclass = PyObject_GetAttr(instance, &_Py_ID(__class__));
if (subclass == NULL) {
Py_DECREF(impl);
return NULL;
@@ -622,12 +615,12 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
}
}
/* Fall back to the subclass check. */
- result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
- subclass);
+ result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
+ subclass);
goto end;
}
- result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
- subclass);
+ result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
+ subclass);
if (result == NULL) {
goto end;
}
@@ -639,8 +632,8 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
break;
case 0:
Py_DECREF(result);
- result = _PyObject_CallMethodIdOneArg(self, &PyId___subclasscheck__,
- subtype);
+ result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
+ subtype);
break;
case 1: // Nothing to do.
break;
@@ -723,8 +716,8 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
}
/* 3. Check the subclass hook. */
- ok = _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId___subclasshook__,
- subclass);
+ ok = PyObject_CallMethodOneArg(
+ (PyObject *)self, &_Py_ID(__subclasshook__), subclass);
if (ok == NULL) {
goto end;
}