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