]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-64595: Argument Clinic: Touch source file if any output file changed (#104152)
authorErlend E. Aasland <erlend.aasland@protonmail.com>
Fri, 5 May 2023 12:38:38 +0000 (14:38 +0200)
committerGitHub <noreply@github.com>
Fri, 5 May 2023 12:38:38 +0000 (12:38 +0000)
Lib/test/test_clinic.py
Tools/clinic/clinic.py

index 660f7a1e296d8f97b192fbf29b6c62ebc475fcd6..6aaf4d1ed8d56029ac0d420598b90c5b9a445e3f 100644 (file)
@@ -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):
index 2746b24c333e66d1501b8ffbb4e78902fd37aa79..5f6e67e7d65a1df0d34326776fa95c5f2bc3539f 100755 (executable)
@@ -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):