fix(6477): a plain-word call needs the parenthesis right after the word
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / integration (push) Successful in 59s
CI & Build / Python tests (push) Successful in 1m37s
CI & Build / Build & push image (push) Successful in 26s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / integration (push) Successful in 59s
CI & Build / Python tests (push) Successful in 1m37s
CI & Build / Build & push image (push) Successful in 26s
Read against Fabled Archives after the cleanup: of the 9 rows still linked to snippet #5448 (symbol `file`), all but one matched prose in a comment, "a file (not a directory)", "the file (ScanWaiting". The only real call was `r.file(ctx, ...)`. Formatted code never puts a space before a call's parenthesis and prose does, so the plain-word test is now `word(` with no whitespace. _PROPOSER_VERSION 8 re-reads every row once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1798,7 +1798,7 @@ def _semantic_priority(row) -> tuple:
|
||||
# were examined under, so a tightened rule re-examines everything once. A
|
||||
# change that does not alter what is proposed needs no bump. A stale "miss"
|
||||
# basis on an old row is inert: a miss is not evidence (see _SEMANTIC_LIMIT).
|
||||
_PROPOSER_VERSION = 7
|
||||
_PROPOSER_VERSION = 8
|
||||
# Signature resemblance floor, name blanked (difflib ratio) — and a length
|
||||
# floor, because `def NAME():` resembles `def NAME(x):` at 0.95 while saying
|
||||
# nothing; a family shape has parameters to resemble.
|
||||
@@ -1939,7 +1939,9 @@ def names_canon(
|
||||
unless the canon is recorded in this very file;
|
||||
- never a generic verb, with or without a leading underscore;
|
||||
- a bare lowercase word (`file`, `seen`, `seal`) only where it is called
|
||||
as `word(`, because as a plain word it is everyone's variable.
|
||||
as `word(`, because as a plain word it is everyone's variable. No space
|
||||
is allowed before the parenthesis: formatted code never has one, and
|
||||
prose does ("a file (not a directory)").
|
||||
Same kind and language family are checked by the callers' loops."""
|
||||
sym = _norm_symbol(canon.symbol or "")
|
||||
if not sym:
|
||||
@@ -1954,7 +1956,7 @@ def names_canon(
|
||||
if not any(lp and _path_touches(lp, path) for lp, _ls in canon.locations):
|
||||
return False
|
||||
if kind == "sym" and re.fullmatch(r"[a-z]+", sym):
|
||||
return re.search(rf"(?<![\w$]){re.escape(sym)}\s*\(", body or "") is not None
|
||||
return re.search(rf"(?<![\w$]){re.escape(sym)}\(", body or "") is not None
|
||||
return references_symbol(body, sym, kind)
|
||||
|
||||
|
||||
|
||||
@@ -601,7 +601,9 @@ def test_a_plain_word_counts_only_where_it_is_called():
|
||||
from grimoire.services.shape_ledger import Canon, _norm_text, reference_canons
|
||||
seen = Canon(8, "sym", "seen", (("src/tree.py", "seen"),), "def seen(f):", _norm_text("x"), 2, "python")
|
||||
assert reference_canons("sym", "src/a.py", "walk", "if path in seen:\n return", [seen]) == []
|
||||
assert reference_canons("sym", "src/a.py", "walk", "if seen (f):\n return", [seen]) == [8]
|
||||
assert reference_canons("sym", "src/a.py", "walk", "if seen(f):\n return", [seen]) == [8]
|
||||
# Prose puts a space before the parenthesis; a call does not.
|
||||
assert reference_canons("sym", "src/a.py", "walk", "// a seen (or unseen) path\nreturn p", [seen]) == []
|
||||
# A leading underscore does not get a generic verb past the stoplist.
|
||||
run = Canon(9, "sym", "_run", (("src/x.py", "_run"),), "def _run(cmd):", _norm_text("x"), 2, "python")
|
||||
assert reference_canons("sym", "src/a.py", "go", "_run(['ls'])", [run]) == []
|
||||
|
||||
Reference in New Issue
Block a user