From 63b55864ff61b96b569e4234f3a2fb53b4094798 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Mon, 2 Jan 2023 20:45:50 -0500 Subject: [PATCH 1/3] RF: Deprecate tmpdirs.TemporaryDirectory, duplicate of tempfile.TemporaryDirectory Move examples into __init__ to suppress warnings during doctests --- nibabel/tmpdirs.py | 55 +++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/nibabel/tmpdirs.py b/nibabel/tmpdirs.py index cb921418e3..31e76c04e1 100644 --- a/nibabel/tmpdirs.py +++ b/nibabel/tmpdirs.py @@ -9,46 +9,40 @@ """Contexts for *with* statement providing temporary directories """ import os -import shutil -from tempfile import mkdtemp, template +import tempfile +from .deprecated import deprecate_with_version -class TemporaryDirectory: + +class TemporaryDirectory(tempfile.TemporaryDirectory): """Create and return a temporary directory. This has the same behavior as mkdtemp but can be used as a context manager. Upon exiting the context, the directory and everything contained in it are removed. - - Examples - -------- - >>> import os - >>> with TemporaryDirectory() as tmpdir: - ... fname = os.path.join(tmpdir, 'example_file.txt') - ... with open(fname, 'wt') as fobj: - ... _ = fobj.write('a string\\n') - >>> os.path.exists(tmpdir) - False """ - def __init__(self, suffix='', prefix=template, dir=None): - self.name = mkdtemp(suffix, prefix, dir) - self._closed = False - - def __enter__(self): - return self.name - - def cleanup(self): - if not self._closed: - shutil.rmtree(self.name) - self._closed = True - - def __exit__(self, exc, value, tb): - self.cleanup() - return False + @deprecate_with_version( + 'Please use the standard library tempfile.TemporaryDirectory', + '5.0', + '7.0', + ) + def __init__(self, suffix='', prefix=tempfile.template, dir=None): + """ + Examples + -------- + >>> import os + >>> with TemporaryDirectory() as tmpdir: + ... fname = os.path.join(tmpdir, 'example_file.txt') + ... with open(fname, 'wt') as fobj: + ... _ = fobj.write('a string\\n') + >>> os.path.exists(tmpdir) + False + """ + return super().__init__(suffix, prefix, dir) -class InTemporaryDirectory(TemporaryDirectory): +class InTemporaryDirectory(tempfile.TemporaryDirectory): """Create, return, and change directory to a temporary directory Notes @@ -60,9 +54,10 @@ class InTemporaryDirectory(TemporaryDirectory): Examples -------- >>> import os + >>> from pathlib import Path >>> my_cwd = os.getcwd() >>> with InTemporaryDirectory() as tmpdir: - ... _ = open('test.txt', 'wt').write('some text') + ... _ = Path('test.txt').write_text('some text') ... assert os.path.isfile('test.txt') ... assert os.path.isfile(os.path.join(tmpdir, 'test.txt')) >>> os.path.exists(tmpdir) From bb376b122b62b66d75a31bf7a6cc50ca889701c0 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Mon, 2 Jan 2023 23:40:04 -0500 Subject: [PATCH 2/3] RF: Reimplement tmpdirs tools as contextmanagers Simplifying these tools as wrapped functions makes the logic easier to read. --- nibabel/tmpdirs.py | 64 ++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/nibabel/tmpdirs.py b/nibabel/tmpdirs.py index 31e76c04e1..5a8eccfa2c 100644 --- a/nibabel/tmpdirs.py +++ b/nibabel/tmpdirs.py @@ -10,6 +10,19 @@ """ import os import tempfile +from contextlib import contextmanager + +try: + from contextlib import chdir as _chdir +except ImportError: # PY310 + + @contextmanager + def _chdir(path): + cwd = os.getcwd() + os.chdir(path) + yield + os.chdir(cwd) + from .deprecated import deprecate_with_version @@ -42,7 +55,8 @@ def __init__(self, suffix='', prefix=tempfile.template, dir=None): return super().__init__(suffix, prefix, dir) -class InTemporaryDirectory(tempfile.TemporaryDirectory): +@contextmanager +def InTemporaryDirectory(): """Create, return, and change directory to a temporary directory Notes @@ -65,18 +79,12 @@ class InTemporaryDirectory(tempfile.TemporaryDirectory): >>> os.getcwd() == my_cwd True """ - - def __enter__(self): - self._pwd = os.getcwd() - os.chdir(self.name) - return super().__enter__() - - def __exit__(self, exc, value, tb): - os.chdir(self._pwd) - return super().__exit__(exc, value, tb) + with tempfile.TemporaryDirectory() as tmpdir, _chdir(tmpdir): + yield tmpdir -class InGivenDirectory: +@contextmanager +def InGivenDirectory(path=None): """Change directory to given directory for duration of ``with`` block Useful when you want to use `InTemporaryDirectory` for the final test, but @@ -98,27 +106,15 @@ class InGivenDirectory: You can then look at the temporary file outputs to debug what is happening, fix, and finally replace ``InGivenDirectory`` with ``InTemporaryDirectory`` again. - """ - - def __init__(self, path=None): - """Initialize directory context manager - Parameters - ---------- - path : None or str, optional - path to change directory to, for duration of ``with`` block. - Defaults to ``os.getcwd()`` if None - """ - if path is None: - path = os.getcwd() - self.path = os.path.abspath(path) - - def __enter__(self): - self._pwd = os.path.abspath(os.getcwd()) - if not os.path.isdir(self.path): - os.mkdir(self.path) - os.chdir(self.path) - return self.path - - def __exit__(self, exc, value, tb): - os.chdir(self._pwd) + Parameters + ---------- + path : None or str, optional + path to change directory to, for duration of ``with`` block. + Defaults to ``os.getcwd()`` if None + """ + if path is None: + path = os.getcwd() + os.makedirs(path, exist_ok=True) + with _chdir(path): + yield os.path.abspath(path) From 27b757b51b13e4d62c46f2f9ac628e30e27306f4 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 3 Jan 2023 00:42:27 -0500 Subject: [PATCH 3/3] MNT: Schedule final removal of TemporaryDirectory --- nibabel/tests/test_removalschedule.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nibabel/tests/test_removalschedule.py b/nibabel/tests/test_removalschedule.py index 939895abbd..db99ae3a46 100644 --- a/nibabel/tests/test_removalschedule.py +++ b/nibabel/tests/test_removalschedule.py @@ -14,6 +14,12 @@ ] OBJECT_SCHEDULE = [ + ( + '8.0.0', + [ + ('nibabel.tmpdirs', 'TemporaryDirectory'), + ], + ), ( '7.0.0', [