Skip to content

refactor: split gpschecks.py into a subpackage (#197) - #267

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

refactor: split gpschecks.py into a subpackage (#197)#267
iabaako wants to merge 1 commit into
refactor/197-split-backchecks-modulefrom
refactor/197-split-gpschecks-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/gpschecks.py (2,238 lines) into a subpackage, src/datasure/checks/gpschecks/:

  • models.py — module constants (TAB_NAME, MAPBOX_STYLE, _CATEGORY_COLORS); no local Pydantic models were needed since GPSSettings/GPSColumnConfig/related enums already live in datasure.models
  • compute.py — pure GPS-parsing/outlier-detection functions (no Streamlit calls)
  • settings_ui.pygpschecks_report_settings and its config-UI helpers
  • report_ui.pygpschecks_report and its report-rendering UI, including the GPS column-configuration CRUD group (which, like the equivalent group in the backchecks split, turned out to be called only from the report entry point, not settings) and the Plotly/pydeck chart-rendering functions (kept here rather than compute.py since they call st.pydeck_chart/st.secrets directly, not just build-and-return a chart object)
  • __init__.py — left empty, matching every other package in this repo

Also eliminates three intra-file duplicates found while splitting:

  • _get_gps_column_settings/_save_gps_column_settings replace an identical duckdb_get_table/duckdb_save_table pair repeated across 6 call sites
  • _identity_optional_fields dedupes 5 call sites that built (col, col) tooltip/display field pairs
  • _filter_available_columns/_render_table_with_csv_download replace a repeated "filter to available columns → display → CSV download" block

Tests are mirrored into tests/checks/gpschecks/{conftest,test_models,test_compute,test_settings_ui,test_report_ui}.py, replacing the 2,757-line tests/checks/test_gpschecks.py.

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

Why is this change needed? 🤔

Per #197: gpschecks.py mixed GPS parsing/outlier-detection computation with two distinct Streamlit UI flows (settings vs. report) in one 2,238-line file.

How was this implemented? 🛠️

Pure mechanical reorganization — no logic changes, aside from the three documented deduplications above (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 gpschecks_report directly from datasure.checks.gpschecks.report_ui. The generated, gitignored output_view_1.py was left untouched, per this repo's convention of never editing generated output views directly.

How to test or reproduce ? 🧪

  1. uv run python -m pytest tests/checks/gpschecks --cov=datasure.checks.gpschecks --cov-report=term-missing -q — 113/113 tests pass (exact match to the pre-split count), coverage improved from 95.18% to 95.36%
  2. uv run python -m pytest -q -m "not slow" — full suite passes, same pre-existing skips
  3. Confirm the GPS Checks report page in the app still renders (map, outlier detection, comparison checks), 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) — ~3,600 lines changed, but this is a pure file-move/reorganization plus three 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 2,238-line checks/gpschecks.py into models/compute/
settings_ui/report_ui submodules, mirroring the enumerator and
backchecks splits. __init__.py stays empty per convention;
output_view_template.py now imports gpschecks_report directly from
datasure.checks.gpschecks.report_ui.

Also eliminates three intra-file duplicates found while splitting:
_get_gps_column_settings/_save_gps_column_settings replace a repeated
duckdb load/save pair (6 call sites), _identity_optional_fields dedupes
5 call sites building (col, col) tooltip field pairs, and
_filter_available_columns/_render_table_with_csv_download replace a
repeated filter-then-display-then-download block. No behavior change.

Tests mirrored into tests/checks/gpschecks/ with no logic changes;
113/113 tests pass, coverage improved from 95.18% to 95.36%.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@iabaako
iabaako requested a review from a team as a code owner August 7, 2026 21:50
@sonarqubecloud

sonarqubecloud Bot commented Aug 7, 2026

Copy link
Copy Markdown

@iabaako iabaako linked an issue Aug 7, 2026 that may be closed by this pull request
MAPBOX_STYLE = "mapbox://styles/mapbox/light-v9"

# Distinct color palette (RGBA) for categorical coloring on maps
_CATEGORY_COLORS: list[list[int]] = [
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