chore: extend ruff rule selection for the analytics package (#4942) - #4943
Open
hunterckx wants to merge 5 commits into
Open
chore: extend ruff rule selection for the analytics package (#4942)#4943hunterckx wants to merge 5 commits into
hunterckx wants to merge 5 commits into
Conversation
Adds the flake8-comprehensions, flake8-pie and pyupgrade rule categories to the analytics ruff selection, bringing it closer to the selection used in clevercanary/hca-validation-tools. All three are already clean, so this commit changes no code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the flake8-simplify rule category to the analytics ruff selection and collapses the one `if`/`else` block it flags into a ternary. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the ruff-specific rule category to the analytics ruff selection, replacing a single-element tuple concatenation with unpacking and sorting the `static_site` package's `__all__`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the flake8-return rule category to the analytics ruff selection, returning expressions directly instead of assigning them first and dropping two `else` branches that follow a `return`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the flake8-use-pathlib rule category to the analytics ruff selection and moves the static site's path handling and file I/O from `os.path`, `os` and `glob` to `pathlib`. `output_dir` is normalized to a `Path` where it enters `generate_site` and `export_data`, so callers can keep passing strings. `os.makedirs` becomes `Path.mkdir(parents=True, ...)` to preserve parent creation, and the absolute path printed at the end of a run now comes from `Path.resolve()`, which additionally resolves symlinks. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Extends Ruff coverage for the analytics package and applies lint-driven refactors, including migration of static-site file handling to pathlib.
Changes:
- Adds seven Ruff rule categories.
- Simplifies control flow, returns, tuple construction, and exports.
- Refactors static-site path and file operations to use
pathlib.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Summary |
|---|---|
analytics/pyproject.toml |
Expands Ruff rule selection. |
analytics/analytics_package/analytics/static_site/generator.py |
Uses Path for site generation paths. |
analytics/analytics_package/analytics/static_site/export.py |
Uses Path for exports and cleanup. |
analytics/analytics_package/analytics/static_site/__init__.py |
Sorts __all__. |
analytics/analytics_package/analytics/report_elements.py |
Removes redundant else branches. |
analytics/analytics_package/analytics/api.py |
Applies tuple, conditional, and return simplifications. |
analytics/analytics_package/analytics/_report_utils.py |
Returns computed expressions directly. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
(Text via Claude)
Closes #4942
What changed
Extends the ruff
selectlist inanalytics/pyproject.tomlfrom["E4", "E7", "E9", "F", "I", "W", "B"]to addC4,PIE,PTH,RET,RUF,SIMandUP, and fixes every violation the new categories surface.One commit per rule category, each enabling the category and fixing its violations together, so each reviews independently and a regression traces back to one rule:
C4,PIE,UPSIMSIM108:if/else→ ternary inapi.pyRUFRUF005tuple unpacking inapi.py;RUF022sorted__all__instatic_site/__init__.pyRETRET504(assign-then-return) in_report_utils.pyandapi.py; 2×RET505(elseafterreturn) inreport_elements.pyPTHos.path/os/glob→pathlibinstatic_site/export.py(26) andstatic_site/generator.py(7)The
PTHcommit is the bulk of the work and the only real refactor.output_diris normalized to aPathat each public entry point (generate_siteandexport_data), so the fourgenerate_static_site.pyscripts keep passing plain strings;os.makedirsbecomesPath.mkdir(parents=True, exist_ok=True); the stale-detail-file sweep becomesPath.glob+Path.unlink; and everyopen(os.path.join(...))becomes(output_dir / name).open(...).Why
#4934 / #4936 added ruff to the analytics package with a deliberately minimal rule selection — enough to catch the star-import re-export leak that motivated it, but well short of what
clevercanary/hca-validation-toolsalready runs on Python. Two Clever Canary Python codebases linting to two different standards means review habits don't transfer between them, and this package silently accumulates patterns that wouldn't survive review in the other repo.Assumptions I made
Estays narrowed toE4/E7/E9rather than taking all ofE, which is the one intentional deviation from hca-validation-tools' selection. The non-preview rules fullEwould add over that subset are exactlyE501(line-too-long) andE101(mixed-spaces-and-tabs) — both formatting concerns, and thereforeruff format's job. Keeping them out means the linter never duplicates or fights the formatter.selectlist only. hca-validation-tools' other lint settings (per-file-ignores,isort.known-first-party,line-length,target-version) are deliberately out of scope. Noper-file-ignoresentry was needed — every violation had a real fix, and no# noqasuppressions were added anywhere.PTHcommit is path-handling only. A review pass suggested collapsing the ~10 near-identicalopen→json.dump→print(f" Wrote …")blocks inexport.pyinto a shared_write_jsonhelper (net ≈ −16 lines). That repetition is pre-existing — this diff converted it, it didn't create it — so it was deliberately left alone to keep the commit reviewable against the rule it's named for. Filed as a follow-up instead.output_diraccepting eitherstrorPathwas chosen over converting the four caller scripts. Normalizing at the library boundary keeps those scripts as declarative literals and avoids touching four out-of-scope files. The docstrings now state the accepted types, since every sibling argument in them already did.os.path.abspath()→Path.resolve()also resolves symlinks, so the finalFiles written to: …line may differ on a symlinked path.Path("./site")stringifies assite, soanvil-catalog's closingcd ./site && …hint now printscd site && ….How to verify
The issue's definition of done, mapped to steps:
1.
npm run lint:pythonandnpm run check-format:pythonpass clean.2. The same steps pass in
run-checks.ymlCI. Check theanalyticsjob on this PR. To reproduce its exact sequence locally:3. Fresh-venv
generate_static_site.pyrun includinghistoric_data_path, with generated site output confirmed unchanged (per the #4913 verification convention).PTHrewrites path construction and file I/O inexport.pyandgenerator.py, so this checks output equality, not just importability:analytics/readme.md—.credentials/hca_ga4_credentials.jsonfor LungMAP.CURRENT_MONTHinanalytics/lungmap/constants.pyto the month you want.analytics/lungmap, runuv run python generate_static_site.pyand complete the browser OAuth flow. LungMAP is the right app here because it passeshistoric_data_path(HISTORIC_UA_DATA_PATH) and writes intogh-pages/lungmap, exercising the real output path.gh-pages/lungmaptree against the same run onmain. Expected: every file byte-identical exceptdata/meta.json'sgenerated_attimestamp.cd gh-pages && python -m http.server 8080, then open http://localhost:8080.Verification already performed:
historic_data_path: onlygenerated_atdiffers.generate_site(withfetch_datastubbed to canned data, includinghistoric_data_path) andexport_datadirectly, then fingerprinted every output file. Output is byte-identical betweenmainat e738381 and this branch across all 13 JSON files plusindex.html, with onlymeta.json'sgenerated_atnormalized. The harness also covers the two behavior-sensitive spots:mkdir(parents=True)creating a missing intermediate directory, and theglob/unlinksweep removing a staleevent_*_detail.jsonwhile leaving a neighbouring file untouched. Both matchmain.