[PATCH 2 of 2] py3: convert arguments, cwd and env to native strings when spawning subprocess
Matt Harbison
mharbison72 at gmail.com
Sun Sep 23 01:18:53 EDT 2018
# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1537678024 14400
# Sun Sep 23 00:47:04 2018 -0400
# Node ID 422a159f22ec9dda95181c0933a2848ab8a64ba6
# Parent 10b1e61357ac546e70e590cc79889c0889e7bc22
py3: convert arguments, cwd and env to native strings when spawning subprocess
This keeps Windows happy.
diff --git a/hgext/convert/common.py b/hgext/convert/common.py
--- a/hgext/convert/common.py
+++ b/hgext/convert/common.py
@@ -402,7 +402,8 @@ class commandline(object):
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
diff --git a/hgext/convert/gnuarch.py b/hgext/convert/gnuarch.py
--- a/hgext/convert/gnuarch.py
+++ b/hgext/convert/gnuarch.py
@@ -17,6 +17,7 @@ from mercurial.i18n import _
from mercurial import (
encoding,
error,
+ pycompat,
)
from mercurial.utils import (
dateutil,
@@ -201,7 +202,7 @@ class gnuarch_source(common.converter_so
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)
diff --git a/hgext/factotum.py b/hgext/factotum.py
--- a/hgext/factotum.py
+++ b/hgext/factotum.py
@@ -49,6 +49,9 @@ from __future__ import absolute_import
import os
from mercurial.i18n import _
+from mercurial.utils import (
+ procutil,
+)
from mercurial import (
error,
httpconnection,
@@ -83,7 +86,7 @@ def auth_getkey(self, params):
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
diff --git a/hgext/fix.py b/hgext/fix.py
--- a/hgext/fix.py
+++ b/hgext/fix.py
@@ -58,6 +58,10 @@ from mercurial.i18n import _
from mercurial.node import nullrev
from mercurial.node import wdirrev
+from mercurial.utils import (
+ procutil,
+)
+
from mercurial import (
cmdutil,
context,
@@ -448,9 +452,9 @@ def fixfile(ui, opts, fixers, fixctx, pa
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)
diff --git a/hgext/fsmonitor/pywatchman/__init__.py b/hgext/fsmonitor/pywatchman/__init__.py
--- a/hgext/fsmonitor/pywatchman/__init__.py
+++ b/hgext/fsmonitor/pywatchman/__init__.py
@@ -48,6 +48,14 @@ try:
except ImportError:
from . import pybser as bser
+from mercurial.utils import (
+ procutil,
+)
+
+from mercurial import (
+ pycompat,
+)
+
from . import (
capabilities,
compat,
@@ -580,7 +588,8 @@ class CLIProcessTransport(Transport):
'--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 @@ class client(object):
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)
diff --git a/hgext/infinitepush/__init__.py b/hgext/infinitepush/__init__.py
--- a/hgext/infinitepush/__init__.py
+++ b/hgext/infinitepush/__init__.py
@@ -1182,5 +1182,6 @@ def _asyncsavemetadata(root, nodes):
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)
diff --git a/hgext/infinitepush/store.py b/hgext/infinitepush/store.py
--- a/hgext/infinitepush/store.py
+++ b/hgext/infinitepush/store.py
@@ -111,7 +111,8 @@ class externalbundlestore(abstractbundle
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
diff --git a/hgext/logtoprocess.py b/hgext/logtoprocess.py
--- a/hgext/logtoprocess.py
+++ b/hgext/logtoprocess.py
@@ -44,6 +44,10 @@ from mercurial import (
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 @@ def uisetup(ui):
# 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 @@ def uisetup(ui):
# 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
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -3074,7 +3074,8 @@ def debugwireproto(ui, repo, path=None,
'-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)
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -1339,9 +1339,11 @@ def extdatasource(repo, source):
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
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -951,9 +951,11 @@ class svnsubrepo(abstractsubrepo):
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 @@ class gitsubrepo(abstractsubrepo):
# 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=procutil.tonativestr(cwd),
+ env=procutil.tonativeenv(env),
+ close_fds=procutil.closefds,
stdout=subprocess.PIPE, stderr=errpipe)
if stream:
return p.stdout, None
diff --git a/mercurial/utils/procutil.py b/mercurial/utils/procutil.py
--- a/mercurial/utils/procutil.py
+++ b/mercurial/utils/procutil.py
@@ -120,13 +120,15 @@ def popen(cmd, mode='rb', bufsize=-1):
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 @@ def popen2(cmd, env=None):
# 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 @@ def popen3(cmd, env=None):
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,14 @@ def system(cmd, environ=None, cwd=None,
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=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=tonativestr(cwd),
+ stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in iter(proc.stdout.readline, ''):
out.write(line)
More information about the Mercurial-devel
mailing list