D11081: run-test: rework the redirection script for python on windows
marmoute (Pierre-Yves David)
phabricator at mercurial-scm.org
Sun Jul 11 21:38:38 UTC 2021
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
REVISION SUMMARY
This should get use something something overall simpler and clearer. Especially,
we now have a `python.exe` script (even if by default Windows has
`C:\Python27\python.exe` hardcoded in the register to open .py file)
REPOSITORY
rHG Mercurial
BRANCH
default
REVISION DETAIL
https://phab.mercurial-scm.org/D11081
AFFECTED FILES
tests/run-tests.py
CHANGE DETAILS
diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -3572,16 +3572,18 @@
def _usecorrectpython(self):
"""Configure the environment to use the appropriate Python in tests."""
# Tests must use the same interpreter as us or bad things will happen.
- if sys.platform == 'win32':
+ if WINDOWS and PYTHON3:
+ pyexe_names = [b'python', b'python3', b'python.exe']
+ elif WINDOWS:
pyexe_names = [b'python', b'python.exe']
- elif sys.version_info[0] < 3:
+ elif PYTHON3:
+ pyexe_names = [b'python', b'python3']
+ else:
pyexe_names = [b'python', b'python2']
- else:
- pyexe_names = [b'python', b'python3']
# os.symlink() is a thing with py3 on Windows, but it requires
# Administrator rights.
- if getattr(os, 'symlink', None) and not WINDOWS:
+ if not WINDOWS and getattr(os, 'symlink', None):
msg = "# Making python executable in test path a symlink to '%s'"
msg %= sysexecutable
vlog(msg)
@@ -3602,57 +3604,50 @@
# child processes may race, which is harmless
if err.errno != errno.EEXIST:
raise
+ elif WINDOWS and not os.getenv('MSYSTEM'):
+ raise AssertionError('cannot run test on Windows without MSYSTEM')
else:
- # Windows doesn't have `python3.exe`, and MSYS cannot understand the
- # reparse point with that name provided by Microsoft. Create a
- # simple script on PATH with that name that delegates to the py3
- # launcher so the shebang lines work.
- if os.getenv('MSYSTEM'):
- py3exe_name = os.path.join(self._custom_bin_dir, b'python3')
- with open(py3exe_name, 'wb') as f:
- f.write(b'#!/bin/sh\n')
- f.write(b'py -3.%d "$@"\n' % sys.version_info[1])
-
- pyexe_name = os.path.join(self._custom_bin_dir, b'python')
- with open(pyexe_name, 'wb') as f:
- f.write(b'#!/bin/sh\n')
- f.write(b'py -%d.%d "$@"\n' % sys.version_info[0:2])
-
- exedir, exename = os.path.split(sysexecutable)
+ # Generate explicit file instead of symlink
+ #
+ # This is especially important as Windows doesn't have
+ # `python3.exe`, and MSYS cannot understand the reparse point with
+ # that name provided by Microsoft. Create a simple script on PATH
+ # with that name that delegates to the py3 launcher so the shebang
+ # lines work.
+ esc_executable = _sys2bytes(shellquote(sysexecutable))
for pyexename in pyexe_names:
- msg = "# Modifying search path to find %s as %s in '%s'"
- msg %= (exename, pyexename, exedir)
- vlog(msg)
- path = os.environ['PATH'].split(os.pathsep)
- while exedir in path:
- path.remove(exedir)
-
- # Binaries installed by pip into the user area like pylint.exe may
- # not be in PATH by default.
- extra_paths = [exedir]
- vi = sys.version_info
- appdata = os.environ.get('APPDATA')
- if appdata is not None:
- scripts_dir = os.path.join(
- appdata,
- 'Python',
- 'Python%d%d' % (vi[0], vi[1]),
- 'Scripts',
- )
-
- if vi.major == 2:
- scripts_dir = os.path.join(
- appdata,
- 'Python',
- 'Scripts',
- )
-
- extra_paths.append(scripts_dir)
-
- os.environ['PATH'] = os.pathsep.join(extra_paths + path)
- for pyexename in pyexe_names:
- if not self._findprogram(pyexename):
- print("WARNING: Cannot find %s in search path" % pyexename)
+ stub_exec_path = os.path.join(self._custom_bin_dir, pyexename)
+ with open(stub_exec_path, 'wb') as f:
+ f.write(b'#!/bin/sh\n')
+ f.write(b'%s "$@"\n' % esc_executable)
+
+ if WINDOWS:
+ if not PYTHON3:
+ # lets try to build a valid python3 executable for the
+ # scrip that requires it.
+ py3exe_name = os.path.join(self._custom_bin_dir, b'python3')
+ with open(py3exe_name, 'wb') as f:
+ f.write(b'#!/bin/sh\n')
+ f.write(b'py -3 "$@"\n')
+
+ # adjust the path to make sur the main python finds it own dll
+ path = os.environ['PATH'].split(os.pathsep)
+ main_exec_dir = os.path.dirname(sysexecutable)
+ extra_paths = [_bytes2sys(self._custom_bin_dir), main_exec_dir]
+
+ # Binaries installed by pip into the user area like pylint.exe may
+ # not be in PATH by default.
+ appdata = os.environ.get('APPDATA')
+ vi = sys.version_info
+ if appdata is not None:
+ python_dir = 'Python%d%d' % (vi[0], vi[1])
+ scripts_path = [appdata, 'Python', python_dir, 'Scripts']
+ if not PYTHON3:
+ scripts_path = [appdata, 'Python', 'Scripts']
+ scripts_dir = os.path.join(*scripts_path)
+ extra_paths.append(scripts_dir)
+
+ os.environ['PATH'] = os.pathsep.join(extra_paths + path)
def _use_correct_mercurial(self):
target_exec = os.path.join(self._custom_bin_dir, b'hg')
To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
More information about the Mercurial-devel
mailing list