diff --git a/IPython/frontend/terminal/console/interactiveshell.py b/IPython/frontend/terminal/console/interactiveshell.py index 2f5c02a..c39eab7 100644 --- a/IPython/frontend/terminal/console/interactiveshell.py +++ b/IPython/frontend/terminal/console/interactiveshell.py @@ -22,7 +22,6 @@ import signal import os import sys import time -import tempfile import subprocess from io import BytesIO import base64 @@ -39,6 +38,7 @@ from IPython.core import page from IPython.utils.warn import warn, error, fatal from IPython.utils import io from IPython.utils.traitlets import List, Enum, Any +from IPython.utils.tempdir import NamedFileInTemporaryDirectory from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell from IPython.frontend.terminal.console.completer import ZMQCompleter @@ -285,7 +285,7 @@ class ZMQTerminalInteractiveShell(TerminalInteractiveShell): raw = base64.decodestring(data[mime]) imageformat = self._imagemime[mime] ext = '.{0}'.format(imageformat) - with nested(tempfile.NamedTemporaryFile(suffix=ext), + with nested(NamedFileInTemporaryDirectory('tmp.{0}'.format(ext)), open(os.devnull, 'w')) as (f, devnull): f.write(raw) f.flush() diff --git a/IPython/utils/tempdir.py b/IPython/utils/tempdir.py index 57f02fc..364e119 100644 --- a/IPython/utils/tempdir.py +++ b/IPython/utils/tempdir.py @@ -3,14 +3,14 @@ This is copied from the stdlib and will be standard in Python 3.2 and onwards. """ +import os as _os + # This code should only be used in Python versions < 3.2, since after that we # can rely on the stdlib itself. try: from tempfile import TemporaryDirectory except ImportError: - - import os as _os from tempfile import mkdtemp, template class TemporaryDirectory(object): @@ -74,3 +74,33 @@ except ImportError: self._rmdir(path) except self._os_error: pass + + +class NamedFileInTemporaryDirectory(object): + + def __init__(self, filename, mode='w+b', bufsize=-1, **kwds): + """ + Open a file named `filename` in a temporary directory. + + This context manager is preferred over `NamedTemporaryFile` in + stdlib `tempfile` when one needs to reopen the file. + + Arguments `mode` and `bufsize` are passed to `open`. + Rest of the arguments are passed to `TemporaryDirectory`. + + """ + self._tmpdir = TemporaryDirectory(**kwds) + path = _os.path.join(self._tmpdir.name, filename) + self.file = open(path, mode, bufsize) + + def cleanup(self): + self.file.close() + self._tmpdir.cleanup() + + __del__ = cleanup + + def __enter__(self): + return self.file + + def __exit__(self, type, value, traceback): + self.cleanup() diff --git a/IPython/utils/tests/test_tempdir.py b/IPython/utils/tests/test_tempdir.py new file mode 100644 index 0000000..5935cc7 --- /dev/null +++ b/IPython/utils/tests/test_tempdir.py @@ -0,0 +1,20 @@ +#----------------------------------------------------------------------------- +# Copyright (C) 2012- The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +import os + +from IPython.utils.tempdir import NamedFileInTemporaryDirectory + + +def test_named_file_in_temporary_directory(): + with NamedFileInTemporaryDirectory('filename') as file: + name = file.name + assert not file.closed + assert os.path.exists(name) + file.write('test') + assert file.closed + assert not os.path.exists(name)