From 8b7d4c1c2f277170fcb83790eb3f252f3f16b85b Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Tue, 5 Aug 2014 10:50:09 -0700 Subject: [PATCH] Rework atomic_writing with tests & docstring --- IPython/html/services/contents/filemanager.py | 2 +- IPython/utils/tests/test_io.py | 31 +++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/IPython/html/services/contents/filemanager.py b/IPython/html/services/contents/filemanager.py index ad36f3963..ef6cbdf78 100644 --- a/IPython/html/services/contents/filemanager.py +++ b/IPython/html/services/contents/filemanager.py @@ -313,7 +313,7 @@ class FileContentsManager(ContentsManager): bcontent = base64.decodestring(b64_bytes) except Exception as e: raise web.HTTPError(400, u'Encoding error saving %s: %s' % (os_path, e)) - with atomic_writing(os_path, 'wb') as f: + with atomic_writing(os_path, text=False) as f: f.write(bcontent) def _save_directory(self, os_path, model, name='', path=''): diff --git a/IPython/utils/tests/test_io.py b/IPython/utils/tests/test_io.py index 9f28ba2cd..bf4ed7d72 100644 --- a/IPython/utils/tests/test_io.py +++ b/IPython/utils/tests/test_io.py @@ -15,6 +15,7 @@ from __future__ import print_function from __future__ import absolute_import import io as stdlib_io +import os.path import sys from subprocess import Popen, PIPE @@ -23,8 +24,11 @@ import unittest import nose.tools as nt from IPython.testing.decorators import skipif -from IPython.utils.io import Tee, capture_output, unicode_std_stream +from IPython.utils.io import (Tee, capture_output, unicode_std_stream, + atomic_writing, + ) from IPython.utils.py3compat import doctest_refactor_print, PY3 +from IPython.utils.tempdir import TemporaryDirectory if PY3: from io import StringIO @@ -121,4 +125,27 @@ def test_UnicodeStdStream_nowrap(): nt.assert_is(unicode_std_stream(), sys.stdout) assert not sys.stdout.closed finally: - sys.stdout = orig_stdout \ No newline at end of file + sys.stdout = orig_stdout + +def test_atomic_writing(): + class CustomExc(Exception): pass + + with TemporaryDirectory() as td: + f1 = os.path.join(td, 'penguin') + with stdlib_io.open(f1, 'w') as f: + f.write(u'Before') + + with nt.assert_raises(CustomExc): + with atomic_writing(f1) as f: + f.write(u'Failing write') + raise CustomExc + + # Because of the exception, the file should not have been modified + with stdlib_io.open(f1, 'r') as f: + nt.assert_equal(f.read(), u'Before') + + with atomic_writing(f1) as f: + f.write(u'Overwritten') + + with stdlib_io.open(f1, 'r') as f: + nt.assert_equal(f.read(), u'Overwritten')