| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
Following our discussion on the previous PR, I also changed the _cursesmodule prefix to cursesmodule so that we have at least a bit more of consistency. I won't touch the AC-generated functions. |
Sorry, something went wrong.
|
I'm really un-sure of how free-threaded builds with multi-phase initialization would interact with capsule objects. So I'd happy if any free-threaded expert could help me here. Here are some questions (and we may perhaps address them in separate PRs):
cc @colesbury (I don't know other free-threaded experts but feel free to delegate the question to anyone who knows about the topic if you don't have enough time!) |
Sorry, something went wrong.
There was a problem hiding this comment.
Can you try to add a global variable to prevent having more than 1 instance at the same time?
Sorry, something went wrong.
|
Here's the output, do you think it's good enough? >>> import sys
...
>>> import _curses as curses1
>>> del sys.modules['_curses']
...
>>> import _curses as curses2
...
Traceback (most recent call last):
File "<python-input-3>", line 1, in <module>
import _curses as curses2
ImportError: module 'curses' can only be loaded once per process |
Sorry, something went wrong.
|
cursesmodule_free() should set curses_module_loaded to 0. So you can load-unload the extension multiple times: import sys
import gc
print("load-unload")
import _curses
del _curses
del sys.modules['_curses']
gc.collect()
print("load again")
import _curses
del _curses
del sys.modules['_curses'] |
Sorry, something went wrong.
I'm not sure it works. Even if I do this it still tells me that the curses module cannot be loaded more than once per process. The cursesmodule_free() does not seem to be called even if gc.collect() is called (at least not in the REPL). What should I do? |
Sorry, something went wrong.
It works if you run my script: load-unload load again |
Sorry, something went wrong.
|
After some tests, it appears that the REPL only calls free() upon exiting the process (the REPL imports curses in Lib/_pyrepl/curses.py). So, reloading curses inside the REPL won't work. In a normal script, however: $ read -r -d '' code << EOM
import sys
print("load-unload")
import _curses
del _curses
del sys.modules['_curses']
print("load again")
import _curses
del _curses
del sys.modules['_curses']
EOM
$ ./python -c "$code"
load-unload
load again
Traceback (most recent call last):
File "<string>", line 9, in <module>
import _curses
ImportError: module 'curses' can only be loaded once per processWhen free is called via gc.collect(): $ read -r -d '' code << EOM
import sys
import gc
print("load-unload")
import _curses
del _curses
del sys.modules['_curses']
gc.collect()
print("load again")
import _curses
del _curses
del sys.modules['_curses']
EOM
$ ./python -c "$code"
load-unload
load again |
Sorry, something went wrong.
|
Merged, thanks. That's a nice step forward for the _curses extension :-) |
Sorry, something went wrong.
|
Python no longer leaks at exit: $ ./python -X showrefcount -c 'import _curses' [0 refs, 0 blocks] Python 3.13 for comparison: $ ./python -X showrefcount -c 'import _curses' [234 refs, 159 blocks] |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
I think this is the very last PR for this task, conditioned to some final cleanups just for macro readability and comments.