Skip to content

gh-120029: refactor symtable.c (remove deprecated macros and update some values) #120218

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

Closed
wants to merge 3 commits into from
Closed
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
57 changes: 32 additions & 25 deletions Include/internal/pycore_symtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,37 +134,44 @@ extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);

/* Flags for def-use information */

#define DEF_GLOBAL 1 /* global stmt */
#define DEF_LOCAL 2 /* assignment in code block */
#define DEF_PARAM (2<<1) /* formal parameter */
#define DEF_NONLOCAL (2<<2) /* nonlocal stmt */
#define USE (2<<3) /* name is used */
#define DEF_FREE (2<<4) /* name used but not defined in nested block */
#define DEF_FREE_CLASS (2<<5) /* free variable from class's method */
#define DEF_IMPORT (2<<6) /* assignment occurred via import */
#define DEF_ANNOT (2<<7) /* this name is annotated */
#define DEF_COMP_ITER (2<<8) /* this name is a comprehension iteration variable */
#define DEF_TYPE_PARAM (2<<9) /* this name is a type parameter */
#define DEF_COMP_CELL (2<<10) /* this name is a cell in an inlined comprehension */

#define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT)

/* GLOBAL_EXPLICIT and GLOBAL_IMPLICIT are used internally by the symbol
table. GLOBAL is returned from PyST_GetScope() for either of them.
It is stored in ste_symbols at bits 13-16.
*/
#define SCOPE_OFFSET 12
#define SCOPE_MASK (DEF_GLOBAL | DEF_LOCAL | DEF_PARAM | DEF_NONLOCAL)

#define USE (1 << 0) /* this name is used */
#define DEF_ANNOT (1 << 1) /* this name is annotated */

#define DEF_IMPORT (1 << 2) /* assignment by an 'import' statement */
#define DEF_GLOBAL (1 << 3) /* (re-)declaration by a 'global' statement */
#define DEF_NONLOCAL (1 << 4) /* (re-)declaration by a 'nonlocal' statement */
#define DEF_LOCAL (1 << 5) /* assignment in a code block */

#define DEF_PARAM (1 << 6) /* this name is a formal parameter */
#define DEF_TYPE_PARAM (1 << 7) /* this name is a formal type parameter */

#define DEF_FREE_CLASS (1 << 8) /* this name is a free from a method perspective */
#define DEF_COMP_ITER (1 << 9) /* this name is a comprehension iteration variable */
#define DEF_COMP_CELL (1 << 10) /* this name is a cell in an inlined comprehension */

#define DEF_BOUND (DEF_IMPORT | DEF_LOCAL | DEF_PARAM)

// The scope is stored in "ste_symbols" at bits 11, 12 and 13 (bits indexed
// from 0, from right to left), namely:
//
// ste_symbols = (SCOPE << SCOPE_OFFSET) | DEF_OR_USE_FLAGS
//
// Whenever a 'def-use' flag (resp., a 'scope' value) is added or removed,
// the SCOPE_OFFSET (resp., SCOPE_MASK) value must be changed accordingly.
#define SCOPE_OFFSET 11 /* 1 + highest bit for a DEF_* flag */
#define SCOPE_MASK 0b111 /* 3 bits for storing the scope */

// Scopes for a symbol.
//
// GLOBAL_EXPLICIT and GLOBAL_IMPLICIT are used internally by the symbol
// table. For symbols with such scopes, the ``symtable.Symbol.is_global``
// method returns True.
#define LOCAL 1
#define GLOBAL_EXPLICIT 2
#define GLOBAL_IMPLICIT 3
#define FREE 4
#define CELL 5

#define GENERATOR 1
#define GENERATOR_EXPRESSION 2

// Used by symtablemodule.c
extern struct symtable* _Py_SymtableStringObjectFlags(
const char *str,
Expand Down
3 changes: 2 additions & 1 deletion Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ def _write_atomic(path, data, mode=0o666):
# Python 3.13a6 3570 (Add __firstlineno__ class attribute)
# Python 3.14a1 3600 (Add LOAD_COMMON_CONSTANT)
# Python 3.14a1 3601 (Fix miscompilation of private names in generic classes)
# Python 3.14a1 3602 (Update the DEF_* flags values and the SCOPE_OFFSET)

# Python 3.15 will start with 3700

Expand All @@ -490,7 +491,7 @@ def _write_atomic(path, data, mode=0o666):
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.

MAGIC_NUMBER = (3601).to_bytes(2, 'little') + b'\r\n'
MAGIC_NUMBER = (3602).to_bytes(2, 'little') + b'\r\n'

_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Remove unused macros in ``symtable.c``.
Patch by Bénédikt Tran.
7 changes: 4 additions & 3 deletions Modules/symtablemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,17 @@ static int
symtable_init_constants(PyObject *m)
{
if (PyModule_AddIntMacro(m, USE) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_ANNOT) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_IMPORT) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_GLOBAL) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_NONLOCAL) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_LOCAL) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_PARAM) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_TYPE_PARAM) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_FREE) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_FREE_CLASS) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_IMPORT) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_COMP_ITER) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_COMP_CELL) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_BOUND) < 0) return -1;
if (PyModule_AddIntMacro(m, DEF_ANNOT) < 0) return -1;

if (PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock) < 0)
return -1;
Expand Down
12 changes: 5 additions & 7 deletions Python/symtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,17 +318,16 @@ static void _dump_symtable(PySTEntryObject* ste, PyObject* prefix)
int scope = _PyST_GetScope(ste, name);
long flags = _PyST_GetSymbol(ste, name);
printf("%s %s: ", PyUnicode_AsUTF8(prefix), PyUnicode_AsUTF8(name));
if (flags & USE) printf(" USE");
if (flags & DEF_ANNOT) printf(" DEF_ANNOT");
if (flags & DEF_IMPORT) printf(" DEF_IMPORT");
if (flags & DEF_GLOBAL) printf(" DEF_GLOBAL");
if (flags & DEF_NONLOCAL) printf(" DEF_NONLOCAL");
if (flags & DEF_LOCAL) printf(" DEF_LOCAL");
if (flags & DEF_PARAM) printf(" DEF_PARAM");
if (flags & DEF_NONLOCAL) printf(" DEF_NONLOCAL");
if (flags & USE) printf(" USE");
if (flags & DEF_FREE) printf(" DEF_FREE");
if (flags & DEF_TYPE_PARAM) printf(" DEF_TYPE_PARAM");
if (flags & DEF_FREE_CLASS) printf(" DEF_FREE_CLASS");
if (flags & DEF_IMPORT) printf(" DEF_IMPORT");
if (flags & DEF_ANNOT) printf(" DEF_ANNOT");
if (flags & DEF_COMP_ITER) printf(" DEF_COMP_ITER");
if (flags & DEF_TYPE_PARAM) printf(" DEF_TYPE_PARAM");
if (flags & DEF_COMP_CELL) printf(" DEF_COMP_CELL");
switch (scope) {
case LOCAL: printf(" LOCAL"); break;
Expand Down Expand Up @@ -791,7 +790,6 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
// letting it be marked as free in class scope will break due to
// drop_class_free
scope = GLOBAL_IMPLICIT;
only_flags &= ~DEF_FREE;
if (PySet_Discard(comp_free, k) < 0) {
return 0;
}
Expand Down
Loading