mirror of
https://github.com/python/cpython.git
synced 2025-09-03 15:31:08 +00:00
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
This commit is contained in:
parent
c018d3037b
commit
81c72044a1
108 changed files with 2282 additions and 1573 deletions
106
Python/compile.c
106
Python/compile.c
|
@ -632,11 +632,9 @@ compiler_unit_free(struct compiler_unit *u)
|
|||
static int
|
||||
compiler_set_qualname(struct compiler *c)
|
||||
{
|
||||
_Py_static_string(dot, ".");
|
||||
_Py_static_string(dot_locals, ".<locals>");
|
||||
Py_ssize_t stack_size;
|
||||
struct compiler_unit *u = c->u;
|
||||
PyObject *name, *base, *dot_str, *dot_locals_str;
|
||||
PyObject *name, *base;
|
||||
|
||||
base = NULL;
|
||||
stack_size = PyList_GET_SIZE(c->c_stack);
|
||||
|
@ -667,11 +665,10 @@ compiler_set_qualname(struct compiler *c)
|
|||
if (!force_global) {
|
||||
if (parent->u_scope_type == COMPILER_SCOPE_FUNCTION
|
||||
|| parent->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION
|
||||
|| parent->u_scope_type == COMPILER_SCOPE_LAMBDA) {
|
||||
dot_locals_str = _PyUnicode_FromId(&dot_locals);
|
||||
if (dot_locals_str == NULL)
|
||||
return 0;
|
||||
base = PyUnicode_Concat(parent->u_qualname, dot_locals_str);
|
||||
|| parent->u_scope_type == COMPILER_SCOPE_LAMBDA)
|
||||
{
|
||||
base = PyUnicode_Concat(parent->u_qualname,
|
||||
&_Py_STR(dot_locals));
|
||||
if (base == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
@ -683,12 +680,7 @@ compiler_set_qualname(struct compiler *c)
|
|||
}
|
||||
|
||||
if (base != NULL) {
|
||||
dot_str = _PyUnicode_FromId(&dot);
|
||||
if (dot_str == NULL) {
|
||||
Py_DECREF(base);
|
||||
return 0;
|
||||
}
|
||||
name = PyUnicode_Concat(base, dot_str);
|
||||
name = PyUnicode_Concat(base, &_Py_STR(dot));
|
||||
Py_DECREF(base);
|
||||
if (name == NULL)
|
||||
return 0;
|
||||
|
@ -1603,17 +1595,11 @@ compiler_enter_scope(struct compiler *c, identifier name,
|
|||
}
|
||||
if (u->u_ste->ste_needs_class_closure) {
|
||||
/* Cook up an implicit __class__ cell. */
|
||||
_Py_IDENTIFIER(__class__);
|
||||
PyObject *name;
|
||||
int res;
|
||||
assert(u->u_scope_type == COMPILER_SCOPE_CLASS);
|
||||
assert(PyDict_GET_SIZE(u->u_cellvars) == 0);
|
||||
name = _PyUnicode_FromId(&PyId___class__);
|
||||
if (!name) {
|
||||
compiler_unit_free(u);
|
||||
return 0;
|
||||
}
|
||||
res = PyDict_SetItem(u->u_cellvars, name, _PyLong_GetZero());
|
||||
res = PyDict_SetItem(u->u_cellvars, &_Py_ID(__class__),
|
||||
_PyLong_GetZero());
|
||||
if (res < 0) {
|
||||
compiler_unit_free(u);
|
||||
return 0;
|
||||
|
@ -1998,11 +1984,6 @@ compiler_body(struct compiler *c, asdl_stmt_seq *stmts)
|
|||
int i = 0;
|
||||
stmt_ty st;
|
||||
PyObject *docstring;
|
||||
_Py_IDENTIFIER(__doc__);
|
||||
PyObject *__doc__ = _PyUnicode_FromId(&PyId___doc__); /* borrowed ref*/
|
||||
if (__doc__ == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set current line number to the line number of first statement.
|
||||
This way line number for SETUP_ANNOTATIONS will always
|
||||
|
@ -2027,7 +2008,7 @@ compiler_body(struct compiler *c, asdl_stmt_seq *stmts)
|
|||
assert(st->kind == Expr_kind);
|
||||
VISIT(c, expr, st->v.Expr.value);
|
||||
UNSET_LOC(c);
|
||||
if (!compiler_nameop(c, __doc__, Store))
|
||||
if (!compiler_nameop(c, &_Py_ID(__doc__), Store))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -2041,12 +2022,8 @@ compiler_mod(struct compiler *c, mod_ty mod)
|
|||
{
|
||||
PyCodeObject *co;
|
||||
int addNone = 1;
|
||||
_Py_static_string(PyId__module, "<module>");
|
||||
PyObject *module = _PyUnicode_FromId(&PyId__module); /* borrowed ref */
|
||||
if (module == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (!compiler_enter_scope(c, module, COMPILER_SCOPE_MODULE, mod, 1)) {
|
||||
if (!compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE,
|
||||
mod, 1)) {
|
||||
return NULL;
|
||||
}
|
||||
c->u->u_lineno = 1;
|
||||
|
@ -2324,7 +2301,6 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
|
|||
|
||||
Return 0 on error, -1 if no annotations pushed, 1 if a annotations is pushed.
|
||||
*/
|
||||
_Py_IDENTIFIER(return);
|
||||
Py_ssize_t annotations_len = 0;
|
||||
|
||||
if (!compiler_visit_argannotations(c, args->args, &annotations_len))
|
||||
|
@ -2342,11 +2318,8 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
|
|||
args->kwarg->annotation, &annotations_len))
|
||||
return 0;
|
||||
|
||||
identifier return_str = _PyUnicode_FromId(&PyId_return); /* borrowed ref */
|
||||
if (return_str == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (!compiler_visit_argannotation(c, return_str, returns, &annotations_len)) {
|
||||
if (!compiler_visit_argannotation(c, &_Py_ID(return), returns,
|
||||
&annotations_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2891,7 +2864,6 @@ compiler_lambda(struct compiler *c, expr_ty e)
|
|||
{
|
||||
PyCodeObject *co;
|
||||
PyObject *qualname;
|
||||
identifier name;
|
||||
Py_ssize_t funcflags;
|
||||
arguments_ty args = e->v.Lambda.args;
|
||||
assert(e->kind == Lambda_kind);
|
||||
|
@ -2899,18 +2871,12 @@ compiler_lambda(struct compiler *c, expr_ty e)
|
|||
if (!compiler_check_debug_args(c, args))
|
||||
return 0;
|
||||
|
||||
_Py_static_string(PyId_lambda, "<lambda>");
|
||||
name = _PyUnicode_FromId(&PyId_lambda); /* borrowed ref */
|
||||
if (name == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
funcflags = compiler_default_arguments(c, args);
|
||||
if (funcflags == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!compiler_enter_scope(c, name, COMPILER_SCOPE_LAMBDA,
|
||||
if (!compiler_enter_scope(c, &_Py_STR(anon_lambda), COMPILER_SCOPE_LAMBDA,
|
||||
(void *)e, e->lineno)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -3809,12 +3775,6 @@ compiler_from_import(struct compiler *c, stmt_ty s)
|
|||
{
|
||||
Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names);
|
||||
PyObject *names;
|
||||
_Py_static_string(PyId_empty_string, "");
|
||||
PyObject *empty_string = _PyUnicode_FromId(&PyId_empty_string); /* borrowed ref */
|
||||
|
||||
if (empty_string == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ADDOP_LOAD_CONST_NEW(c, PyLong_FromLong(s->v.ImportFrom.level));
|
||||
|
||||
|
@ -3841,7 +3801,7 @@ compiler_from_import(struct compiler *c, stmt_ty s)
|
|||
ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names);
|
||||
}
|
||||
else {
|
||||
ADDOP_NAME(c, IMPORT_NAME, empty_string, names);
|
||||
ADDOP_NAME(c, IMPORT_NAME, &_Py_STR(empty), names);
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
|
||||
|
@ -5389,13 +5349,8 @@ error:
|
|||
static int
|
||||
compiler_genexp(struct compiler *c, expr_ty e)
|
||||
{
|
||||
_Py_static_string(PyId_genexpr, "<genexpr>");
|
||||
identifier name = _PyUnicode_FromId(&PyId_genexpr); /* borrowed ref */
|
||||
if (name == NULL) {
|
||||
return 0;
|
||||
}
|
||||
assert(e->kind == GeneratorExp_kind);
|
||||
return compiler_comprehension(c, e, COMP_GENEXP, name,
|
||||
return compiler_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr),
|
||||
e->v.GeneratorExp.generators,
|
||||
e->v.GeneratorExp.elt, NULL);
|
||||
}
|
||||
|
@ -5403,13 +5358,8 @@ compiler_genexp(struct compiler *c, expr_ty e)
|
|||
static int
|
||||
compiler_listcomp(struct compiler *c, expr_ty e)
|
||||
{
|
||||
_Py_static_string(PyId_listcomp, "<listcomp>");
|
||||
identifier name = _PyUnicode_FromId(&PyId_listcomp); /* borrowed ref */
|
||||
if (name == NULL) {
|
||||
return 0;
|
||||
}
|
||||
assert(e->kind == ListComp_kind);
|
||||
return compiler_comprehension(c, e, COMP_LISTCOMP, name,
|
||||
return compiler_comprehension(c, e, COMP_LISTCOMP, &_Py_STR(anon_listcomp),
|
||||
e->v.ListComp.generators,
|
||||
e->v.ListComp.elt, NULL);
|
||||
}
|
||||
|
@ -5417,13 +5367,8 @@ compiler_listcomp(struct compiler *c, expr_ty e)
|
|||
static int
|
||||
compiler_setcomp(struct compiler *c, expr_ty e)
|
||||
{
|
||||
_Py_static_string(PyId_setcomp, "<setcomp>");
|
||||
identifier name = _PyUnicode_FromId(&PyId_setcomp); /* borrowed ref */
|
||||
if (name == NULL) {
|
||||
return 0;
|
||||
}
|
||||
assert(e->kind == SetComp_kind);
|
||||
return compiler_comprehension(c, e, COMP_SETCOMP, name,
|
||||
return compiler_comprehension(c, e, COMP_SETCOMP, &_Py_STR(anon_setcomp),
|
||||
e->v.SetComp.generators,
|
||||
e->v.SetComp.elt, NULL);
|
||||
}
|
||||
|
@ -5432,13 +5377,8 @@ compiler_setcomp(struct compiler *c, expr_ty e)
|
|||
static int
|
||||
compiler_dictcomp(struct compiler *c, expr_ty e)
|
||||
{
|
||||
_Py_static_string(PyId_dictcomp, "<dictcomp>");
|
||||
identifier name = _PyUnicode_FromId(&PyId_dictcomp); /* borrowed ref */
|
||||
if (name == NULL) {
|
||||
return 0;
|
||||
}
|
||||
assert(e->kind == DictComp_kind);
|
||||
return compiler_comprehension(c, e, COMP_DICTCOMP, name,
|
||||
return compiler_comprehension(c, e, COMP_DICTCOMP, &_Py_STR(anon_dictcomp),
|
||||
e->v.DictComp.generators,
|
||||
e->v.DictComp.key, e->v.DictComp.value);
|
||||
}
|
||||
|
@ -5960,12 +5900,6 @@ compiler_annassign(struct compiler *c, stmt_ty s)
|
|||
{
|
||||
expr_ty targ = s->v.AnnAssign.target;
|
||||
PyObject* mangled;
|
||||
_Py_IDENTIFIER(__annotations__);
|
||||
/* borrowed ref*/
|
||||
PyObject *__annotations__ = _PyUnicode_FromId(&PyId___annotations__);
|
||||
if (__annotations__ == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(s->kind == AnnAssign_kind);
|
||||
|
||||
|
@ -5988,7 +5922,7 @@ compiler_annassign(struct compiler *c, stmt_ty s)
|
|||
else {
|
||||
VISIT(c, expr, s->v.AnnAssign.annotation);
|
||||
}
|
||||
ADDOP_NAME(c, LOAD_NAME, __annotations__, names);
|
||||
ADDOP_NAME(c, LOAD_NAME, &_Py_ID(__annotations__), names);
|
||||
mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id);
|
||||
ADDOP_LOAD_CONST_NEW(c, mangled);
|
||||
ADDOP(c, STORE_SUBSCR);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue