mirror of
https://github.com/usestrix/strix.git
synced 2026-10-29 06:32:26 +00:00
fix(todo): unwrap JSON string-scalar ids (addresses review feedback)
The first pass routed every non-array input through the literal-token path, which dropped the surrounding quotes of a JSON string scalar — so a caller passing '"a3f9c2"' looked the id up *with* quotes and missed the real todo (a regression from the prior json.loads behaviour, flagged by the Greptile review on #663). Handle a parsed `str` by unwrapping it, while still keeping numeric-looking bare ids literal (json.loads yields a float/inf for those, not a str). The string / comma / single-token cases resolve into one token list, which also keeps the function within the return-count lint limit. Adds a regression test for the quoted-scalar and empty-string inputs.
This commit is contained in:
parent
946ae52411
commit
370e945da2
2 changed files with 28 additions and 8 deletions
|
|
@ -131,20 +131,30 @@ def _normalize_todo_ids(raw_ids: Any) -> list[str]:
|
|||
stripped = raw_ids.strip()
|
||||
if not stripped:
|
||||
return []
|
||||
# json.loads is used only to unpack the JSON *array* form, e.g.
|
||||
# '["a", "b"]'. A bare string is a literal id (optionally
|
||||
# comma-separated) and must NOT be routed through the parsed
|
||||
# scalar value: ids are 6-char uuid slugs, and ones like "1e5230"
|
||||
# or "2363e0" are valid JSON numbers that json.loads would mangle
|
||||
# (-> inf / "2363.0"), silently targeting a non-existent todo.
|
||||
# json.loads is used only to unpack a JSON *array* ('["a", "b"]')
|
||||
# or a JSON *string* scalar ('"a3f9c2"', which unwraps to the id).
|
||||
# Any other bare token is a literal id (optionally comma-separated)
|
||||
# and must NOT be routed through a parsed *numeric* scalar: ids are
|
||||
# 6-char uuid slugs, and ones like "1e5230" or "2363e0" are valid
|
||||
# JSON numbers that json.loads would mangle (-> inf / "2363.0"),
|
||||
# silently targeting a non-existent todo.
|
||||
try:
|
||||
parsed = json.loads(stripped)
|
||||
except json.JSONDecodeError:
|
||||
parsed = None
|
||||
if isinstance(parsed, list):
|
||||
return [str(item).strip() for item in parsed if str(item).strip()]
|
||||
parts = stripped.split(",") if "," in stripped else [stripped]
|
||||
return [part.strip() for part in parts if part.strip()]
|
||||
# Otherwise resolve to literal tokens: a JSON string scalar unwraps
|
||||
# to its value, a comma string splits, and anything else is a single
|
||||
# token kept verbatim (so numeric-looking ids aren't mangled by the
|
||||
# parse above).
|
||||
if isinstance(parsed, str):
|
||||
tokens = [parsed]
|
||||
elif "," in stripped:
|
||||
tokens = stripped.split(",")
|
||||
else:
|
||||
tokens = [stripped]
|
||||
return [token.strip() for token in tokens if token.strip()]
|
||||
if isinstance(raw_ids, list):
|
||||
return [str(item).strip() for item in raw_ids if str(item).strip()]
|
||||
return [str(raw_ids).strip()]
|
||||
|
|
|
|||
|
|
@ -43,6 +43,16 @@ def test_json_array_of_ids_is_unpacked() -> None:
|
|||
assert _normalize_todo_ids('["1e5230", "a3f9c2"]') == ["1e5230", "a3f9c2"]
|
||||
|
||||
|
||||
def test_json_string_scalar_id_is_unwrapped() -> None:
|
||||
# A caller may JSON-encode a single id ('"a3f9c2"'); the surrounding
|
||||
# quotes must be stripped, not treated as part of the id. A quoted
|
||||
# numeric-looking slug stays a literal string (not a parsed number),
|
||||
# and an empty JSON string yields no ids.
|
||||
assert _normalize_todo_ids('"a3f9c2"') == ["a3f9c2"]
|
||||
assert _normalize_todo_ids('"1e5230"') == ["1e5230"]
|
||||
assert _normalize_todo_ids('""') == []
|
||||
|
||||
|
||||
def test_comma_separated_ids_are_split() -> None:
|
||||
assert _normalize_todo_ids("1e5230, a3f9c2") == ["1e5230", "a3f9c2"]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue