File: atomic-pyc-rename.diff

package info (click to toggle)
python2.7 2.7.16-2%2Bdeb10u1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 78,524 kB
  • sloc: python: 469,695; ansic: 444,315; sh: 17,604; asm: 14,304; makefile: 4,899; objc: 761; exp: 499; cpp: 128; xml: 76
file content (34 lines) | stat: -rw-r--r-- 999 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
--- a/Lib/py_compile.py
+++ b/Lib/py_compile.py
@@ -120,13 +120,24 @@
             return
     if cfile is None:
         cfile = file + (__debug__ and 'c' or 'o')
-    with open(cfile, 'wb') as fc:
-        fc.write('\0\0\0\0')
-        wr_long(fc, timestamp)
-        marshal.dump(codeobject, fc)
-        fc.flush()
-        fc.seek(0, 0)
-        fc.write(MAGIC)
+    # Atomically write the pyc/pyo file.  Issue #13146.
+    # id() is used to generate a pseudo-random filename.
+    path_tmp = '{}.{}'.format(cfile, id(cfile))
+    try:
+        with open(path_tmp, 'wb') as fc:
+            fc.write('\0\0\0\0')
+            wr_long(fc, timestamp)
+            marshal.dump(codeobject, fc)
+            fc.flush()
+            fc.seek(0, 0)
+            fc.write(MAGIC)
+        os.rename(path_tmp, cfile)
+    except OSError:
+        try:
+            os.unlink(path_tmp)
+        except OSError:
+            pass
+        raise
 
 def main(args=None):
     """Compile several source files.