use subprocess run

The usage of subprocess.run is recommended since python 3.5.
Popen, check_call, call and check_output calls were replaced with run.
This commit is contained in:
Gyorgy Orban 2017-10-23 11:22:56 +02:00
parent 385337eb90
commit bb54a954fe
21 changed files with 105 additions and 91 deletions

View File

@ -660,9 +660,9 @@ class Quitter:
try:
args, cwd = self._get_restart_args(pages, session, override_args)
if cwd is None:
subprocess.Popen(args)
subprocess.run(args)
else:
subprocess.Popen(args, cwd=cwd)
subprocess.run(args, cwd=cwd)
except OSError:
log.destroy.exception("Failed to restart")
return False

View File

@ -151,12 +151,14 @@ def _git_str_subprocess(gitpath):
return None
try:
# https://stackoverflow.com/questions/21017300/21017394#21017394
commit_hash = subprocess.check_output(
commit_hash = subprocess.run(
['git', 'describe', '--match=NeVeRmAtCh', '--always', '--dirty'],
cwd=gitpath).decode('UTF-8').strip()
date = subprocess.check_output(
cwd=gitpath, check=True,
stdout=subprocess.PIPE).stdout.decode('UTF-8').strip()
date = subprocess.run(
['git', 'show', '-s', '--format=%ci', 'HEAD'],
cwd=gitpath).decode('UTF-8').strip()
cwd=gitpath, check=True,
stdout=subprocess.PIPE).stdout.decode('UTF-8').strip()
return '{} ({})'.format(commit_hash, date)
except (subprocess.CalledProcessError, OSError):
return None

View File

@ -224,16 +224,16 @@ class AsciiDoc:
return self._args.asciidoc
try:
subprocess.call(['asciidoc'], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
subprocess.run(['asciidoc'], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
except OSError:
pass
else:
return ['asciidoc']
try:
subprocess.call(['asciidoc.py'], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
subprocess.run(['asciidoc.py'], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
except OSError:
pass
else:
@ -258,7 +258,7 @@ class AsciiDoc:
try:
env = os.environ.copy()
env['HOME'] = self._homedir
subprocess.check_call(cmdline, env=env)
subprocess.run(cmdline, check=True, env=env)
except (subprocess.CalledProcessError, OSError) as e:
self._failed = True
utils.print_col(str(e), 'red')

View File

@ -50,7 +50,7 @@ def call_script(name, *args, python=sys.executable):
python: The python interpreter to use.
"""
path = os.path.join(os.path.dirname(__file__), os.pardir, name)
subprocess.check_call([python, path] + list(args))
subprocess.run([python, path] + list(args), check=True)
def call_tox(toxenv, *args, python=sys.executable):
@ -64,9 +64,9 @@ def call_tox(toxenv, *args, python=sys.executable):
env = os.environ.copy()
env['PYTHON'] = python
env['PATH'] = os.environ['PATH'] + os.pathsep + os.path.dirname(python)
subprocess.check_call(
subprocess.run(
[sys.executable, '-m', 'tox', '-vv', '-e', toxenv] + list(args),
env=env)
env=env, check=True)
def run_asciidoc2html(args):
@ -89,8 +89,9 @@ def _maybe_remove(path):
def smoke_test(executable):
"""Try starting the given qutebrowser executable."""
subprocess.check_call([executable, '--no-err-windows', '--nowindow',
'--temp-basedir', 'about:blank', ':later 500 quit'])
subprocess.run([executable, '--no-err-windows', '--nowindow',
'--temp-basedir', 'about:blank', ':later 500 quit'],
check=True)
def patch_mac_app():
@ -178,7 +179,7 @@ def build_mac():
utils.print_title("Patching .app")
patch_mac_app()
utils.print_title("Building .dmg")
subprocess.check_call(['make', '-f', 'scripts/dev/Makefile-dmg'])
subprocess.run(['make', '-f', 'scripts/dev/Makefile-dmg'], check=True)
dmg_name = 'qutebrowser-{}.dmg'.format(qutebrowser.__version__)
os.rename('qutebrowser.dmg', dmg_name)
@ -187,14 +188,14 @@ def build_mac():
try:
with tempfile.TemporaryDirectory() as tmpdir:
subprocess.check_call(['hdiutil', 'attach', dmg_name,
'-mountpoint', tmpdir])
subprocess.run(['hdiutil', 'attach', dmg_name,
'-mountpoint', tmpdir], check=True)
try:
binary = os.path.join(tmpdir, 'qutebrowser.app', 'Contents',
'MacOS', 'qutebrowser')
smoke_test(binary)
finally:
subprocess.call(['hdiutil', 'detach', tmpdir])
subprocess.run(['hdiutil', 'detach', tmpdir])
except PermissionError as e:
print("Failed to remove tempdir: {}".format(e))
@ -242,13 +243,13 @@ def build_windows():
patch_windows(out_64)
utils.print_title("Building installers")
subprocess.check_call(['makensis.exe',
'/DVERSION={}'.format(qutebrowser.__version__),
'misc/qutebrowser.nsi'])
subprocess.check_call(['makensis.exe',
'/DX64',
'/DVERSION={}'.format(qutebrowser.__version__),
'misc/qutebrowser.nsi'])
subprocess.run(['makensis.exe',
'/DVERSION={}'.format(qutebrowser.__version__),
'misc/qutebrowser.nsi'], check=True)
subprocess.run(['makensis.exe',
'/DX64',
'/DVERSION={}'.format(qutebrowser.__version__),
'misc/qutebrowser.nsi'], check=True)
name_32 = 'qutebrowser-{}-win32.exe'.format(qutebrowser.__version__)
name_64 = 'qutebrowser-{}-amd64.exe'.format(qutebrowser.__version__)
@ -292,12 +293,12 @@ def build_sdist():
_maybe_remove('dist')
subprocess.check_call([sys.executable, 'setup.py', 'sdist'])
subprocess.run([sys.executable, 'setup.py', 'sdist'], check=True)
dist_files = os.listdir(os.path.abspath('dist'))
assert len(dist_files) == 1
dist_file = os.path.join('dist', dist_files[0])
subprocess.check_call(['gpg', '--detach-sign', '-a', dist_file])
subprocess.run(['gpg', '--detach-sign', '-a', dist_file], check=True)
tar = tarfile.open(dist_file)
by_ext = collections.defaultdict(list)
@ -366,7 +367,7 @@ def github_upload(artifacts, tag):
def pypi_upload(artifacts):
"""Upload the given artifacts to PyPI using twine."""
filenames = [a[0] for a in artifacts]
subprocess.check_call(['twine', 'upload'] + filenames)
subprocess.run(['twine', 'upload'] + filenames, check=True)
def main():

View File

@ -285,8 +285,8 @@ def main_check():
print(msg.text)
print()
filters = ','.join('qutebrowser/' + msg.filename for msg in messages)
subprocess.check_call([sys.executable, '-m', 'coverage', 'report',
'--show-missing', '--include', filters])
subprocess.run([sys.executable, '-m', 'coverage', 'report',
'--show-missing', '--include', filters], check=True)
print()
print("To debug this, run 'tox -e py36-pyqt59-cov' "
"(or py35-pyqt59-cov) locally and check htmlcov/index.html")
@ -312,9 +312,9 @@ def main_check_all():
for test_file, src_file in PERFECT_FILES:
if test_file is None:
continue
subprocess.check_call(
subprocess.run(
[sys.executable, '-m', 'pytest', '--cov', 'qutebrowser',
'--cov-report', 'xml', test_file])
'--cov-report', 'xml', test_file], check=True)
with open('coverage.xml', encoding='utf-8') as f:
messages = check(f, [(test_file, src_file)])
os.remove('coverage.xml')

View File

@ -24,7 +24,8 @@ import sys
import subprocess
import os
code = subprocess.call(['git', '--no-pager', 'diff', '--exit-code', '--stat'])
code = subprocess.run(['git', '--no-pager', 'diff',
'--exit-code', '--stat']).returncode
if os.environ.get('TRAVIS_PULL_REQUEST', 'false') != 'false':
if code != 0:
@ -42,6 +43,6 @@ if code != 0:
if 'TRAVIS' in os.environ:
print()
print("travis_fold:start:gitdiff")
subprocess.call(['git', '--no-pager', 'diff'])
subprocess.run(['git', '--no-pager', 'diff'])
print("travis_fold:end:gitdiff")
sys.exit(code)

View File

@ -23,4 +23,4 @@
import subprocess
with open('qutebrowser/resources.py', 'w', encoding='utf-8') as f:
subprocess.check_call(['pyrcc5', 'qutebrowser.rcc'], stdout=f)
subprocess.run(['pyrcc5', 'qutebrowser.rcc'], stdout=f, check=True)

View File

@ -84,7 +84,8 @@ def parse_coredumpctl_line(line):
def get_info(pid):
"""Get and parse "coredumpctl info" output for the given PID."""
data = {}
output = subprocess.check_output(['coredumpctl', 'info', str(pid)])
output = subprocess.run(['coredumpctl', 'info', str(pid)], check=True,
stdout=subprocess.PIPE).stdout
output = output.decode('utf-8')
for line in output.split('\n'):
if not line.strip():
@ -117,12 +118,12 @@ def dump_infos_gdb(parsed):
"""Dump all needed infos for the given crash using gdb."""
with tempfile.TemporaryDirectory() as tempdir:
coredump = os.path.join(tempdir, 'dump')
subprocess.check_call(['coredumpctl', 'dump', '-o', coredump,
str(parsed.pid)])
subprocess.check_call(['gdb', parsed.exe, coredump,
'-ex', 'info threads',
'-ex', 'thread apply all bt full',
'-ex', 'quit'])
subprocess.run(['coredumpctl', 'dump', '-o', coredump,
str(parsed.pid)], check=True)
subprocess.run(['gdb', parsed.exe, coredump,
'-ex', 'info threads',
'-ex', 'thread apply all bt full',
'-ex', 'quit'], check=True)
def dump_infos(parsed):
@ -143,7 +144,7 @@ def check_prerequisites():
"""Check if coredumpctl/gdb are installed."""
for binary in ['coredumpctl', 'gdb']:
try:
subprocess.check_call([binary, '--version'])
subprocess.run([binary, '--version'], check=True)
except FileNotFoundError:
print("{} is needed to run this script!".format(binary),
file=sys.stderr)
@ -158,7 +159,8 @@ def main():
action='store_true')
args = parser.parse_args()
coredumps = subprocess.check_output(['coredumpctl', 'list'])
coredumps = subprocess.run(['coredumpctl', 'list'], check=True,
stdout=subprocess.PIPE).stdout
lines = coredumps.decode('utf-8').split('\n')
for line in lines[1:]:
if not line.strip():

View File

@ -62,7 +62,8 @@ def check_git():
print()
return False
untracked = []
gitst = subprocess.check_output(['git', 'status', '--porcelain'])
gitst = subprocess.run(['git', 'status', '--porcelain'], check=True,
stdout=subprocess.PIPE).stdout
gitst = gitst.decode('UTF-8').strip()
for line in gitst.splitlines():
s, name = line.split(maxsplit=1)

View File

@ -116,9 +116,11 @@ def main():
with tempfile.TemporaryDirectory() as tmpdir:
pip_bin = os.path.join(tmpdir, 'bin', 'pip')
subprocess.check_call(['virtualenv', tmpdir])
subprocess.check_call([pip_bin, 'install', '-r', filename])
reqs = subprocess.check_output([pip_bin, 'freeze']).decode('utf-8')
subprocess.run(['virtualenv', tmpdir], check=True)
subprocess.run([pip_bin, 'install', '-r', filename], check=True)
reqs = subprocess.run([pip_bin, 'freeze'], check=True,
stdout=subprocess.PIPE
).stdout.decode('utf-8')
with open(filename, 'r', encoding='utf-8') as f:
comments = read_comments(f)

View File

@ -76,14 +76,15 @@ def main():
pass
elif args.profile_tool == 'gprof2dot':
# yep, shell=True. I know what I'm doing.
subprocess.call('gprof2dot -f pstats {} | dot -Tpng | feh -F -'.format(
shlex.quote(profilefile)), shell=True)
subprocess.run(
'gprof2dot -f pstats {} | dot -Tpng | feh -F -'.format(
shlex.quote(profilefile)), shell=True)
elif args.profile_tool == 'kcachegrind':
callgraphfile = os.path.join(tempdir, 'callgraph')
subprocess.call(['pyprof2calltree', '-k', '-i', profilefile,
'-o', callgraphfile])
subprocess.run(['pyprof2calltree', '-k', '-i', profilefile,
'-o', callgraphfile])
elif args.profile_tool == 'snakeviz':
subprocess.call(['snakeviz', profilefile])
subprocess.run(['snakeviz', profilefile])
shutil.rmtree(tempdir)

View File

@ -73,7 +73,7 @@ def main():
env = os.environ.copy()
env['PYTHONPATH'] = os.pathsep.join(pythonpath)
ret = subprocess.call(['pylint'] + args, env=env)
ret = subprocess.run(['pylint'] + args, env=env).returncode
return ret

View File

@ -92,22 +92,22 @@ def main():
utils.print_bold("==== {} ====".format(page))
if test_harfbuzz:
print("With system harfbuzz:")
ret = subprocess.call([sys.executable, '-c', SCRIPT, page])
ret = subprocess.run([sys.executable, '-c', SCRIPT, page]).returncode
print_ret(ret)
retvals.append(ret)
if test_harfbuzz:
print("With QT_HARFBUZZ=old:")
env = dict(os.environ)
env['QT_HARFBUZZ'] = 'old'
ret = subprocess.call([sys.executable, '-c', SCRIPT, page],
env=env)
ret = subprocess.run([sys.executable, '-c', SCRIPT, page],
env=env).returncode
print_ret(ret)
retvals.append(ret)
print("With QT_HARFBUZZ=new:")
env = dict(os.environ)
env['QT_HARFBUZZ'] = 'new'
ret = subprocess.call([sys.executable, '-c', SCRIPT, page],
env=env)
ret = subprocess.run([sys.executable, '-c', SCRIPT, page],
env=env).returncode
print_ret(ret)
retvals.append(ret)
if all(r == 0 for r in retvals):

View File

@ -529,9 +529,9 @@ def regenerate_cheatsheet():
]
for filename, x, y in files:
subprocess.check_call(['inkscape', '-e', filename, '-b', 'white',
'-w', str(x), '-h', str(y),
'misc/cheatsheet.svg'])
subprocess.run(['inkscape', '-e', filename, '-b', 'white',
'-w', str(x), '-h', str(y),
'misc/cheatsheet.svg'], check=True)
def main():

View File

@ -46,12 +46,14 @@ def run_py(executable, *code):
f.write('\n'.join(code))
cmd = [executable, filename]
try:
ret = subprocess.check_output(cmd, universal_newlines=True)
ret = subprocess.run(cmd, universal_newlines=True, check=True,
stdout=subprocess.PIPE).stdout
finally:
os.remove(filename)
else:
cmd = [executable, '-c', '\n'.join(code)]
ret = subprocess.check_output(cmd, universal_newlines=True)
ret = subprocess.run(cmd, universal_newlines=True, check=True,
stdout=subprocess.PIPE).stdout
return ret.rstrip()

View File

@ -51,12 +51,14 @@ def _git_str():
return None
try:
# https://stackoverflow.com/questions/21017300/21017394#21017394
commit_hash = subprocess.check_output(
commit_hash = subprocess.run(
['git', 'describe', '--match=NeVeRmAtCh', '--always', '--dirty'],
cwd=BASEDIR).decode('UTF-8').strip()
date = subprocess.check_output(
cwd=BASEDIR, check=True,
stdout=subprocess.PIPE).stdout.decode('UTF-8').strip()
date = subprocess.run(
['git', 'show', '-s', '--format=%ci', 'HEAD'],
cwd=BASEDIR).decode('UTF-8').strip()
cwd=BASEDIR, check=True,
stdout=subprocess.PIPE).stdout.decode('UTF-8').strip()
return '{} ({})'.format(commit_hash, date)
except (subprocess.CalledProcessError, OSError):
return None

View File

@ -47,10 +47,10 @@ def update_documentation():
return
try:
subprocess.call(['asciidoc'], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
subprocess.run(['asciidoc'], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
except OSError:
pytest.skip("Docs outdated and asciidoc unavailable!")
update_script = os.path.join(script_path, 'asciidoc2html.py')
subprocess.call([sys.executable, update_script])
subprocess.run([sys.executable, update_script])

View File

@ -259,14 +259,13 @@ def test_command_on_start(request, quteproc_new):
def test_launching_with_python2():
try:
proc = subprocess.Popen(['python2', '-m', 'qutebrowser',
'--no-err-windows'], stderr=subprocess.PIPE)
proc = subprocess.run(['python2', '-m', 'qutebrowser',
'--no-err-windows'], stderr=subprocess.PIPE)
except FileNotFoundError:
pytest.skip("python2 not found")
_stdout, stderr = proc.communicate()
assert proc.returncode == 1
error = "At least Python 3.5 is required to run qutebrowser"
assert stderr.decode('ascii').startswith(error)
assert proc.stderr.decode('ascii').startswith(error)
def test_initial_private_browsing(request, quteproc_new):

View File

@ -36,15 +36,14 @@ TEXT = (r"At least Python 3.5 is required to run qutebrowser, but it's "
def test_python2():
"""Run checkpyver with python 2."""
try:
proc = subprocess.Popen(
proc = subprocess.run(
['python2', checkpyver.__file__, '--no-err-windows'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
except FileNotFoundError:
pytest.skip("python2 not found")
assert not stdout
stderr = stderr.decode('utf-8')
assert not proc.stdout
stderr = proc.stderr.decode('utf-8')
assert re.match(TEXT, stderr), stderr
assert proc.returncode == 1

View File

@ -555,8 +555,9 @@ def test_no_qapplication(qapp, tmpdir):
pyfile = tmpdir / 'sub.py'
pyfile.write_text(textwrap.dedent(sub_code), encoding='ascii')
output = subprocess.check_output([sys.executable, str(pyfile)] + sys.path,
universal_newlines=True)
output = subprocess.run([sys.executable, str(pyfile)] + sys.path,
universal_newlines=True,
check=True, stdout=subprocess.PIPE).stdout
sub_locations = json.loads(output)
standarddir._init_dirs()

View File

@ -299,8 +299,8 @@ class TestGitStr:
def _has_git():
"""Check if git is installed."""
try:
subprocess.check_call(['git', '--version'], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
subprocess.run(['git', '--version'], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL, check=True)
except (OSError, subprocess.CalledProcessError):
return False
else:
@ -337,12 +337,13 @@ class TestGitStrSubprocess:
# If we don't call this with shell=True it might fail under
# some environments on Windows...
# http://bugs.python.org/issue24493
subprocess.check_call(
subprocess.run(
'git -C "{}" {}'.format(tmpdir, ' '.join(args)),
env=env, shell=True)
env=env, check=True, shell=True)
else:
subprocess.check_call(
['git', '-C', str(tmpdir)] + list(args), env=env)
subprocess.run(
['git', '-C', str(tmpdir)] + list(args),
check=True, env=env)
(tmpdir / 'file').write_text("Hello World!", encoding='utf-8')
_git('init')
@ -368,14 +369,14 @@ class TestGitStrSubprocess:
subprocess.CalledProcessError(1, 'foobar')
])
def test_exception(self, exc, mocker, tmpdir):
"""Test with subprocess.check_output raising an exception.
"""Test with subprocess.run raising an exception.
Args:
exc: The exception to raise.
"""
m = mocker.patch('qutebrowser.utils.version.os')
m.path.isdir.return_value = True
mocker.patch('qutebrowser.utils.version.subprocess.check_output',
mocker.patch('qutebrowser.utils.version.subprocess.run',
side_effect=exc)
ret = version._git_str_subprocess(str(tmpdir))
assert ret is None