From 7d4c602ccc0f3959ed80d5dd9ed28483e9464478 Mon Sep 17 00:00:00 2001 From: dxnnystyles Date: Mon, 26 Oct 2026 11:10:54 -0700 Subject: [PATCH] docs: clarify optional dependency lock exclusions --- requirements-lock.txt | 6 ++++++ tests/test_dependency_versions.py | 33 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/requirements-lock.txt b/requirements-lock.txt index f7b5acd9..86b50a38 100644 --- a/requirements-lock.txt +++ b/requirements-lock.txt @@ -8,6 +8,12 @@ # # Install with: pip install -r requirements-lock.txt # (faircode itself is installed separately, in editable mode, from this checkout: pip install -e ".[benchmark]") +# This results-reproduction lock intentionally excludes optional tools outside the benchmark environment: +# certifi - only used by the external-link checker's trust-store fallback +# mcp - only used by the optional MCP server +# playwright - only used by the optional browser tests +# pyarrow - only used by the optional parquet extra +# pytest-cov - only used by the optional coverage/test tooling appnope==0.1.4 asttokens==3.0.2 diff --git a/tests/test_dependency_versions.py b/tests/test_dependency_versions.py index 921ecb0d..9a5600e6 100644 --- a/tests/test_dependency_versions.py +++ b/tests/test_dependency_versions.py @@ -43,6 +43,39 @@ def test_requirements_lock_versions_satisfy_pyproject_minimums(): ) +def test_every_project_dependency_is_locked_or_documented_as_excluded(): + root = Path(__file__).resolve().parents[1] + pyproject_text = (root / "pyproject.toml").read_text(encoding="utf-8") + lock_text = (root / "requirements-lock.txt").read_text(encoding="utf-8") + + core_section = re.search(r"(?ms)^\[project\]\s*(.*?)(?=^\[project\.optional-dependencies\])", pyproject_text) + optional_section = re.search(r"(?ms)^\[project\.optional-dependencies\]\s*(.*?)(?=^\[)", pyproject_text) + assert core_section is not None and optional_section is not None + dependency_arrays = re.findall( + r"(?ms)^\s*dependencies\s*=\s*\[(.*?)^\s*\]", core_section.group(1) + ) + dependency_arrays.extend( + re.findall(r"(?ms)^\s*[A-Za-z0-9_-]+\s*=\s*\[(.*?)\]", optional_section.group(1)) + ) + declared = set() + for array in dependency_arrays: + for requirement in re.findall(r'[\"\']([^\"\']+)[\"\']', array): + match = re.match(r"([A-Za-z0-9_.-]+)", requirement) + assert match is not None, f"could not parse dependency requirement: {requirement}" + declared.add(normalize_dependency(match.group(1))) + locked = { + normalize_dependency(name) + for name in re.findall(r"^([A-Za-z0-9_.-]+)==", lock_text, re.MULTILINE) + } + excluded = { + normalize_dependency(name) + for name in re.findall(r"^# ([A-Za-z0-9_.-]+) - .+", lock_text, re.MULTILINE) + } + + assert declared - locked == excluded + assert excluded, "document intentional exclusions in requirements-lock.txt" + + def version_tuple(version): return tuple(int(part) for part in version.split("."))