Skip to content

Commit ac476bd

Browse files
committed
fix(entrypoints): validate disable: shape; drop dead setuptools stanza (#27)
- disable: must now be a list of rule id strings; a bare-string typo or other malformed value raises RulesError instead of silently disabling nothing (set() over a string iterated its characters). - Remove [tool.setuptools.package-data] -- this project builds with hatchling, which already ships entrypoints/rules.yml via its default whole-package inclusion (verified with uv build --wheel).
1 parent 8f4d412 commit ac476bd

3 files changed

Lines changed: 23 additions & 4 deletions

File tree

codeanalyzer/entrypoints/rules.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def _read(path: Path) -> Dict[str, Any]:
7676

7777
def _merge(out: RuleSet, data: Dict[str, Any], origin: str) -> None:
7878
out.rulesets.append(origin)
79-
disabled = set(data.get("disable") or [])
79+
disabled = set(_disable_list(data, origin))
8080
frameworks = data.get("frameworks") or {}
8181
if not isinstance(frameworks, dict):
8282
raise RulesError(f"{origin}: `frameworks` must be a mapping")
@@ -96,6 +96,13 @@ def _merge(out: RuleSet, data: Dict[str, Any], origin: str) -> None:
9696
fw.bases = [r for r in fw.bases if r.id not in disabled]
9797

9898

99+
def _disable_list(data: Dict[str, Any], origin: str) -> List[str]:
100+
raw = data.get("disable") or []
101+
if not isinstance(raw, list) or not all(isinstance(x, str) for x in raw):
102+
raise RulesError(f"{origin}: `disable` must be a list of rule id strings")
103+
return raw
104+
105+
99106
def _require(raw: Dict[str, Any], key: str, origin: str) -> Any:
100107
if key not in raw:
101108
raise RulesError(f"{origin}: rule {raw!r} is missing `{key}`")

pyproject.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@ neo4j = [
5959
"neo4j>=5.0.0,<6.0.0",
6060
]
6161

62-
[tool.setuptools.package-data]
63-
codeanalyzer = ["entrypoints/*.yml"]
64-
6562
[dependency-groups]
6663
test = [
6764
"pytest>=7.0.0,<8.0.0",

test/test_entrypoint_rules.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,18 @@ def test_malformed_user_file_raises_before_analysis(tmp_path):
2424
bad.write_text("frameworks: [this is a list not a mapping]\n")
2525
with pytest.raises(RulesError):
2626
load_rules([bad])
27+
28+
29+
def test_bare_string_disable_raises_instead_of_silently_matching_chars(tmp_path):
30+
bad = tmp_path / "bad.yml"
31+
bad.write_text("disable: flask.route\n")
32+
with pytest.raises(RulesError):
33+
load_rules([bad])
34+
35+
36+
def test_well_formed_disable_list_removes_the_shipped_rule(tmp_path):
37+
user = tmp_path / "user.yml"
38+
user.write_text("disable: [flask.route]\n")
39+
rs = load_rules([user])
40+
flask = rs.frameworks["flask"]
41+
assert all(r.id != "flask.route" for r in flask.decorators)

0 commit comments

Comments
 (0)