# HG changeset patch # User Matt Harbison # Date 2018-09-15 04:04:06 # Node ID 543a788eea2df09e0b3359e4ae3aeda8728408f5 # Parent f3d1229555d9fcc8e92c9a8791c212c6705fb312 py3: allow run-tests.py to run on Windows This is now functional: HGMODULEPOLICY=py py -3 run-tests.py --local test-help.t --pure --view bcompare However, on this machine without a C compiler, it tries to load cext anyway, and blows up. I haven't looked into why, other than to see that it does set the environment variable. When the test exits though, I see it can't find killdaemons.py, get-with-headers.py, etc. I have no idea why these changes are needed, given that it runs on Linux. But os.system() is insisting that it take a str, and subprocess.Popen() blows up without str: Errored test-help.t: Traceback (most recent call last): File "run-tests.py", line 810, in run self.runTest() File "run-tests.py", line 858, in runTest ret, out = self._run(env) File "run-tests.py", line 1268, in _run exitcode, output = self._runcommand(cmd, env) File "run-tests.py", line 1141, in _runcommand env=env) File "C:\Program Files\Python37\lib\subprocess.py", line 756, in __init__ restore_signals, start_new_session) File "C:\Program Files\Python37\lib\subprocess.py", line 1100, in _execute_child args = list2cmdline(args) File "C:\Program Files\Python37\lib\subprocess.py", line 511, in list2cmdline needquote = (" " in arg) or ("\t" in arg) or not arg TypeError: argument of type 'int' is not iterable This is exactly how it crashes when trying to spin up a pager too. I left one instance of os.system() unchanged in _installhg(), because it doesn't get there. diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -229,7 +229,8 @@ def checkportisavailable(port): closefds = os.name == 'posix' def Popen4(cmd, wd, timeout, env=None): processlock.acquire() - p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd, env=env, + p = subprocess.Popen(_strpath(cmd), shell=True, bufsize=-1, + cwd=_strpath(wd), env=env, close_fds=closefds, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) @@ -988,7 +989,7 @@ class Test(unittest.TestCase): return ( (b''.join(c.isalpha() and b'[%s%s]' % (c.lower(), c.upper()) or c in b'/\\' and br'[/\\]' or c.isdigit() and c or b'\\' + c - for c in p)) + for c in [p[i:i + 1] for i in range(len(p))])) ) else: return re.escape(p) @@ -1137,7 +1138,8 @@ class Test(unittest.TestCase): Return a tuple (exitcode, output). output is None in debug mode. """ if self._debug: - proc = subprocess.Popen(cmd, shell=True, cwd=self._testtmp, + proc = subprocess.Popen(_strpath(cmd), shell=True, + cwd=_strpath(self._testtmp), env=env) ret = proc.wait() return (ret, None) @@ -1817,10 +1819,8 @@ class TestResult(unittest._TextTestResul pass elif self._options.view: v = self._options.view - if PYTHON3: - v = _bytespath(v) - os.system(b"%s %s %s" % - (v, test.refpath, test.errpath)) + os.system(r"%s %s %s" % + (v, _strpath(test.refpath), _strpath(test.errpath))) else: servefail, lines = getdiff(expected, got, test.refpath, test.errpath) @@ -2888,7 +2888,10 @@ class TestRunner(object): """Configure the environment to use the appropriate Python in tests.""" # Tests must use the same interpreter as us or bad things will happen. pyexename = sys.platform == 'win32' and b'python.exe' or b'python' - if getattr(os, 'symlink', None): + + # os.symlink() is a thing with py3 on Windows, but it requires + # Administrator rights. + if getattr(os, 'symlink', None) and os.name != 'nt': vlog("# Making python executable in test path a symlink to '%s'" % sys.executable) mypython = os.path.join(self._tmpbindir, pyexename)