+def write_json_file(obj, fn):
+ """ Encode obj as JSON and write it to fn, atomically """
+
+ # In Python 2.x, json.dump expects a bytestream.
+ # In Python 3.x, it writes to a character stream
+ if sys.version_info < (3, 0):
+ mode = 'wb'
+ encoding = None
+ else:
+ mode = 'w'
+ encoding = 'utf-8'
+ tf = tempfile.NamedTemporaryFile(
+ suffix='.tmp', prefix=os.path.basename(fn) + '.',
+ dir=os.path.dirname(fn),
+ delete=False)
+
+ try:
+ with tf:
+ json.dump(obj, tf)
+ os.rename(tf.name, fn)
+ except:
+ try:
+ os.remove(tf.name)
+ except OSError:
+ pass
+ raise
+
+
+if sys.version_info >= (2, 7):