Author vstinner
Recipients arcivanov, vstinner
Date 2020-07-10.09:57:24
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
Ok, I can reproduce the crash on the 3.9 branch using: ./python

The first problem is that astmodule_clear() doesn't reset the initiallized member: add "state->initialized = 0;".

The _ast module is special. Not only it has regular module function which access the module state, it also has 3 functions in C APIs which are called directly:

* PyAST_Check()
* PyAST_mod2obj()
* PyAST_obj2mod()

These functions require to have access to the _ast module. In Python 3.9, I chose to use a global state, as it was done in Python 3.8.

If sys.modules['_ast'] is cleared and then _ast is imported again, _PyState_AddModule() is called to store the new _ast module instance which calls astmodule_clear() on the old module instance.

The problem is that when astmodule_clear() is called, the new instance is already created and so exposes the "old" _ast.AST type.

1) import _ast: call init_types() which creates AST type #1
2) del sys.modules['_ast]
3) import _ast: create a new module which exposes AST type #1
3) import _ast: also clears the old module (_PyState_AddModule()) which calls astmodule_clear()
4) Calling PyAST_Check() calls init_types() which creates AST type #2: PyAST_Check() returns false, since AST type #1 and AST type #2 are different


In the master branch, I modified PyAST_Check(), PyAST_mod2obj() and PyAST_obj2mod() to import the _ast module and get the state from the module. The state is not global in master.

For 3.9, I'm not sure what is the best option:

* Backport master changes (not well tested yet, but is it worse than this known crash?)
* Never clear the state: leak references at Python exit.
Date User Action Args
2020-07-10 09:57:24vstinnersetrecipients: + vstinner, arcivanov
2020-07-10 09:57:24vstinnersetmessageid: <>
2020-07-10 09:57:24vstinnerlinkissue41261 messages
2020-07-10 09:57:24vstinnercreate