Message373456
Ok, I can reproduce the crash on the 3.9 branch using: ./python repro.py.
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:24 | vstinner | set | recipients:
+ vstinner, arcivanov |
2020-07-10 09:57:24 | vstinner | set | messageid: <1594375044.71.0.318124052546.issue41261@roundup.psfhosted.org> |
2020-07-10 09:57:24 | vstinner | link | issue41261 messages |
2020-07-10 09:57:24 | vstinner | create | |
|