Skip to content
Snippets Groups Projects
Commit 3080d5f3 authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

Merge branch 'mnt/run-silent' into 'main'

MNT: New 'silent' option to run function

See merge request fsl/fslpy!428
parents a5260424 b04a7ee8
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,17 @@ This document contains the ``fslpy`` release history in reverse chronological
order.
3.16.0 (Under development)
--------------------------
Added
^^^^^
* New `silent` option to the :func:`.run` function = passing ``silent=True`` is
equivalent to passing ``log={'tee':False}`` (!428).
3.15.3 (Thursday 16th November 2023)
------------------------------------
......
......@@ -20,7 +20,6 @@ import pytest
import fsl.utils.tempdir as tempdir
from fsl.utils.platform import platform as fslplatform
import fsl.utils.run as run
import fsl.utils.fslsub as fslsub
from . import make_random_image, mockFSLDIR, CaptureStdout, touch
......@@ -138,6 +137,13 @@ def test_run_tee():
assert stdout == expstdout
assert capture.stdout == ''
# disable forwarding via silent=True
with capture.reset():
stdout = run.run('./script.sh 1 2 3', silent=True)
assert stdout == expstdout
assert capture.stdout == ''
with capture.reset():
stdout, stderr = run.run('./script.sh 1 2 3', stderr=True,
log={'tee' : True})
......@@ -289,6 +295,8 @@ def mock_fsl_sub(*cmd, **kwargs):
name = op.basename(name)
kwargs.pop('log', None)
jid = '12345'
output = run.run(cmd)
......@@ -323,7 +331,7 @@ def test_run_submit():
jid = run.run('fsltest', submit=True)
assert jid == '12345'
stdout, stderr = fslsub.output(jid)
stdout, stderr = run.job_output(jid)
assert stdout == 'test_script running\n'
assert stderr == ''
......@@ -331,7 +339,7 @@ def test_run_submit():
kwargs = {'name' : 'abcde', 'ram' : '4GB'}
jid = run.run('fsltest', submit=kwargs)
assert jid == '12345'
stdout, stderr = fslsub.output(jid)
stdout, stderr = run.job_output(jid)
experr = '\n'.join(['{}: {}'.format(k, kwargs[k])
for k in sorted(kwargs.keys())]) + '\n'
assert stdout == 'test_script running\n'
......@@ -341,7 +349,7 @@ def test_run_submit():
kwargs = {'name' : 'abcde', 'ram' : '4GB'}
jid = run.run('fsltest', submit=True, **kwargs)
assert jid == '12345'
stdout, stderr = fslsub.output(jid)
stdout, stderr = run.job_output(jid)
experr = '\n'.join(['{}: {}'.format(k, kwargs[k])
for k in sorted(kwargs.keys())]) + '\n'
assert stdout == 'test_script running\n'
......@@ -482,7 +490,7 @@ def test_func_to_cmd():
for tmp_dir in (None, '.'):
for clean in ('never', 'on_success', 'always'):
for verbose in (False, True):
cmd = fslsub.func_to_cmd(_good_func, clean=clean, tmp_dir=tmp_dir, verbose=verbose)
cmd = run.func_to_cmd(_good_func, clean=clean, tmp_dir=tmp_dir, verbose=verbose)
fn = cmd.split()[-1]
assert op.exists(fn)
stdout, stderr, exitcode = run.run(cmd, exitcode=True, stdout=True, stderr=True,
......@@ -497,7 +505,7 @@ def test_func_to_cmd():
else:
assert stdout.strip() == 'hello'
cmd = fslsub.func_to_cmd(_bad_func, clean=clean, tmp_dir=tmp_dir)
cmd = run.func_to_cmd(_bad_func, clean=clean, tmp_dir=tmp_dir)
fn = cmd.split()[-1]
assert op.exists(fn)
stdout, stderr, exitcode = run.run(cmd, exitcode=True, stdout=True, stderr=True,
......
......@@ -188,6 +188,9 @@ def run(*args, **kwargs):
- cmd: Optional file-like or callable to which
the command itself is logged.
:arg silent: Suppress standard output/error. Equivalent to passing
``log={'tee' : False}``. Ignored if `log` is also passed.
All other keyword arguments are passed through to the ``subprocess.Popen``
object (via :func:`_realrun`), unless ``submit=True``, in which case they
are passed through to the :func:`.fsl_sub` function.
......@@ -204,10 +207,11 @@ def run(*args, **kwargs):
submit = kwargs.pop('submit', {})
cmdonly = kwargs.pop('cmdonly', False)
logg = kwargs.pop('log', None)
silent = kwargs.pop('silent', False)
args = prepareArgs(args)
if logg is None:
logg = {}
logg = {'tee' : not silent}
tee = logg.get('tee', True)
logStdout = logg.get('stdout', None)
......@@ -237,7 +241,7 @@ def run(*args, **kwargs):
# but harmless, as we've popped the "submit" arg above.
if submit is not None:
from fsl.wrappers import fsl_sub # pylint: disable=import-outside-toplevel # noqa: E501
return fsl_sub(*args, **submit, **kwargs)[0].strip()
return fsl_sub(*args, log=logg, **submit, **kwargs)[0].strip()
# Run directly - delegate to _realrun
stdout, stderr, exitcode = _realrun(
......@@ -633,10 +637,10 @@ def hold(job_ids, hold_filename=None, timeout=10):
submit = {
'jobhold' : _flatten_job_ids(job_ids),
'jobtime' : 1,
'name' : '.hold'
'name' : '.hold',
}
run(f'touch {hold_filename}', submit=submit)
run(f'touch {hold_filename}', submit=submit, silent=True)
while not op.exists(hold_filename):
time.sleep(timeout)
......
......@@ -193,7 +193,16 @@ def genxwrapper(func, runner, funccmd=False):
exitcode = kwargs.pop('exitcode', opts['exitcode'])
submit = kwargs.pop('submit', opts['submit'])
cmdonly = kwargs.pop('cmdonly', opts['cmdonly'])
logg = kwargs.pop('log', opts['log'])
silent = kwargs.pop('silent', False)
# If silent=True, we need to explicitly set
# log, as the run function will otherwise
# ignore silent and preferentially use the
# value we pass for log.
if silent:
logg = kwargs.pop('log', {'tee' : False})
else:
logg = kwargs.pop('log', opts['log'])
if funccmd:
cmd = run.func_to_cmd(func, args=args, kwargs=kwargs,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment