##// END OF EJS Templates
Implement atomic save...
Thomas Kluyver -
Show More
@@ -13,6 +13,7 b' from tornado import web'
13 13
14 14 from .manager import ContentsManager
15 15 from IPython.nbformat import current
16 from IPython.utils.io import atomic_writing
16 17 from IPython.utils.path import ensure_dir_exists
17 18 from IPython.utils.traitlets import Unicode, Bool, TraitError
18 19 from IPython.utils.py3compat import getcwd
@@ -295,7 +296,7 b' class FileContentsManager(ContentsManager):'
295 296 if 'name' in nb['metadata']:
296 297 nb['metadata']['name'] = u''
297 298
298 with io.open(os_path, 'w', encoding='utf-8') as f:
299 with atomic_writing(os_path, encoding='utf-8') as f:
299 300 current.write(nb, f, u'json')
300 301
301 302 def _save_file(self, os_path, model, name='', path=''):
@@ -312,7 +313,7 b' class FileContentsManager(ContentsManager):'
312 313 bcontent = base64.decodestring(b64_bytes)
313 314 except Exception as e:
314 315 raise web.HTTPError(400, u'Encoding error saving %s: %s' % (os_path, e))
315 with io.open(os_path, 'wb') as f:
316 with atomic_writing(os_path, 'wb') as f:
316 317 f.write(bcontent)
317 318
318 319 def _save_directory(self, os_path, model, name='', path=''):
@@ -16,6 +16,7 b' from __future__ import absolute_import'
16 16 # Imports
17 17 #-----------------------------------------------------------------------------
18 18 import codecs
19 from contextlib import contextmanager
19 20 import os
20 21 import sys
21 22 import tempfile
@@ -217,6 +218,23 b" def temp_pyfile(src, ext='.py'):"
217 218 f.flush()
218 219 return fname, f
219 220
221 @contextmanager
222 def atomic_writing(path, mode='w', encoding='utf-8', **kwargs):
223 tmp_file = path + '.tmp-write'
224 if 'b' in mode:
225 encoding = None
226
227 with open(tmp_file, mode, encoding=encoding, **kwargs) as f:
228 yield f
229
230 # Written successfully, now rename it
231
232 if os.name == 'nt' and os.path.exists(path):
233 # Rename over existing file doesn't work on Windows
234 os.remove(path)
235
236 os.rename(tmp_file, path)
237
220 238
221 239 def raw_print(*args, **kw):
222 240 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
General Comments 0
You need to be logged in to leave comments. Login now