From 76d3c987d4094617300154db947fa132c5e95122 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sun, 18 Oct 2026 14:32:30 +0200 Subject: [PATCH] fix: name the corrections an export withholds --- scripts/export_native.py | 4 ++++ scripts/exporter/base_exporter.py | 8 ++++++++ scripts/exporter/emudeck_exporter.py | 8 ++++++++ tests/test_export_counts.py | 10 ++++++++++ 4 files changed, 30 insertions(+) diff --git a/scripts/export_native.py b/scripts/export_native.py index d6c45ed0..fbace929 100644 --- a/scripts/export_native.py +++ b/scripts/export_native.py @@ -433,7 +433,11 @@ def export_platform( summary += f", {refused} the format cannot state" if lost: summary += f", {lost} of theirs dropped" + withheld = exporter.withheld() + if withheld: + summary += f", {len(withheld)} corrections withheld" messages.append(summary) + messages.extend(f"withheld: {reason}" for reason in withheld) for correction in applied[:5]: messages.append(f"hash corrected: {correction}") if len(applied) > 5: diff --git a/scripts/exporter/base_exporter.py b/scripts/exporter/base_exporter.py index 8e022454..cf7753fe 100644 --- a/scripts/exporter/base_exporter.py +++ b/scripts/exporter/base_exporter.py @@ -179,6 +179,14 @@ class BaseExporter(ABC): """ return field_name in self.carries() + def withheld(self) -> list[str]: + """Corrections the render proved and still did not write, named. + + Empty for most formats. One that refuses a rewrite to keep a value + the platform holds says so here, or the run reads as nothing to do. + """ + return [] + def outcome( self, systems: dict[str, NativeSystem], diff --git a/scripts/exporter/emudeck_exporter.py b/scripts/exporter/emudeck_exporter.py index b91f19f3..96a07699 100644 --- a/scripts/exporter/emudeck_exporter.py +++ b/scripts/exporter/emudeck_exporter.py @@ -103,6 +103,14 @@ class Exporter(BaseExporter): return [] return self._md5s(systems, system_id) + def withheld(self) -> list[str]: + """Each check whose rewrite was refused, and the md5 that kept it.""" + return [ + f"{name} keeps EmuDeck's array: rewriting it would drop " + f"{', '.join(sorted(values))}, which no profile carries" + for name, values in sorted(getattr(self, "_withdrawn", {}).items()) + ] + def _refused_systems(self) -> set[str]: withdrawn = getattr(self, "_withdrawn", {}) return {FUNCTION_HASH_MAP[name] for name in withdrawn if name in FUNCTION_HASH_MAP} diff --git a/tests/test_export_counts.py b/tests/test_export_counts.py index 9c59d021..bf4a71f4 100644 --- a/tests/test_export_counts.py +++ b/tests/test_export_counts.py @@ -318,6 +318,16 @@ class EmuDeckWritesItsCorrections(unittest.TestCase): self.assertEqual( [i for i in exporter.validate(systems, produced) if "checkPS1BIOS" in i], [] ) + # Refused and named: the run said only "0 hashes corrected", which + # reads the same as nothing to correct. + withheld = exporter.withheld() + self.assertEqual(len(withheld), 1) + self.assertIn("checkPS1BIOS", withheld[0]) + self.assertIn(d, withheld[0]) + + def test_the_summary_reads_the_hook(self): + source = (Path(__file__).resolve().parents[1] / "scripts" / "export_native.py").read_text() + self.assertIn("withheld = exporter.withheld()", source) class BizHawkCountsWhatItWrites(unittest.TestCase):