Commit 4ef642f3 authored by Paul McCarthy's avatar Paul McCarthy 🚵
Browse files

Merge branch 'bf/wrapper-tempfile' into 'master'

Bf/wrapper tempfile

See merge request fsl/fslpy!313
parents a55a39e0 03e8261d
Pipeline #11473 failed with stages
in 10 seconds
...@@ -171,10 +171,10 @@ test:3.9: ...@@ -171,10 +171,10 @@ test:3.9:
<<: *test_template <<: *test_template
test:3.10: # test:3.10:
stage: test # stage: test
image: pauldmccarthy/fsleyes-py310-wxpy4-gtk3 # image: pauldmccarthy/fsleyes-py310-wxpy4-gtk3
<<: *test_template # <<: *test_template
test:build-pypi-dist: test:build-pypi-dist:
......
...@@ -2,8 +2,8 @@ This document contains the ``fslpy`` release history in reverse chronological ...@@ -2,8 +2,8 @@ This document contains the ``fslpy`` release history in reverse chronological
order. order.
3.8.0 (Under development) 3.7.1 (Friday 12th November 2021)
------------------------- ---------------------------------
Changed Changed
...@@ -11,7 +11,15 @@ Changed ...@@ -11,7 +11,15 @@ Changed
* BIDS and ``dcm2niix`` ``.json`` sidecar files with control characters * BIDS and ``dcm2niix`` ``.json`` sidecar files with control characters
are now accepted. are now accepted (!312).
Fixed
^^^^^
* Fixed an issue with temporary input files created by :mod:`fsl.wrappers`
functions not being deleted (!313).
3.7.0 (Friday 20th August 2021) 3.7.0 (Friday 20th August 2021)
...@@ -23,7 +31,7 @@ Added ...@@ -23,7 +31,7 @@ Added
* New :mod:`fsl.wrappers.fsl_sub` wrapper function for the ``fsl_sub`` * New :mod:`fsl.wrappers.fsl_sub` wrapper function for the ``fsl_sub``
command. command (!309).
Changed Changed
...@@ -32,19 +40,19 @@ Changed ...@@ -32,19 +40,19 @@ Changed
* Performance of the :mod:`.imglob`, :mod:`.imln`, :mod:`imtest`, :mod:`.imrm` * Performance of the :mod:`.imglob`, :mod:`.imln`, :mod:`imtest`, :mod:`.imrm`
and :mod:`.remove_ext` scripts has been improved, by re-organising them to and :mod:`.remove_ext` scripts has been improved, by re-organising them to
avoid unnecessary and expensive imports such as ``numpy``. avoid unnecessary and expensive imports such as ``numpy`` (!310).
* The default behaviour of the :func:`fsl.utils.run.run` function (and hence * The default behaviour of the :func:`fsl.utils.run.run` function (and hence
that of all :mod:`fsl.wrappers` functions) has been changed so that the that of all :mod:`fsl.wrappers` functions) has been changed so that the
standard output and error of the called command is now forwarded to the standard output and error of the called command is now forwarded to the
calling Python process, in addition to being returned from ``run`` as calling Python process, in addition to being returned from ``run`` as
strings. In other words, the default behaviour of ``run('cmd')``, is now strings. In other words, the default behaviour of ``run('cmd')``, is now
equivalent to ``run('cmd', log={"tee":True})``. The previous default equivalent to ``run('cmd', log={"tee":True})``. The previous default
behaviour can be achieved with ``run('cmd', log={"tee":False})``. behaviour can be achieved with ``run('cmd', log={"tee":False})`` (!309).
* The :func:`fsl.utils.run.run` and :func:`fsl.utils.run.runfsl` functions * The :func:`fsl.utils.run.run` and :func:`fsl.utils.run.runfsl` functions
(and hence all :mod:`fsl.wrappers` functions) have been modified to use (and hence all :mod:`fsl.wrappers` functions) have been modified to use
``fsl.wrappers.fsl_sub`` instead of ``fsl.utils.fslsub.submit``. This is an ``fsl.wrappers.fsl_sub`` instead of ``fsl.utils.fslsub.submit``. This is an
internal change which should not affect the usage of the ``run``, ``runfsl`` internal change which should not affect the usage of the ``run``, ``runfsl``
or wrapper functions. or wrapper functions (!309).
Deprecated Deprecated
...@@ -53,10 +61,10 @@ Deprecated ...@@ -53,10 +61,10 @@ Deprecated
* :class:`fsl.utils.fslsub.SubmitParams` and :func:`fsl.utils.fslsub.submit` * :class:`fsl.utils.fslsub.SubmitParams` and :func:`fsl.utils.fslsub.submit`
have been deprecated in favour of using the ``fsl.wrappers.fsl_sub`` wrapper have been deprecated in favour of using the ``fsl.wrappers.fsl_sub`` wrapper
function. function (!309).
* The :func:`fsl.utils.fslsub.info` function has been deprecated in favour of * The :func:`fsl.utils.fslsub.info` function has been deprecated in favour of
using the ``fsl_sub.report`` function, from the separate `fsl_sub using the ``fsl_sub.report`` function, from the separate `fsl_sub
<https://git.fmrib.ox.ac.uk/fsl/fsl_sub>`_ Python library. <https://git.fmrib.ox.ac.uk/fsl/fsl_sub>`_ Python library (!309).
3.6.4 (Tuesday 3rd August 2021) 3.6.4 (Tuesday 3rd August 2021)
......
...@@ -1046,9 +1046,16 @@ def fileOrImage(*args, **kwargs): ...@@ -1046,9 +1046,16 @@ def fileOrImage(*args, **kwargs):
# in-memory image - we have # in-memory image - we have
# to save it out to a file # to save it out to a file
if infile is None: if infile is None or not op.exists(infile):
hd, infile = tempfile.mkstemp(fslimage.defaultExt()) hd, infile = tempfile.mkstemp(fslimage.defaultExt(),
dir=workdir)
os.close(hd) os.close(hd)
# Create a copy of the input image and
# save that, so the original doesn't
# get associated with the temp file
val = nib.nifti1.Nifti1Image(
np.asanyarray(val.dataobj), None, val.header)
val.to_filename(infile) val.to_filename(infile)
return infile return infile
...@@ -1110,7 +1117,7 @@ def fileOrArray(*args, **kwargs): ...@@ -1110,7 +1117,7 @@ def fileOrArray(*args, **kwargs):
infile = None infile = None
if isinstance(val, np.ndarray): if isinstance(val, np.ndarray):
hd, infile = tempfile.mkstemp('.txt') hd, infile = tempfile.mkstemp('.txt', dir=workdir)
os.close(hd) os.close(hd)
np.savetxt(infile, val, fmt='%0.18f') np.savetxt(infile, val, fmt='%0.18f')
...@@ -1176,6 +1183,7 @@ def fileOrText(*args, **kwargs): ...@@ -1176,6 +1183,7 @@ def fileOrText(*args, **kwargs):
if not isinstance(val, pathlib.Path): if not isinstance(val, pathlib.Path):
with tempfile.NamedTemporaryFile(mode='w', with tempfile.NamedTemporaryFile(mode='w',
suffix='.txt', suffix='.txt',
dir=workdir,
delete=False) as f: delete=False) as f:
f.write(val) f.write(val)
infile = f.name infile = f.name
......
...@@ -876,3 +876,61 @@ def test_cmdwrapper_cmdonly_assert(): ...@@ -876,3 +876,61 @@ def test_cmdwrapper_cmdonly_assert():
assert func()[0].strip() == 'hello' assert func()[0].strip() == 'hello'
os.remove('file') os.remove('file')
assert func(cmdonly=True) == ['echo', 'hello'] assert func(cmdonly=True) == ['echo', 'hello']
def test_fileOrArray_all_tempfiles_cleared():
tempfiles = []
@wutils.fileOrArray('in_', 'out')
def array(in_, out):
tempfiles.extend((in_, out))
i = np.loadtxt(in_)
i = i + 1
np.savetxt(out, i)
arr = np.array([[1, 2], [ 3, 4]])
arrout = array(arr, wutils.LOAD).out
assert np.all(np.isclose(arrout, arr + 1))
assert len(tempfiles) == 2
assert not any(op.exists(f) for f in tempfiles)
def test_fileOrImage_all_tempfiles_cleared():
tempfiles = []
@wutils.fileOrImage('in_', 'out')
def image(in_, out):
tempfiles.extend((in_, out))
i = nib.load(in_)
i = nib.Nifti1Image(i.get_fdata() + 1, np.eye(4))
i.to_filename(out)
arr = np.array([[1, 2], [ 3, 4]])
img = nib.nifti1.Nifti1Image(arr, np.eye(4))
imgout = image(img, wutils.LOAD).out
assert np.all(np.isclose(imgout.get_fdata(), img.get_fdata() + 1))
assert len(tempfiles) == 2
assert not any(op.exists(f) for f in tempfiles)
def test_fileOrText_all_tempfiles_cleared():
tempfiles = []
@wutils.fileOrText('in_', 'out')
def text(in_, out):
tempfiles.extend((in_, out))
with open(in_, 'rt') as inf, open(out, 'wt') as outf:
outf.write(inf.read())
outf.write('456')
txt = '123'
txtout = text( txt, wutils.LOAD).out
assert txtout == '123456'
assert len(tempfiles) == 2
assert not any(op.exists(f) for f in tempfiles)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment