py3: convert arguments, cwd and env to native strings when spawning subprocess
This keeps Windows happy.
--- a/hgext/convert/common.py Fri Sep 21 21:14:27 2018 -0400
+++ b/hgext/convert/common.py Sun Sep 23 00:47:04 2018 -0400
@@ -402,7 +402,8 @@
def _run(self, cmd, *args, **kwargs):
def popen(cmdline):
- p = subprocess.Popen(cmdline, shell=True, bufsize=-1,
+ p = subprocess.Popen(pycompat.rapply(procutil.tonativestr, cmdline),
+ shell=True, bufsize=-1,
close_fds=procutil.closefds,
stdout=subprocess.PIPE)
return p
--- a/hgext/convert/gnuarch.py Fri Sep 21 21:14:27 2018 -0400
+++ b/hgext/convert/gnuarch.py Sun Sep 23 00:47:04 2018 -0400
@@ -17,6 +17,7 @@
from mercurial import (
encoding,
error,
+ pycompat,
)
from mercurial.utils import (
dateutil,
@@ -201,7 +202,7 @@
cmdline += ['>', os.devnull, '2>', os.devnull]
cmdline = procutil.quotecommand(' '.join(cmdline))
self.ui.debug(cmdline, '\n')
- return os.system(cmdline)
+ return os.system(pycompat.rapply(procutil.tonativestr, cmdline))
def _update(self, rev):
self.ui.debug('applying revision %s...\n' % rev)
--- a/hgext/factotum.py Fri Sep 21 21:14:27 2018 -0400
+++ b/hgext/factotum.py Sun Sep 23 00:47:04 2018 -0400
@@ -49,6 +49,9 @@
import os
from mercurial.i18n import _
+from mercurial.utils import (
+ procutil,
+)
from mercurial import (
error,
httpconnection,
@@ -83,7 +86,7 @@
if 'user=' not in params:
params = '%s user?' % params
params = '%s !password?' % params
- os.system("%s -g '%s'" % (_executable, params))
+ os.system(procutil.tonativestr("%s -g '%s'" % (_executable, params)))
def auth_getuserpasswd(self, getkey, params):
params = 'proto=pass %s' % params
--- a/hgext/fix.py Fri Sep 21 21:14:27 2018 -0400
+++ b/hgext/fix.py Sun Sep 23 00:47:04 2018 -0400
@@ -58,6 +58,10 @@
from mercurial.node import nullrev
from mercurial.node import wdirrev
+from mercurial.utils import (
+ procutil,
+)
+
from mercurial import (
cmdutil,
context,
@@ -448,9 +452,9 @@
continue
ui.debug('subprocess: %s\n' % (command,))
proc = subprocess.Popen(
- command,
+ pycompat.rapply(procutil.tonativestr, command),
shell=True,
- cwd='/',
+ cwd=procutil.tonativestr(b'/'),
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
--- a/hgext/fsmonitor/pywatchman/__init__.py Fri Sep 21 21:14:27 2018 -0400
+++ b/hgext/fsmonitor/pywatchman/__init__.py Sun Sep 23 00:47:04 2018 -0400
@@ -48,6 +48,14 @@
except ImportError:
from . import pybser as bser
+from mercurial.utils import (
+ procutil,
+)
+
+from mercurial import (
+ pycompat,
+)
+
from . import (
capabilities,
compat,
@@ -580,7 +588,8 @@
'--no-pretty',
'-j',
]
- self.proc = subprocess.Popen(args,
+ self.proc = subprocess.Popen(pycompat.rapply(procutil.tonativestr,
+ args),
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
return self.proc
@@ -822,7 +831,8 @@
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
args['startupinfo'] = startupinfo
- p = subprocess.Popen(cmd, **args)
+ p = subprocess.Popen(pycompat.rapply(procutil.tonativestr, cmd),
+ **args)
except OSError as e:
raise WatchmanError('"watchman" executable not in PATH (%s)' % e)
--- a/hgext/infinitepush/__init__.py Fri Sep 21 21:14:27 2018 -0400
+++ b/hgext/infinitepush/__init__.py Sun Sep 23 00:47:04 2018 -0400
@@ -1182,5 +1182,6 @@
cmdline = [util.hgexecutable(), 'debugfillinfinitepushmetadata',
'-R', root] + nodesargs
# Process will run in background. We don't care about the return code
- subprocess.Popen(cmdline, close_fds=True, shell=False,
+ subprocess.Popen(pycompat.rapply(procutil.tonativestr, cmdline),
+ close_fds=True, shell=False,
stdin=devnull, stdout=devnull, stderr=devnull)
--- a/hgext/infinitepush/store.py Fri Sep 21 21:14:27 2018 -0400
+++ b/hgext/infinitepush/store.py Sun Sep 23 00:47:04 2018 -0400
@@ -11,6 +11,13 @@
import subprocess
import tempfile
+from mercurial import (
+ pycompat,
+)
+from mercurial.utils import (
+ procutil,
+)
+
NamedTemporaryFile = tempfile.NamedTemporaryFile
class BundleWriteException(Exception):
@@ -111,7 +118,8 @@
def _call_binary(self, args):
p = subprocess.Popen(
- args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ pycompat.rapply(procutil.tonativestr, args),
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE,
close_fds=True)
stdout, stderr = p.communicate()
returncode = p.returncode
--- a/hgext/logtoprocess.py Fri Sep 21 21:14:27 2018 -0400
+++ b/hgext/logtoprocess.py Sun Sep 23 00:47:04 2018 -0400
@@ -44,6 +44,10 @@
pycompat,
)
+from mercurial.utils import (
+ procutil,
+)
+
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
@@ -62,7 +66,8 @@
# we can't use close_fds *and* redirect stdin. I'm not sure that we
# need to because the detached process has no console connection.
subprocess.Popen(
- script, shell=True, env=env, close_fds=True,
+ pycompat.rapply(procutil.tonativestr, script),
+ shell=True, env=procutil.tonativeenv(env), close_fds=True,
creationflags=_creationflags)
else:
def runshellcommand(script, env):
@@ -82,7 +87,9 @@
# connect stdin to devnull to make sure the subprocess can't
# muck up that stream for mercurial.
subprocess.Popen(
- script, shell=True, stdin=open(os.devnull, 'r'), env=env,
+ pycompat.rapply(procutil.tonativestr, script),
+ shell=True, stdin=open(os.devnull, 'r'),
+ env=procutil.tonativeenv(env),
close_fds=True, **newsession)
finally:
# mission accomplished, this child needs to exit and not
--- a/mercurial/debugcommands.py Fri Sep 21 21:14:27 2018 -0400
+++ b/mercurial/debugcommands.py Sun Sep 23 00:47:04 2018 -0400
@@ -3074,7 +3074,8 @@
'-R', repo.root,
'debugserve', '--sshstdio',
]
- proc = subprocess.Popen(args, stdin=subprocess.PIPE,
+ proc = subprocess.Popen(pycompat.rapply(procutil.tonativestr, args),
+ stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
bufsize=0)
--- a/mercurial/scmutil.py Fri Sep 21 21:14:27 2018 -0400
+++ b/mercurial/scmutil.py Sun Sep 23 00:47:04 2018 -0400
@@ -1339,9 +1339,11 @@
if spec.startswith("shell:"):
# external commands should be run relative to the repo root
cmd = spec[6:]
- proc = subprocess.Popen(cmd, shell=True, bufsize=-1,
+ proc = subprocess.Popen(pycompat.rapply(procutil.tonativestr, cmd),
+ shell=True, bufsize=-1,
close_fds=procutil.closefds,
- stdout=subprocess.PIPE, cwd=repo.root)
+ stdout=subprocess.PIPE,
+ cwd=procutil.tonativestr(repo.root))
src = proc.stdout
else:
# treat as a URL or file
--- a/mercurial/subrepo.py Fri Sep 21 21:14:27 2018 -0400
+++ b/mercurial/subrepo.py Sun Sep 23 00:47:04 2018 -0400
@@ -951,9 +951,11 @@
env['LANG'] = lc_all
del env['LC_ALL']
env['LC_MESSAGES'] = 'C'
- p = subprocess.Popen(cmd, bufsize=-1, close_fds=procutil.closefds,
+ p = subprocess.Popen(pycompat.rapply(procutil.tonativestr, cmd),
+ bufsize=-1, close_fds=procutil.closefds,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- universal_newlines=True, env=env, **extrakw)
+ universal_newlines=True,
+ env=procutil.tonativeenv(env), **extrakw)
stdout, stderr = p.communicate()
stderr = stderr.strip()
if not failok:
@@ -1268,8 +1270,12 @@
# insert the argument in the front,
# the end of git diff arguments is used for paths
commands.insert(1, '--color')
- p = subprocess.Popen([self._gitexecutable] + commands, bufsize=-1,
- cwd=cwd, env=env, close_fds=procutil.closefds,
+ p = subprocess.Popen(pycompat.rapply(procutil.tonativestr,
+ [self._gitexecutable] + commands),
+ bufsize=-1,
+ cwd=pycompat.rapply(procutil.tonativestr, cwd),
+ env=procutil.tonativeenv(env),
+ close_fds=procutil.closefds,
stdout=subprocess.PIPE, stderr=errpipe)
if stream:
return p.stdout, None
--- a/mercurial/utils/procutil.py Fri Sep 21 21:14:27 2018 -0400
+++ b/mercurial/utils/procutil.py Sun Sep 23 00:47:04 2018 -0400
@@ -120,13 +120,15 @@
raise error.ProgrammingError('unsupported mode: %r' % mode)
def _popenreader(cmd, bufsize):
- p = subprocess.Popen(quotecommand(cmd), shell=True, bufsize=bufsize,
+ p = subprocess.Popen(tonativestr(quotecommand(cmd)),
+ shell=True, bufsize=bufsize,
close_fds=closefds,
stdout=subprocess.PIPE)
return _pfile(p, p.stdout)
def _popenwriter(cmd, bufsize):
- p = subprocess.Popen(quotecommand(cmd), shell=True, bufsize=bufsize,
+ p = subprocess.Popen(tonativestr(quotecommand(cmd)),
+ shell=True, bufsize=bufsize,
close_fds=closefds,
stdin=subprocess.PIPE)
return _pfile(p, p.stdin)
@@ -135,10 +137,11 @@
# Setting bufsize to -1 lets the system decide the buffer size.
# The default for bufsize is 0, meaning unbuffered. This leads to
# poor performance on Mac OS X: http://bugs.python.org/issue4194
- p = subprocess.Popen(cmd, shell=True, bufsize=-1,
+ p = subprocess.Popen(pycompat.rapply(tonativestr, cmd),
+ shell=True, bufsize=-1,
close_fds=closefds,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- env=env)
+ env=tonativeenv(env))
return p.stdin, p.stdout
def popen3(cmd, env=None):
@@ -146,16 +149,18 @@
return stdin, stdout, stderr
def popen4(cmd, env=None, bufsize=-1):
- p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
+ p = subprocess.Popen(pycompat.rapply(tonativestr, cmd),
+ shell=True, bufsize=bufsize,
close_fds=closefds,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
- env=env)
+ env=tonativeenv(env))
return p.stdin, p.stdout, p.stderr, p
def pipefilter(s, cmd):
'''filter string S through command CMD, returning its output'''
- p = subprocess.Popen(cmd, shell=True, close_fds=closefds,
+ p = subprocess.Popen(pycompat.rapply(tonativestr, cmd),
+ shell=True, close_fds=closefds,
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
pout, perr = p.communicate(s)
return pout
@@ -346,11 +351,16 @@
cmd = quotecommand(cmd)
env = shellenviron(environ)
if out is None or isstdout(out):
- rc = subprocess.call(cmd, shell=True, close_fds=closefds,
- env=env, cwd=cwd)
+ rc = subprocess.call(pycompat.rapply(tonativestr, cmd),
+ shell=True, close_fds=closefds,
+ env=tonativeenv(env),
+ cwd=pycompat.rapply(tonativestr, cwd))
else:
- proc = subprocess.Popen(cmd, shell=True, close_fds=closefds,
- env=env, cwd=cwd, stdout=subprocess.PIPE,
+ proc = subprocess.Popen(pycompat.rapply(tonativestr, cmd),
+ shell=True, close_fds=closefds,
+ env=tonativeenv(env),
+ cwd=pycompat.rapply(tonativestr, cwd),
+ stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in iter(proc.stdout.readline, ''):
out.write(line)