summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend.aasland@protonmail.com>2023-05-05 14:38:38 +0200
committerGitHub <noreply@github.com>2023-05-05 12:38:38 +0000
commit45a9e3834a6ed20ee250e2e5a8583dffcef0eb73 (patch)
treeceb551db66a9d1a904b376bb859112e05cbc3e61
parentd0b4abedfb8b0322df835065f85551d097cfecb8 (diff)
downloadcpython-git-45a9e3834a6ed20ee250e2e5a8583dffcef0eb73.tar.gz
gh-64595: Argument Clinic: Touch source file if any output file changed (#104152)
-rw-r--r--Lib/test/test_clinic.py7
-rwxr-xr-xTools/clinic/clinic.py19
2 files changed, 17 insertions, 9 deletions
diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py
index 660f7a1e29..6aaf4d1ed8 100644
--- a/Lib/test/test_clinic.py
+++ b/Lib/test/test_clinic.py
@@ -99,8 +99,9 @@ class ClinicWholeFileTest(TestCase):
# the last line of the block got corrupted.
c = clinic.Clinic(clinic.CLanguage(None), filename="file")
raw = "/*[clinic]\nfoo\n[clinic]*/"
- cooked = c.parse(raw).splitlines()
- end_line = cooked[2].rstrip()
+ cooked, _ = c.parse(raw)
+ lines = cooked.splitlines()
+ end_line = lines[2].rstrip()
# this test is redundant, it's just here explicitly to catch
# the regression test so we don't forget what it looked like
self.assertNotEqual(end_line, "[clinic]*/[clinic]*/")
@@ -259,7 +260,7 @@ xyz
c = clinic.Clinic(language, filename="file")
c.parsers['inert'] = InertParser(c)
c.parsers['copy'] = CopyParser(c)
- computed = c.parse(input)
+ computed, _ = c.parse(input)
self.assertEqual(output, computed)
def test_clinic_1(self):
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index 2746b24c33..5f6e67e7d6 100755
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -1954,12 +1954,12 @@ legacy_converters = {}
return_converters = {}
-def write_file(filename, new_contents):
+def write_file(filename, new_contents, force=False):
try:
with open(filename, 'r', encoding="utf-8") as fp:
old_contents = fp.read()
- if old_contents == new_contents:
+ if old_contents == new_contents and not force:
# no change: avoid modifying the file modification time
return
except FileNotFoundError:
@@ -2123,6 +2123,8 @@ impl_definition block
traceback.format_exc().rstrip())
printer.print_block(block)
+ clinic_out = []
+
# these are destinations not buffers
for name, destination in self.destinations.items():
if destination.type == 'suppress':
@@ -2162,10 +2164,11 @@ impl_definition block
block.input = 'preserve\n'
printer_2 = BlockPrinter(self.language)
printer_2.print_block(block, core_includes=True)
- write_file(destination.filename, printer_2.f.getvalue())
+ pair = destination.filename, printer_2.f.getvalue()
+ clinic_out.append(pair)
continue
- return printer.f.getvalue()
+ return printer.f.getvalue(), clinic_out
def _module_and_class(self, fields):
@@ -2221,9 +2224,13 @@ def parse_file(filename, *, verify=True, output=None):
return
clinic = Clinic(language, verify=verify, filename=filename)
- cooked = clinic.parse(raw)
+ src_out, clinic_out = clinic.parse(raw)
- write_file(output, cooked)
+ # If clinic output changed, force updating the source file as well.
+ force = bool(clinic_out)
+ write_file(output, src_out, force=force)
+ for fn, data in clinic_out:
+ write_file(fn, data)
def compute_checksum(input, length=None):