Commit 377e44cb authored by Kirill Smelkov's avatar Kirill Smelkov

gpython: Fix startup on Windows when installed by pip

On windows setuptools install gpython.exe and gpython-script.py while
pip/distlib install gpython.exe with gpython-script sometimes embedded
into gpython.exe itself with argv[0] pointing to 'gpython' without .exe
suffix. This leads to gpython startup failure:

    (1.wenv) Z:\home\kirr\src\tools\go\pygo-win\pygolang>gpython
    Traceback (most recent call last):
      File "C:\Program Files\Python310\lib\runpy.py", line 196, in _run_module_as_main
        return _run_code(code, main_globals, None,
      File "C:\Program Files\Python310\lib\runpy.py", line 86, in _run_code
        exec(code, run_globals)
      File "Z:\home\kirr\src\tools\go\pygo-win\1.wenv\Scripts\gpython.exe\__main__.py", line 7, in <module>
      File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\gpython\__init__.py", line 437, in main
        pymain(argv, init)
      File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\gpython\__init__.py", line 79, in pymain
        if not _is_buildout_script(exe):
      File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\gpython\__init__.py", line 442, in _is_buildout_script
        with open(path, 'rb') as f:
    FileNotFoundError: [Errno 2] No such file or directory: 'Z:\\home\\kirr\\src\\tools\\go\\pygo-win\\1.wenv\\Scripts\\gpython'

    (1.wenv) Z:\home\kirr\src\tools\go\pygo-win\pygolang>dir ../1.wenv/scripts/gpython*

    Directory of Z:\home\kirr\src\tools\go\pygo-win\1.wenv\scripts

    26.04.2023     14:17       108,404  gpython.exe
           1 file                   108,404 bytes
           0 directories     88,508,866,560 bytes free

-> Adjust pymain to handle this case accordingly.
parent 2f632a3e
......@@ -50,19 +50,27 @@ _pyopt_long = ('version',)
# init, if provided, is called after options are parsed, but before interpreter start.
def pymain(argv, init=None):
import sys
from os.path import dirname, realpath
import os
from os.path import dirname, realpath, splitext
# sys.executable
# on windows there are
# gpython-script.py
# gpython.exe
# gpython-script.py
# gpython.manifest
# and argv[0] is gpython-script.py
# with gpython-script.py sometimes embedded into gpython.exe (pip/distlib)
# and argv[0] is 'gpython-script.py' (setuptools) or 'gpython' (pip/distlib; note no .exe)
exe = realpath(argv[0])
argv = argv[1:]
if exe.endswith('-script.py'):
exe = exe[:-len('-script.py')]
exe = exe + '.exe'
if os.name == 'nt':
if exe.endswith('-script.py'):
exe = exe[:-len('-script.py')] # gpython-script.py -> gpython.exe
exe = exe + '.exe'
else:
_, ext = splitext(exe) # gpython -> gpython.exe
if not ext:
exe += '.exe'
sys._gpy_underlying_executable = sys.executable
sys.executable = exe
......@@ -70,20 +78,26 @@ def pymain(argv, init=None):
# `gpython file` will add path-to-file to sys.path[0] by itself, and
# /path/to/gpython is unnecessary and would create difference in behaviour
# in between gpython and python.
#
# on windows when gpython.exe comes with embedded __main__.py, it is
# gpython.exe that is installed into sys.path[0] .
exedir = dirname(exe)
if sys.path[0] == exedir:
if sys.path[0] in (exedir, exe):
del sys.path[0]
else:
# buildout injects `sys.path[0:0] = eggs` into python scripts.
# detect that and remove sys.path entry corresponding to exedir.
if not _is_buildout_script(exe):
raise RuntimeError('pymain: internal error: sys.path[0] was not set by underlying python to dirname(exe):'
raise RuntimeError('pymain: internal error: sys.path[0] was not set by underlying python to dirname(exe) or exe:'
'\n\n\texe:\t%s\n\tsys.path[0]:\t%s' % (exe, sys.path[0]))
else:
if exedir in sys.path:
sys.path.remove(exedir)
else:
raise RuntimeError('pymain: internal error: sys.path does not contain dirname(exe):'
ok = False
for _ in (exedir, exe):
if _ in sys.path:
sys.path.remove(_)
ok = True
if not ok:
raise RuntimeError('pymain: internal error: sys.path does not contain dirname(exe) or exe:'
'\n\n\texe:\t%s\n\tsys.path:\t%s' % (exe, sys.path))
......@@ -202,7 +216,6 @@ def pymain(argv, init=None):
#
# python -O gpython file.py
if len(reexec_with) > 0:
import os
argv = [sys._gpy_underlying_executable] + reexec_with + [sys.executable] + reexec_argv
os.execv(argv[0], argv)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment