gh-135801: Add the module parameter to compile() etc (GH-139652)

Many functions related to compiling or parsing Python code, such as
compile(), ast.parse(), symtable.symtable(),
and importlib.abc.InspectLoader.source_to_code() now allow to pass
the module name used when filtering syntax warnings.
This commit is contained in:
Serhiy Storchaka 2025-11-13 13:21:32 +02:00 committed by GitHub
parent 63548b3699
commit d8e6bdc0d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
47 changed files with 390 additions and 115 deletions

View file

@ -104,11 +104,13 @@ typedef struct _PyCompiler {
* (including instructions for nested code objects)
*/
int c_disable_warning;
PyObject *c_module;
} compiler;
static int
compiler_setup(compiler *c, mod_ty mod, PyObject *filename,
PyCompilerFlags *flags, int optimize, PyArena *arena)
PyCompilerFlags *flags, int optimize, PyArena *arena,
PyObject *module)
{
PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
@ -126,6 +128,7 @@ compiler_setup(compiler *c, mod_ty mod, PyObject *filename,
if (!_PyFuture_FromAST(mod, filename, &c->c_future)) {
return ERROR;
}
c->c_module = Py_XNewRef(module);
if (!flags) {
flags = &local_flags;
}
@ -136,7 +139,9 @@ compiler_setup(compiler *c, mod_ty mod, PyObject *filename,
c->c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize;
c->c_save_nested_seqs = false;
if (!_PyAST_Preprocess(mod, arena, filename, c->c_optimize, merged, 0, 1)) {
if (!_PyAST_Preprocess(mod, arena, filename, c->c_optimize, merged,
0, 1, module))
{
return ERROR;
}
c->c_st = _PySymtable_Build(mod, filename, &c->c_future);
@ -156,6 +161,7 @@ compiler_free(compiler *c)
_PySymtable_Free(c->c_st);
}
Py_XDECREF(c->c_filename);
Py_XDECREF(c->c_module);
Py_XDECREF(c->c_const_cache);
Py_XDECREF(c->c_stack);
PyMem_Free(c);
@ -163,13 +169,13 @@ compiler_free(compiler *c)
static compiler*
new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
int optimize, PyArena *arena)
int optimize, PyArena *arena, PyObject *module)
{
compiler *c = PyMem_Calloc(1, sizeof(compiler));
if (c == NULL) {
return NULL;
}
if (compiler_setup(c, mod, filename, pflags, optimize, arena) < 0) {
if (compiler_setup(c, mod, filename, pflags, optimize, arena, module) < 0) {
compiler_free(c);
return NULL;
}
@ -1221,7 +1227,8 @@ _PyCompile_Warn(compiler *c, location loc, const char *format, ...)
return ERROR;
}
int ret = _PyErr_EmitSyntaxWarning(msg, c->c_filename, loc.lineno, loc.col_offset + 1,
loc.end_lineno, loc.end_col_offset + 1);
loc.end_lineno, loc.end_col_offset + 1,
c->c_module);
Py_DECREF(msg);
return ret;
}
@ -1476,10 +1483,10 @@ _PyCompile_OptimizeAndAssemble(compiler *c, int addNone)
PyCodeObject *
_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
int optimize, PyArena *arena)
int optimize, PyArena *arena, PyObject *module)
{
assert(!PyErr_Occurred());
compiler *c = new_compiler(mod, filename, pflags, optimize, arena);
compiler *c = new_compiler(mod, filename, pflags, optimize, arena, module);
if (c == NULL) {
return NULL;
}
@ -1492,7 +1499,8 @@ _PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
int
_PyCompile_AstPreprocess(mod_ty mod, PyObject *filename, PyCompilerFlags *cf,
int optimize, PyArena *arena, int no_const_folding)
int optimize, PyArena *arena, int no_const_folding,
PyObject *module)
{
_PyFutureFeatures future;
if (!_PyFuture_FromAST(mod, filename, &future)) {
@ -1502,7 +1510,9 @@ _PyCompile_AstPreprocess(mod_ty mod, PyObject *filename, PyCompilerFlags *cf,
if (optimize == -1) {
optimize = _Py_GetConfig()->optimization_level;
}
if (!_PyAST_Preprocess(mod, arena, filename, optimize, flags, no_const_folding, 0)) {
if (!_PyAST_Preprocess(mod, arena, filename, optimize, flags,
no_const_folding, 0, module))
{
return -1;
}
return 0;
@ -1627,7 +1637,7 @@ _PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
return NULL;
}
compiler *c = new_compiler(mod, filename, pflags, optimize, arena);
compiler *c = new_compiler(mod, filename, pflags, optimize, arena, NULL);
if (c == NULL) {
_PyArena_Free(arena);
return NULL;