gh-120678: pyrepl: Include globals from modules passed with -i#120904
gh-120678: pyrepl: Include globals from modules passed with -i#120904ambv merged 9 commits intopython:mainfrom
-i#120904Conversation
|
Cc. @eryksun if you're interested! |
|
The reason why >>> __package__
'_pyrepl'
>>> __name__
'__main__'
>>> __spec__
ModuleSpec(name='_pyrepl.__main__', loader=<_frozen_importlib_external.SourceFileLoader object at 0x103a020c0>, origin='/Volumes/RAMDisk/cpython/Lib/_pyrepl/__main__.py')
>>> __file__
'/Volumes/RAMDisk/cpython/Lib/_pyrepl/__main__.py'We'd need to work around that. |
| reader.can_colorize = False | ||
| return reader | ||
|
|
||
| def test_stdin_is_tty(self): |
There was a problem hiding this comment.
This was helpful to me when debugging weird behavior so I decided to keep it.
| return; | ||
| } | ||
| int run = pymain_run_module(L"_pyrepl", 0); | ||
| int run = pymain_start_pyrepl_no_main(); |
There was a problem hiding this comment.
My first intuition was to simply PyImport_ImportModule("_pyrepl.__main__") but then the entire shell session is a side-effect of an on-going import, which was ugly and caused some funny edge cases (a non-zero exit was technically an ImportError).
So instead we do the full dance of running _pyrepl.main.interactive_console(). While doing that I'm smuggling PYTHONSTARTUP support because:
- you can always remove PYTHONSTARTUP from your environment to not have it;
- but previously you could not get PYTHONSTARTUP to be executed even if you wanted.
|
Thanks for picking this up @ambv! |
|
It's team work: I push the shoddy changes, you get the |
|
Thanks @AlexWaygood for the PR, and @ambv for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13. |
pythonGH-120904) (cherry picked from commit ac07451) Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Łukasz Langa <lukasz@langa.pl>
|
GH-121916 is a backport of this pull request to the 3.13 branch. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
In order to fix the regression caused by #119547, this PR goes back to the original fix that was proposed in the early commits of #119547.
The REPL must use the globals from
sys.modules["__main__"]in case a different module has been run as__main__using-i; in order to prevent globals from_pyrepl.__main__from leaking into the global namespace, we move the vast majority of the globals out of__main__.pyinstead of running the REPL with an entirely fresh set of globals.Some small filtering of globals is additionally done in
Lib/_pyrepl/simple_interact.py, so that we're able to import functions and classes in_pyrepl.__main__without these globals leaking into the REPL environment. (This filtering only works for things with__module__attributes, though, so it's still best to keep_pyrepl/__main__.pyas minimal as possible.)This still doesn't exactly match the behaviour of the old REPL for some dunders:
I'm not really sure why that is!
-i#120678