Patchwork [3,of,9] byteify-strings: add --inplace option to write back result

login
register
mail settings
Submitter Yuya Nishihara
Date June 18, 2018, 1:17 p.m.
Message ID <e1566a950374c824a1ca.1529327821@mimosa>
Download mbox | patch
Permalink /patch/32271/
State Accepted
Headers show

Comments

Yuya Nishihara - June 18, 2018, 1:17 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1527773309 -32400
#      Thu May 31 22:28:29 2018 +0900
# Node ID e1566a950374c824a1ca950904ed5c053af1037b
# Parent  27476a7a2bbcd16085794977001a189114a114f0
byteify-strings: add --inplace option to write back result

Patch

diff --git a/contrib/byteify-strings.py b/contrib/byteify-strings.py
--- a/contrib/byteify-strings.py
+++ b/contrib/byteify-strings.py
@@ -10,8 +10,12 @@ 
 from __future__ import absolute_import
 
 import argparse
+import contextlib
+import errno
 import io
+import os
 import sys
+import tempfile
 import token
 import tokenize
 
@@ -162,14 +166,44 @@  def process(fin, fout):
     tokens = replacetokens(list(tokens), fullname='<dummy>')
     fout.write(tokenize.untokenize(tokens))
 
+def tryunlink(fname):
+    try:
+        os.unlink(fname)
+    except OSError as err:
+        if err.errno != errno.ENOENT:
+            raise
+
+@contextlib.contextmanager
+def editinplace(fname):
+    n = os.path.basename(fname)
+    d = os.path.dirname(fname)
+    fp = tempfile.NamedTemporaryFile(prefix='.%s-' % n, suffix='~', dir=d,
+                                     delete=False)
+    try:
+        yield fp
+        fp.close()
+        if os.name == 'nt':
+            tryunlink(fname)
+        os.rename(fp.name, fname)
+    finally:
+        fp.close()
+        tryunlink(fp.name)
+
 def main():
     ap = argparse.ArgumentParser()
+    ap.add_argument('-i', '--inplace', action='store_true', default=False,
+                    help='edit files in place')
     ap.add_argument('files', metavar='FILE', nargs='+', help='source file')
     args = ap.parse_args()
     for fname in args.files:
-        with open(fname, 'rb') as fin:
-            fout = sys.stdout.buffer
-            process(fin, fout)
+        if args.inplace:
+            with editinplace(fname) as fout:
+                with open(fname, 'rb') as fin:
+                    process(fin, fout)
+        else:
+            with open(fname, 'rb') as fin:
+                fout = sys.stdout.buffer
+                process(fin, fout)
 
 if __name__ == '__main__':
     main()