cpython/Tools/scripts/update_file.py
Eric Snow 044e8d866f
bpo-45019: Add a tool to generate list of modules to include for frozen modules (gh-27980)
Frozen modules must be added to several files in order to work properly. Before this change this had to be done manually. Here we add a tool to generate the relevant lines in those files instead. This helps us avoid mistakes and omissions.

https://bugs.python.org/issue45019
2021-08-30 17:25:11 -06:00

52 lines
1.5 KiB
Python

"""
A script that replaces an old file with a new one, only if the contents
actually changed. If not, the new file is simply deleted.
This avoids wholesale rebuilds when a code (re)generation phase does not
actually change the in-tree generated code.
"""
import contextlib
import os
import os.path
import sys
@contextlib.contextmanager
def updating_file_with_tmpfile(filename, tmpfile=None):
"""A context manager for updating a file via a temp file.
The context manager provides two open files: the source file open
for reading, and the temp file, open for writing.
Upon exiting: both files are closed, and the source file is replaced
with the temp file.
"""
# XXX Optionally use tempfile.TemporaryFile?
if not tmpfile:
tmpfile = filename + '.tmp'
elif os.path.isdir(tmpfile):
tmpfile = os.path.join(tmpfile, filename + '.tmp')
with open(tmpfile, 'w') as outfile:
with open(filename) as infile:
yield infile, outfile
update_file_with_tmpfile(filename, tmpfile)
def update_file_with_tmpfile(filename, tmpfile):
with open(filename, 'rb') as f:
old_contents = f.read()
with open(tmpfile, 'rb') as f:
new_contents = f.read()
if old_contents != new_contents:
os.replace(tmpfile, filename)
else:
os.unlink(tmpfile)
if __name__ == '__main__':
if len(sys.argv) != 3:
print("Usage: %s <path to be updated> <path with new contents>" % (sys.argv[0],))
sys.exit(1)
update_file_with_tmpfile(sys.argv[1], sys.argv[2])