comparison tests/run-tests.py @ 42523:49998d5ba66a

pycompat: make fewer assumptions about sys.executable There are many Python "bundlers" which create an archive to run a Python binary from, and they may not set sys.executable at all - handle that case properly, especially to run tests. Differential Revision: https://phab.mercurial-scm.org/D6575
author Rodrigo Damazio Bovendorp <rdamazio@google.com>
date Tue, 25 Jun 2019 19:28:41 -0700
parents 84aff7e20c55
children 9913fffd744b
comparison
equal deleted inserted replaced
42522:d29db0a0c4eb 42523:49998d5ba66a
280 terminate(p) 280 terminate(p)
281 threading.Thread(target=t).start() 281 threading.Thread(target=t).start()
282 282
283 return p 283 return p
284 284
285 PYTHON = _bytespath(sys.executable.replace('\\', '/')) 285 if sys.executable:
286 sysexecutable = sys.executable
287 elif os.environ.get('PYTHONEXECUTABLE'):
288 sysexecutable = os.environ['PYTHONEXECUTABLE']
289 elif os.environ.get('PYTHON'):
290 sysexecutable = os.environ['PYTHON']
291 else:
292 raise AssertionError('Could not find Python interpreter')
293
294 PYTHON = _bytespath(sysexecutable.replace('\\', '/'))
286 IMPL_PATH = b'PYTHONPATH' 295 IMPL_PATH = b'PYTHONPATH'
287 if 'java' in sys.platform: 296 if 'java' in sys.platform:
288 IMPL_PATH = b'JYTHONPATH' 297 IMPL_PATH = b'JYTHONPATH'
289 298
290 defaults = { 299 defaults = {
1092 # This list should be parallel to _portmap in _getreplacements 1101 # This list should be parallel to _portmap in _getreplacements
1093 defineport(port) 1102 defineport(port)
1094 env["HGRCPATH"] = _strpath(os.path.join(self._threadtmp, b'.hgrc')) 1103 env["HGRCPATH"] = _strpath(os.path.join(self._threadtmp, b'.hgrc'))
1095 env["DAEMON_PIDS"] = _strpath(os.path.join(self._threadtmp, 1104 env["DAEMON_PIDS"] = _strpath(os.path.join(self._threadtmp,
1096 b'daemon.pids')) 1105 b'daemon.pids'))
1097 env["HGEDITOR"] = ('"' + sys.executable + '"' 1106 env["HGEDITOR"] = ('"' + sysexecutable + '"'
1098 + ' -c "import sys; sys.exit(0)"') 1107 + ' -c "import sys; sys.exit(0)"')
1099 env["HGUSER"] = "test" 1108 env["HGUSER"] = "test"
1100 env["HGENCODING"] = "ascii" 1109 env["HGENCODING"] = "ascii"
1101 env["HGENCODINGMODE"] = "strict" 1110 env["HGENCODINGMODE"] = "strict"
1102 env["HGHOSTNAME"] = "test-hostname" 1111 env["HGHOSTNAME"] = "test-hostname"
2347 # that alter hg's behavior inside the tests. 2356 # that alter hg's behavior inside the tests.
2348 opts = '' 2357 opts = ''
2349 withhg = self._runner.options.with_hg 2358 withhg = self._runner.options.with_hg
2350 if withhg: 2359 if withhg:
2351 opts += ' --with-hg=%s ' % shellquote(_strpath(withhg)) 2360 opts += ' --with-hg=%s ' % shellquote(_strpath(withhg))
2352 rtc = '%s %s %s %s' % (sys.executable, sys.argv[0], opts, 2361 rtc = '%s %s %s %s' % (sysexecutable, sys.argv[0], opts,
2353 test) 2362 test)
2354 data = pread(bisectcmd + ['--command', rtc]) 2363 data = pread(bisectcmd + ['--command', rtc])
2355 m = re.search( 2364 m = re.search(
2356 (br'\nThe first (?P<goodbad>bad|good) revision ' 2365 (br'\nThe first (?P<goodbad>bad|good) revision '
2357 br'is:\nchangeset: +\d+:(?P<node>[a-f0-9]+)\n.*\n' 2366 br'is:\nchangeset: +\d+:(?P<node>[a-f0-9]+)\n.*\n'
3001 3010
3002 # os.symlink() is a thing with py3 on Windows, but it requires 3011 # os.symlink() is a thing with py3 on Windows, but it requires
3003 # Administrator rights. 3012 # Administrator rights.
3004 if getattr(os, 'symlink', None) and os.name != 'nt': 3013 if getattr(os, 'symlink', None) and os.name != 'nt':
3005 vlog("# Making python executable in test path a symlink to '%s'" % 3014 vlog("# Making python executable in test path a symlink to '%s'" %
3006 sys.executable) 3015 sysexecutable)
3007 mypython = os.path.join(self._tmpbindir, pyexename) 3016 mypython = os.path.join(self._tmpbindir, pyexename)
3008 try: 3017 try:
3009 if os.readlink(mypython) == sys.executable: 3018 if os.readlink(mypython) == sysexecutable:
3010 return 3019 return
3011 os.unlink(mypython) 3020 os.unlink(mypython)
3012 except OSError as err: 3021 except OSError as err:
3013 if err.errno != errno.ENOENT: 3022 if err.errno != errno.ENOENT:
3014 raise 3023 raise
3015 if self._findprogram(pyexename) != sys.executable: 3024 if self._findprogram(pyexename) != sysexecutable:
3016 try: 3025 try:
3017 os.symlink(sys.executable, mypython) 3026 os.symlink(sysexecutable, mypython)
3018 self._createdfiles.append(mypython) 3027 self._createdfiles.append(mypython)
3019 except OSError as err: 3028 except OSError as err:
3020 # child processes may race, which is harmless 3029 # child processes may race, which is harmless
3021 if err.errno != errno.EEXIST: 3030 if err.errno != errno.EEXIST:
3022 raise 3031 raise
3023 else: 3032 else:
3024 exedir, exename = os.path.split(sys.executable) 3033 exedir, exename = os.path.split(sysexecutable)
3025 vlog("# Modifying search path to find %s as %s in '%s'" % 3034 vlog("# Modifying search path to find %s as %s in '%s'" %
3026 (exename, pyexename, exedir)) 3035 (exename, pyexename, exedir))
3027 path = os.environ['PATH'].split(os.pathsep) 3036 path = os.environ['PATH'].split(os.pathsep)
3028 while exedir in path: 3037 while exedir in path:
3029 path.remove(exedir) 3038 path.remove(exedir)
3046 else: 3055 else:
3047 pure = b"" 3056 pure = b""
3048 3057
3049 # Run installer in hg root 3058 # Run installer in hg root
3050 script = os.path.realpath(sys.argv[0]) 3059 script = os.path.realpath(sys.argv[0])
3051 exe = sys.executable 3060 exe = sysexecutable
3052 if PYTHON3: 3061 if PYTHON3:
3053 compiler = _bytespath(compiler) 3062 compiler = _bytespath(compiler)
3054 script = _bytespath(script) 3063 script = _bytespath(script)
3055 exe = _bytespath(exe) 3064 exe = _bytespath(exe)
3056 hgroot = os.path.dirname(os.path.dirname(script)) 3065 hgroot = os.path.dirname(os.path.dirname(script))