bpo-41194: The _ast module cannot be loaded more than once (GH-21290) · python/cpython@91e1bc1

@@ -691,7 +691,7 @@ def visitModule(self, mod):

691691

Py_ssize_t i, numfields = 0;

692692

int res = -1;

693693

PyObject *key, *value, *fields;

694-

astmodulestate *state = astmodulestate_global;

694+

astmodulestate *state = get_global_ast_state();

695695

if (_PyObject_LookupAttr((PyObject*)Py_TYPE(self), state->_fields, &fields) < 0) {

696696

goto cleanup;

697697

}

@@ -760,7 +760,7 @@ def visitModule(self, mod):

760760

static PyObject *

761761

ast_type_reduce(PyObject *self, PyObject *unused)

762762

{

763-

astmodulestate *state = astmodulestate_global;

763+

astmodulestate *state = get_global_ast_state();

764764

PyObject *dict;

765765

if (_PyObject_LookupAttr(self, state->__dict__, &dict) < 0) {

766766

return NULL;

@@ -971,19 +971,7 @@ def visitModule(self, mod):

971971972972

self.emit("static int init_types(void)",0)

973973

self.emit("{", 0)

974-

self.emit("PyObject *module = PyState_FindModule(&_astmodule);", 1)

975-

self.emit("if (module == NULL) {", 1)

976-

self.emit("module = PyModule_Create(&_astmodule);", 2)

977-

self.emit("if (!module) {", 2)

978-

self.emit("return 0;", 3)

979-

self.emit("}", 2)

980-

self.emit("if (PyState_AddModule(module, &_astmodule) < 0) {", 2)

981-

self.emit("return 0;", 3)

982-

self.emit("}", 2)

983-

self.emit("}", 1)

984-

self.emit("", 0)

985-986-

self.emit("astmodulestate *state = get_ast_state(module);", 1)

974+

self.emit("astmodulestate *state = get_global_ast_state();", 1)

987975

self.emit("if (state->initialized) return 1;", 1)

988976

self.emit("if (init_identifiers(state) < 0) return 0;", 1)

989977

self.emit("state->AST_type = PyType_FromSpec(&AST_type_spec);", 1)

@@ -1061,13 +1049,16 @@ def visitModule(self, mod):

10611049

self.emit("PyMODINIT_FUNC", 0)

10621050

self.emit("PyInit__ast(void)", 0)

10631051

self.emit("{", 0)

1064-

self.emit("PyObject *m;", 1)

1065-

self.emit("if (!init_types()) return NULL;", 1)

1066-

self.emit('m = PyState_FindModule(&_astmodule);', 1)

1067-

self.emit("if (!m) return NULL;", 1)

1052+

self.emit("PyObject *m = PyModule_Create(&_astmodule);", 1)

1053+

self.emit("if (!m) {", 1)

1054+

self.emit("return NULL;", 2)

1055+

self.emit("}", 1)

10681056

self.emit('astmodulestate *state = get_ast_state(m);', 1)

10691057

self.emit('', 1)

107010581059+

self.emit("if (!init_types()) {", 1)

1060+

self.emit("goto error;", 2)

1061+

self.emit("}", 1)

10711062

self.emit('if (PyModule_AddObject(m, "AST", state->AST_type) < 0) {', 1)

10721063

self.emit('goto error;', 2)

10731064

self.emit('}', 1)

@@ -1084,6 +1075,7 @@ def visitModule(self, mod):

10841075

for dfn in mod.dfns:

10851076

self.visit(dfn)

10861077

self.emit("return m;", 1)

1078+

self.emit("", 0)

10871079

self.emit("error:", 0)

10881080

self.emit("Py_DECREF(m);", 1)

10891081

self.emit("return NULL;", 1)

@@ -1263,9 +1255,11 @@ class PartingShots(StaticVisitor):

12631255

CODE = """

12641256

PyObject* PyAST_mod2obj(mod_ty t)

12651257

{

1266-

if (!init_types())

1258+

if (!init_types()) {

12671259

return NULL;

1268-

astmodulestate *state = astmodulestate_global;

1260+

}

1261+1262+

astmodulestate *state = get_global_ast_state();

12691263

return ast2obj_mod(state, t);

12701264

}

12711265

@@ -1279,16 +1273,17 @@ class PartingShots(StaticVisitor):

12791273

return NULL;

12801274

}

128112751282-

astmodulestate *state = astmodulestate_global;

1276+

astmodulestate *state = get_global_ast_state();

12831277

PyObject *req_type[3];

12841278

req_type[0] = state->Module_type;

12851279

req_type[1] = state->Expression_type;

12861280

req_type[2] = state->Interactive_type;

1287128112881282

assert(0 <= mode && mode <= 2);

128912831290-

if (!init_types())

1284+

if (!init_types()) {

12911285

return NULL;

1286+

}

1292128712931288

isinstance = PyObject_IsInstance(ast, req_type[mode]);

12941289

if (isinstance == -1)

@@ -1308,9 +1303,11 @@ class PartingShots(StaticVisitor):

1308130313091304

int PyAST_Check(PyObject* obj)

13101305

{

1311-

if (!init_types())

1306+

if (!init_types()) {

13121307

return -1;

1313-

astmodulestate *state = astmodulestate_global;

1308+

}

1309+1310+

astmodulestate *state = get_global_ast_state();

13141311

return PyObject_IsInstance(obj, state->AST_type);

13151312

}

13161313

"""

@@ -1361,13 +1358,12 @@ def generate_module_def(f, mod):

13611358

f.write(' PyObject *' + s + ';\n')

13621359

f.write('} astmodulestate;\n\n')

13631360

f.write("""

1361+

static astmodulestate global_ast_state;

1362+13641363

static astmodulestate *

1365-

get_ast_state(PyObject *module)

1364+

get_ast_state(PyObject *Py_UNUSED(module))

13661365

{

1367-

assert(module != NULL);

1368-

void *state = PyModule_GetState(module);

1369-

assert(state != NULL);

1370-

return (astmodulestate *)state;

1366+

return &global_ast_state;

13711367

}

1372136813731369

static int astmodule_clear(PyObject *module)

@@ -1396,17 +1392,14 @@ def generate_module_def(f, mod):

1396139213971393

static struct PyModuleDef _astmodule = {

13981394

PyModuleDef_HEAD_INIT,

1399-

"_ast",

1400-

NULL,

1401-

sizeof(astmodulestate),

1402-

NULL,

1403-

NULL,

1404-

astmodule_traverse,

1405-

astmodule_clear,

1406-

astmodule_free,

1395+

.m_name = "_ast",

1396+

.m_size = -1,

1397+

.m_traverse = astmodule_traverse,

1398+

.m_clear = astmodule_clear,

1399+

.m_free = astmodule_free,

14071400

};

140814011409-

#define astmodulestate_global get_ast_state(PyState_FindModule(&_astmodule))

1402+

#define get_global_ast_state() (&global_ast_state)

1410140314111404

""")

14121405

f.write('static int init_identifiers(astmodulestate *state)\n')