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):
760760static PyObject *
761761ast_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):
971971972972self.emit("static int init_types(void)",0)
973973self.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)
987975self.emit("if (state->initialized) return 1;", 1)
988976self.emit("if (init_identifiers(state) < 0) return 0;", 1)
989977self.emit("state->AST_type = PyType_FromSpec(&AST_type_spec);", 1)
@@ -1061,13 +1049,16 @@ def visitModule(self, mod):
10611049self.emit("PyMODINIT_FUNC", 0)
10621050self.emit("PyInit__ast(void)", 0)
10631051self.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)
10681056self.emit('astmodulestate *state = get_ast_state(m);', 1)
10691057self.emit('', 1)
107010581059+self.emit("if (!init_types()) {", 1)
1060+self.emit("goto error;", 2)
1061+self.emit("}", 1)
10711062self.emit('if (PyModule_AddObject(m, "AST", state->AST_type) < 0) {', 1)
10721063self.emit('goto error;', 2)
10731064self.emit('}', 1)
@@ -1084,6 +1075,7 @@ def visitModule(self, mod):
10841075for dfn in mod.dfns:
10851076self.visit(dfn)
10861077self.emit("return m;", 1)
1078+self.emit("", 0)
10871079self.emit("error:", 0)
10881080self.emit("Py_DECREF(m);", 1)
10891081self.emit("return NULL;", 1)
@@ -1263,9 +1255,11 @@ class PartingShots(StaticVisitor):
12631255CODE = """
12641256PyObject* 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):
1308130313091304int 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):
13611358f.write(' PyObject *' + s + ';\n')
13621359f.write('} astmodulestate;\n\n')
13631360f.write("""
1361+static astmodulestate global_ast_state;
1362+13641363static 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}
1372136813731369static int astmodule_clear(PyObject *module)
@@ -1396,17 +1392,14 @@ def generate_module_def(f, mod):
1396139213971393static 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""")
14121405f.write('static int init_identifiers(astmodulestate *state)\n')