Skip to content

refactor: split backchecks.py into a subpackage (#197) - #266

Open
iabaako wants to merge 1 commit into
refactor/197-split-enumerator-modulefrom
refactor/197-split-backchecks-module
Open

refactor: split backchecks.py into a subpackage (#197)#266
iabaako wants to merge 1 commit into
refactor/197-split-enumerator-modulefrom
refactor/197-split-backchecks-module

Conversation

@iabaako

@iabaako iabaako commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Pull Request Summary 🚀

What does this PR do? 📝

Splits src/datasure/checks/backchecks.py (4,252 lines) into a subpackage, src/datasure/checks/backchecks/:

  • models.py — Pydantic settings/result models, StrEnums, and module constants
  • compute.py — pure compute_*/_calculate_*/_add_*_columns data-processing functions (no Streamlit calls)
  • settings_ui.pybackchecks_report_settings and its config-UI helpers
  • report_ui.pybackchecks_report and its report-rendering UI helpers (including the backcheck-column-configuration UI, which turned out to be called only from the report entry point, not settings)
  • __init__.py — left empty, matching every other package in this repo

Also eliminates two intra-file duplicates found while splitting:

  • _render_no_differences_settings/_render_exclude_values_settings shared an identical add/remove-popover list-editor pattern → extracted _render_value_list_editor, with a guard_remove_membership flag preserving the one subtle behavioral difference between the two callers
  • _add_extra_survey_columns/_add_extra_backcheck_columns shared a select→rename→suffix→join pattern → extracted _join_extra_columns

Tests are mirrored into tests/checks/backchecks/{conftest,test_models,test_compute,test_settings_ui,test_report_ui}.py, replacing the 4,303-line tests/checks/test_backchecks.py.

This is the second of four planned splits tracked by #197 (enumerator done in #265, gpschecks/outliers still pending), stacked on top of refactor/197-split-enumerator-module since that PR is still open.

Why is this change needed? 🤔

Per #197: backchecks.py was the largest and hardest-to-review check module. It mixed settings models, pure computation, and two distinct Streamlit UI flows (settings vs. report) in one 4,252-line file.

How was this implemented? 🛠️

Pure mechanical reorganization — no logic changes, aside from the two documented deduplications above (both verified to produce identical output via the existing test suite). Grepped the full src/ tree to confirm only output_view_template.py imports from this module externally, and updated it to import backchecks_report directly from datasure.checks.backchecks.report_ui instead of relying on package re-exports. The generated, gitignored output_view_1.py was left untouched, per this repo's convention of never editing generated output views directly — it's regenerated from the template.

How to test or reproduce ? 🧪

  1. uv run python -m pytest tests/checks/backchecks --cov=datasure.checks.backchecks --cov-report=term-missing -q — 220/220 tests pass (exact match to the pre-split count), coverage improved from 89.95% to 91.34%
  2. uv run python -m pytest -q -m "not slow" — full suite passes, same pre-existing skips
  3. Confirm the Backchecks report page in the app still renders, and its settings still save/load correctly

Screenshots (if applicable) 📷

N/A — no UI or behavior changes.

Checklist ✅

  • I have run and tested my changes locally
  • I have limit this PR to less than 1000 lines of code change (if not, explain why) — ~5,900 lines changed, but this is a pure file-move/reorganization plus two small, verified dedup extractions; splitting it into multiple PRs would fragment a single mechanical refactor for no review benefit
  • I have updated/added tests to cover my changes (if applicable)
  • I have updated/added requirements to cover my changes (if applicable)
  • I have run linting and formatting on any code changes (if applicable)
  • I have updated the documentation (README, etc.) accordingly
  • I have reviewed and resolved any merge conflict

🤖 Generated with Claude Code

Splits the 4,252-line checks/backchecks.py into models/compute/
settings_ui/report_ui submodules, mirroring the enumerator split.
__init__.py stays empty per convention; output_view_template.py now
imports backchecks_report directly from
datasure.checks.backchecks.report_ui.

Also eliminates two intra-file duplicates found while splitting:
_render_no_differences_settings/_render_exclude_values_settings share
a new _render_value_list_editor, and _add_extra_survey_columns/
_add_extra_backcheck_columns share a new _join_extra_columns. No
behavior change.

Tests mirrored into tests/checks/backchecks/ with no logic changes;
220/220 tests pass, coverage improved from 89.95% to 91.34%.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@iabaako
iabaako requested a review from a team as a code owner August 7, 2026 20:26
@iabaako iabaako linked an issue Aug 7, 2026 that may be closed by this pull request
@sonarqubecloud

sonarqubecloud Bot commented Aug 7, 2026

Copy link
Copy Markdown

sys.modules["streamlit"] = mock_st

import datasure.checks.backchecks.compute as compute_module
import datasure.checks.backchecks.report_ui as report_ui_module
sys.modules["streamlit"] = mock_st

import datasure.checks.backchecks.compute as compute_module
import datasure.checks.backchecks.settings_ui as settings_ui_module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Split oversized check modules (post-1.0)

1 participant