On 3/25/2019 12:27 AM, Cameron Simpson wrote:
On 24Mar2019 23:22, Terry Reedy <tjre...@udel.edu> wrote:
On 3/24/2019 10:01 PM, Terry Reedy wrote:
On 3/24/2019 7:00 PM, Cameron Simpson wrote:
Did you have a specific scenario in mind?
I was thinking about IDLE and its tangled web of circular inports,
but I am now convinced that this change will not affect it. Indeed,
idlelib/pyshell.py already implements idea of the proposal, ending with
if __name__ == "__main__":
sys.modules['pyshell'] = sys.modules['__main__']
main()
After more investigation, I realized that to stop having duplicate
modulue:
1. The alias should be 'idlelib.pyshell', not 'pyshell', at least when
imports are all absolute.
The PEP499 patch effectively uses __main__.__spec__.name for the name of
the alias. Does that simplify your issue?
The current PR is here if you want to look at it:
https://github.com/python/cpython/pull/12490
The new test passes on Win10.
2. It should be done at the top of the file, before the import of
modules that import pyshell.
Hmm, if PEP499 comes in you shouldn't need to do this at all. If PEP499
gets delayed or rejected I guess you're supporting this without it. Yes,
you'll want to do it before any other imports happen (well, as you say,
before any which import pyshell).
What about (untested):
if __name__ == '__main__':
if __spec__.name not in sys.modules:
When I start pyshell in my master repository directory on windows with
python -m idlelib.pyshell
__spec__.name is 'idlelib.pyshell, which I currently hard-coded.
When I start with what should be equivalent
python f:/dev/3x/lib/idlelib/pyshell.py
__spec__ is None and __spec__.name an attribute error.
sys.modules[__spec__.name] = sys.modules['__main__']
as a forward compatible setup?
If I run python f:/dev/3x/lib/idlelib/pyshell.py, the PEP patch would
have to notice that pyshell is a module within idlelib and alias
'__main__' to 'idlelib.pyshell', not 'pyshell'. Would the same be
true if within-package import were all relative?
I think so because we're using .__spec__.name, which I though was post
import name resolution.
You must be doing something different when __spec__ is None ;-). I
tested the patch and it does not raise AttributeError with the command
above.
Testing in my PEP499 branch:
Test 1:
[~/src/cpython-cs@github(git:PEP499-cs)]fleet*> ./python.exe -i
Lib/idlelib/pyshell.py
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'run'
This is because of an obsolete 'command = ...' around 420. The if line
is correct always and the if/then not needed.
>>> sys.modules['__main__']
<module '__main__' (<_frozen_importlib_external.SourceFileLoader
object at 0x1088e6040>)>
>>> sys.modules['pyshell']
<module '__main__' (<_frozen_importlib_external.SourceFileLoader
object at 0x1088e6040>)>
>>> sys.modules['idlelib.pyshell']
<module 'idlelib.pyshell' from
'/Users/cameron/src/cpython-cs@github/Lib/idlelib/pyshell.py'>
So pyshell and idlelib.pyshell are distinct here.
I verified that the module was being executed twice by putting
print('running') at the top.
__main__ and pyshell
are the same module, courtesy of your sys.modules assignment at the
bottom of pyshell.py.
Obsolete and removed.
Test 3 below will be with that commented out.
Test 2:
[~/src/cpython-cs@github(git:PEP499-cs)]fleet*> PYTHONPATH=$PWD/Lib
./python.exe -i -m idlelib.pyshell
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'run'
>>> sys.modules['__main__']
<module 'idlelib.pyshell' from
'/Users/cameron/src/cpython-cs@github/Lib/idlelib/pyshell.py'>
>>> sys.modules['pyshell']
<module 'idlelib.pyshell' from
'/Users/cameron/src/cpython-cs@github/Lib/idlelib/pyshell.py'>
>>> sys.modules['idlelib.pyshell']
<module 'idlelib.pyshell' from
'/Users/cameron/src/cpython-cs@github/Lib/idlelib/pyshell.py'>
>>> id(sys.modules['__main__'])
4551072712
>>> id(sys.modules['pyshell'])
4551072712
>>> id(sys.modules['idlelib.pyshell'])
4551072712
So this has __main__ and idlelib.pyshell the same module from the PEP499
patch and pyshell also the same from your sys.modules assignment.
Test 3, with the pyshell.py sys.modules assignment commented out:
[~/src/cpython-cs@github(git:PEP499-cs)]fleet*> PYTHONPATH=$PWD/Lib
./python.exe -i -m idlelib.pyshell
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'run'
>>> sys.modules['__main__']
<module 'idlelib.pyshell' from
'/Users/cameron/src/cpython-cs@github/Lib/idlelib/pyshell.py'>
>>> sys.modules['pyshell']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'pyshell'
>>> sys.modules['idlelib.pyshell']
<module 'idlelib.pyshell' from
'/Users/cameron/src/cpython-cs@github/Lib/idlelib/pyshell.py'>
>>> id(sys.modules['__main__'])
4552379336
>>> id(sys.modules['idlelib.pyshell'])
4552379336
Here we've got __main__ and idlelib.pyshell the same module and no
'pyshell' in sys.modules.
I don't think I understand your "relative import" scenario.
If files other that pyshell used relative 'import ./pyshell' instead of
absolute 'import idlelib.pyshell', would the sys.modules key still be
'idlelib.pyshell' or 'pyshell'? Which is to ask, would the alias
needed to avoid a second pyshell module still be 'idlelib.pyshell' or
'pyshell'?
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com