Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
3e2e84e
feat(version-scanner): support target list inputs via --targets
chalmerlowe Jun 16, 2026
d26715a
feat(version-scanner): simplify targets list input to accept only YAM…
chalmerlowe Jun 17, 2026
156f2b8
test(version-scanner): parametrize targets file failure tests
chalmerlowe Jun 17, 2026
f1c47bb
test(version-scanner): refactor formatting tests to use a shared samp…
chalmerlowe Jun 17, 2026
3c0b8fe
chore(version-scanner): move sample_match fixture to the top of test …
chalmerlowe Jun 17, 2026
00d409d
refactor(version-scanner): consolidate file reading and error handlin…
chalmerlowe Jun 17, 2026
437a13f
test(version-scanner): add parametrized unit tests for _safe_read_fil…
chalmerlowe Jun 17, 2026
5011c0b
chore(version-scanner): configure GHA to use targets file for multi-v…
chalmerlowe Jun 23, 2026
8fc7e61
chore(version-scanner): limit GHA workflow to scan only handwritten a…
chalmerlowe Jun 23, 2026
9f612da
refactor(version-scanner): rename targets file to matrix file to reso…
chalmerlowe Jun 23, 2026
d835491
refactor(version-scanner): rename package list file to example-list-n…
chalmerlowe Jun 23, 2026
66eabc1
fix(version-scanner): address reviewer feedback regarding encoding, f…
chalmerlowe Jun 23, 2026
055975c
feat(version-scanner): support globbing and subpath patterns in ignor…
chalmerlowe Jun 23, 2026
8abd504
feat(version-scanner): implement targeted namespaced ignore pragmas
chalmerlowe Jun 23, 2026
a015856
fix(version_scanner): cast rule name and version to string in re.escape
chalmerlowe Jun 25, 2026
6af4f33
Merge branch 'main' into feat/version-scanner-pr3
chalmerlowe Jun 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions scripts/version_scanner/tests/unit/test_version_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,56 @@ def test_scan_file_ignores_pragma(tmp_path):
results = scan_file(str(test_file), rules)
assert len(results) == 0


def test_scan_file_ignores_targeted_pragma(tmp_path):
test_file = tmp_path / "test.py"
test_file.write_text("python_requires = '>=3.7' # version-scanner: ignore-rule=python_requires_check:3.7\n")

rules = [
{
"name": "python_requires_check",
"pattern": re.compile(r"python_requires\s*=\s*['\"]>=3\.7['\"]"),
"version": "3.7"
}
]

results = scan_file(str(test_file), rules)
assert len(results) == 0


def test_scan_file_handles_non_string_rule_name_and_version(tmp_path):
test_file = tmp_path / "test.py"
test_file.write_text("python_requires = '>=3.7' # version-scanner: ignore-rule=123:3.7\n")

rules = [
{
"name": 123, # Integer rule name
"pattern": re.compile(r"python_requires\s*=\s*['\"]>=3\.7['\"]"),
"version": 3.7 # Float version
}
]

# This should not raise TypeError
results = scan_file(str(test_file), rules)
assert len(results) == 0



def test_scan_file_does_not_ignore_mismatched_targeted_pragma(tmp_path):
test_file = tmp_path / "test.py"
test_file.write_text("python_requires = '>=3.7' # version-scanner: ignore-rule=python_requires_check:3.8\n")

rules = [
{
"name": "python_requires_check",
"pattern": re.compile(r"python_requires\s*=\s*['\"]>=3\.7['\"]"),
"version": "3.7"
}
]

results = scan_file(str(test_file), rules)
assert len(results) == 1

def test_scan_file_ignores_next_line(tmp_path):
test_file = tmp_path / "test.py"
test_file.write_text("# version-scanner: ignore-next-line\npython_requires = '>=3.7'\n")
Expand Down
7 changes: 6 additions & 1 deletion scripts/version_scanner/version_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,16 @@ def scan_file(file_path: str, compiled_rules: List[Dict[str, re.Pattern]]) -> Li
if "version-scanner: ignore-next-line" in line:
skip_next = True
continue
if "version-scanner: ignore" in line:
if "version-scanner: ignore" in line and "version-scanner: ignore-rule" not in line and "version-scanner: ignore-next-line" not in line:
continue
for rule in compiled_rules:
match = rule["pattern"].search(line)
if match:
version = rule.get("version")
if version:
pragma_pattern = rf"version-scanner\s*:\s*ignore-rule\s*=\s*{re.escape(str(rule['name']))}\s*:\s*{re.escape(str(version))}"
if re.search(pragma_pattern, line, re.IGNORECASE):
continue
Comment thread
chalmerlowe marked this conversation as resolved.
results.append({
"rule_name": rule["name"],
"line_number": line_num,
Expand Down
Loading