From 86d5b276537b335d85dac372b62453b49def8d50 Mon Sep 17 00:00:00 2001 From: forge Date: Wed, 21 Oct 2026 02:08:23 +0000 Subject: [PATCH] =?UTF-8?q?forge:=20citation=5Fhash=5Fclass.py=20verdict?= =?UTF-8?q?=5Fof()=20DRY=20extraction=20=E2=80=94=20inline=20verdict=20log?= =?UTF-8?q?ic=20collapsed=20to=20one=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/citation_hash_class.py | 39 +++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/tools/citation_hash_class.py b/tools/citation_hash_class.py index 33ede56..a517c89 100644 --- a/tools/citation_hash_class.py +++ b/tools/citation_hash_class.py @@ -233,6 +233,27 @@ def siblings(IDX, fam, full): return None +def verdict_of(bf, fam, after_size): + """Classify a single token occurrence into its verdict class. + + bf the bound family from bound_family() (or None) + fam the measured family from resolve() + after_size whether a bare size figure precedes the token + + This was previously inlined twice -- once in scan() and once in the + selftest fixtures -- and the two copies had quietly diverged: scan() + excluded AMBIGUOUS from CLASS_MISMATCH while the selftest copy did not. + One function, one source of truth: both callers use this directly. + """ + if bf and fam == 'UNRESOLVED': + return 'BOUND_UNRESOLVED' + if bf and fam not in ('AMBIGUOUS', 'UNRESOLVED') and bf != fam: + return 'CLASS_MISMATCH' + if not bf and after_size and fam in ('BLOB_OID', 'CONTENT_SHA256'): + return 'CLASSLESS_AFTER_SIZE' + return 'ok' + + def scan(repo, corpus, rev, IDX, window, min_len): rows, stats = [], collections.Counter() hexre = re.compile(r'\b[0-9a-f]{%d,64}\b' % min_len) @@ -247,14 +268,7 @@ def scan(repo, corpus, rev, IDX, window, min_len): if bf: stats['bound'] += 1 after_size = bool(AFTER_SIZE.search(text[max(0, m.start() - 40):m.start()])) - if bf and fam == 'UNRESOLVED': - verdict = 'BOUND_UNRESOLVED' - elif bf and fam not in ('AMBIGUOUS', 'UNRESOLVED') and bf != fam: - verdict = 'CLASS_MISMATCH' - elif not bf and after_size and fam in ('BLOB_OID', 'CONTENT_SHA256'): - verdict = 'CLASSLESS_AFTER_SIZE' - else: - verdict = 'ok' + verdict = verdict_of(bf, fam, after_size) stats[verdict] += 1 rows.append({"file": p, "line": text.count('\n', 0, m.start()) + 1, "token": tok, "len": len(tok), "measured": fam, "full": full, @@ -313,14 +327,7 @@ def selftest(repo): i = text.index(tok) bf, _ = bound_family(text, i, i + len(tok), 40) after = bool(AFTER_SIZE.search(text[max(0, i - 40):i])) - if bf and fam == 'UNRESOLVED': - got = 'BOUND_UNRESOLVED' - elif bf and bf != fam: - got = 'CLASS_MISMATCH' - elif not bf and after and fam in ('BLOB_OID', 'CONTENT_SHA256'): - got = 'CLASSLESS_AFTER_SIZE' - else: - got = 'ok' + got = verdict_of(bf, fam, after) n += 1 ok = got == want bad += 0 if ok else 1