Mercurial > hg
comparison tests/run-tests.py @ 47639:e1130abae834
run-test: rework the redirection script for python on windows
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)
Differential Revision: https://phab.mercurial-scm.org/D11081
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Sun, 11 Jul 2021 16:11:58 +0200 |
parents | 55a715c36e3b |
children | c405c089611a |
comparison
equal
deleted
inserted
replaced
47638:55a715c36e3b | 47639:e1130abae834 |
---|---|
3569 pass | 3569 pass |
3570 | 3570 |
3571 def _usecorrectpython(self): | 3571 def _usecorrectpython(self): |
3572 """Configure the environment to use the appropriate Python in tests.""" | 3572 """Configure the environment to use the appropriate Python in tests.""" |
3573 # Tests must use the same interpreter as us or bad things will happen. | 3573 # Tests must use the same interpreter as us or bad things will happen. |
3574 if sys.platform == 'win32': | 3574 if WINDOWS and PYTHON3: |
3575 pyexe_names = [b'python', b'python3', b'python.exe'] | |
3576 elif WINDOWS: | |
3575 pyexe_names = [b'python', b'python.exe'] | 3577 pyexe_names = [b'python', b'python.exe'] |
3576 elif sys.version_info[0] < 3: | 3578 elif PYTHON3: |
3579 pyexe_names = [b'python', b'python3'] | |
3580 else: | |
3577 pyexe_names = [b'python', b'python2'] | 3581 pyexe_names = [b'python', b'python2'] |
3578 else: | |
3579 pyexe_names = [b'python', b'python3'] | |
3580 | 3582 |
3581 # os.symlink() is a thing with py3 on Windows, but it requires | 3583 # os.symlink() is a thing with py3 on Windows, but it requires |
3582 # Administrator rights. | 3584 # Administrator rights. |
3583 if getattr(os, 'symlink', None) and not WINDOWS: | 3585 if not WINDOWS and getattr(os, 'symlink', None): |
3584 msg = "# Making python executable in test path a symlink to '%s'" | 3586 msg = "# Making python executable in test path a symlink to '%s'" |
3585 msg %= sysexecutable | 3587 msg %= sysexecutable |
3586 vlog(msg) | 3588 vlog(msg) |
3587 for pyexename in pyexe_names: | 3589 for pyexename in pyexe_names: |
3588 mypython = os.path.join(self._custom_bin_dir, pyexename) | 3590 mypython = os.path.join(self._custom_bin_dir, pyexename) |
3599 self._createdfiles.append(mypython) | 3601 self._createdfiles.append(mypython) |
3600 except OSError as err: | 3602 except OSError as err: |
3601 # child processes may race, which is harmless | 3603 # child processes may race, which is harmless |
3602 if err.errno != errno.EEXIST: | 3604 if err.errno != errno.EEXIST: |
3603 raise | 3605 raise |
3606 elif WINDOWS and not os.getenv('MSYSTEM'): | |
3607 raise AssertionError('cannot run test on Windows without MSYSTEM') | |
3604 else: | 3608 else: |
3605 # Windows doesn't have `python3.exe`, and MSYS cannot understand the | 3609 # Generate explicit file instead of symlink |
3606 # reparse point with that name provided by Microsoft. Create a | 3610 # |
3607 # simple script on PATH with that name that delegates to the py3 | 3611 # This is especially important as Windows doesn't have |
3608 # launcher so the shebang lines work. | 3612 # `python3.exe`, and MSYS cannot understand the reparse point with |
3609 if os.getenv('MSYSTEM'): | 3613 # that name provided by Microsoft. Create a simple script on PATH |
3610 py3exe_name = os.path.join(self._custom_bin_dir, b'python3') | 3614 # with that name that delegates to the py3 launcher so the shebang |
3611 with open(py3exe_name, 'wb') as f: | 3615 # lines work. |
3616 esc_executable = _sys2bytes(shellquote(sysexecutable)) | |
3617 for pyexename in pyexe_names: | |
3618 stub_exec_path = os.path.join(self._custom_bin_dir, pyexename) | |
3619 with open(stub_exec_path, 'wb') as f: | |
3612 f.write(b'#!/bin/sh\n') | 3620 f.write(b'#!/bin/sh\n') |
3613 f.write(b'py -3.%d "$@"\n' % sys.version_info[1]) | 3621 f.write(b'%s "$@"\n' % esc_executable) |
3614 | 3622 |
3615 pyexe_name = os.path.join(self._custom_bin_dir, b'python') | 3623 if WINDOWS: |
3616 with open(pyexe_name, 'wb') as f: | 3624 if not PYTHON3: |
3617 f.write(b'#!/bin/sh\n') | 3625 # lets try to build a valid python3 executable for the |
3618 f.write(b'py -%d.%d "$@"\n' % sys.version_info[0:2]) | 3626 # scrip that requires it. |
3619 | 3627 py3exe_name = os.path.join(self._custom_bin_dir, b'python3') |
3620 exedir, exename = os.path.split(sysexecutable) | 3628 with open(py3exe_name, 'wb') as f: |
3621 for pyexename in pyexe_names: | 3629 f.write(b'#!/bin/sh\n') |
3622 msg = "# Modifying search path to find %s as %s in '%s'" | 3630 f.write(b'py -3 "$@"\n') |
3623 msg %= (exename, pyexename, exedir) | 3631 |
3624 vlog(msg) | 3632 # adjust the path to make sur the main python finds it own dll |
3625 path = os.environ['PATH'].split(os.pathsep) | 3633 path = os.environ['PATH'].split(os.pathsep) |
3626 while exedir in path: | 3634 main_exec_dir = os.path.dirname(sysexecutable) |
3627 path.remove(exedir) | 3635 extra_paths = [_bytes2sys(self._custom_bin_dir), main_exec_dir] |
3628 | 3636 |
3629 # Binaries installed by pip into the user area like pylint.exe may | 3637 # Binaries installed by pip into the user area like pylint.exe may |
3630 # not be in PATH by default. | 3638 # not be in PATH by default. |
3631 extra_paths = [exedir] | 3639 appdata = os.environ.get('APPDATA') |
3632 vi = sys.version_info | 3640 vi = sys.version_info |
3633 appdata = os.environ.get('APPDATA') | 3641 if appdata is not None: |
3634 if appdata is not None: | 3642 python_dir = 'Python%d%d' % (vi[0], vi[1]) |
3635 scripts_dir = os.path.join( | 3643 scripts_path = [appdata, 'Python', python_dir, 'Scripts'] |
3636 appdata, | 3644 if not PYTHON3: |
3637 'Python', | 3645 scripts_path = [appdata, 'Python', 'Scripts'] |
3638 'Python%d%d' % (vi[0], vi[1]), | 3646 scripts_dir = os.path.join(*scripts_path) |
3639 'Scripts', | 3647 extra_paths.append(scripts_dir) |
3640 ) | 3648 |
3641 | 3649 os.environ['PATH'] = os.pathsep.join(extra_paths + path) |
3642 if vi.major == 2: | |
3643 scripts_dir = os.path.join( | |
3644 appdata, | |
3645 'Python', | |
3646 'Scripts', | |
3647 ) | |
3648 | |
3649 extra_paths.append(scripts_dir) | |
3650 | |
3651 os.environ['PATH'] = os.pathsep.join(extra_paths + path) | |
3652 for pyexename in pyexe_names: | |
3653 if not self._findprogram(pyexename): | |
3654 print("WARNING: Cannot find %s in search path" % pyexename) | |
3655 | 3650 |
3656 def _use_correct_mercurial(self): | 3651 def _use_correct_mercurial(self): |
3657 target_exec = os.path.join(self._custom_bin_dir, b'hg') | 3652 target_exec = os.path.join(self._custom_bin_dir, b'hg') |
3658 if self._hgcommand != b'hg': | 3653 if self._hgcommand != b'hg': |
3659 # shutil.which only accept bytes from 3.8 | 3654 # shutil.which only accept bytes from 3.8 |