Skip to content

Add the --allow-blocking-problems option to rubem run - #355

Merged
soaressgabriel merged 5 commits into
mainfrom
feat/352-allow-blocking-problems
Sep 22, 2026
Merged

soaressgabriel merged 5 commits into
mainfrom
feat/352-allow-blocking-problems

Conversation

@soaressgabriel

Copy link
Copy Markdown
Collaborator

Checklist

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?
  • Added tests for changed code.
  • Updated documentation for changed code.

Description

  • ModelConfiguration(..., allow_blocking_problems=False), also on ModelConfiguration.load: the same checks run and every problem stays in ModelConfiguration.problems. With the keyword the blocking problems are logged at ERR (the non-blocking ones stay at WRN), one final ERR line states that the simulation continues despite N blocking problem(s), and the configuration loads instead of raising ConfigurationError. Without it nothing changes: every problem is logged at WRN and the blocking ones raise, the zero-denominator domains (Tw >= 1, C_wp >= 1) included.
  • rubem run --allow-blocking-problems (no short form) passes the keyword through. Combined with -s/--skip-inputs-validation it is a usage error (exit code 2, raised before anything else runs), since -s skips the very checks the option reports. Failures that are not Problems stay fatal: schema validation, a missing lookup table file, no raster format enabled, the DEM/clone/georeference mismatch. Exit code 0 when the forced run completes, 1 when it fails. The option is not added to _LEGACY_OPTIONS, so rubem -c <config> --allow-blocking-problems is rejected with exit code 2.
  • Python API: Add the programmatic Python API #342 landed first, so this side exposes the keyword on the same path as validate_input. Model.from_file(..., allow_blocking_problems=False) and Model.from_config(..., allow_blocking_problems=False) hand it to the loader; Model keeps it next to the validation flag and Model.run_isolated passes both to the subprocess, so the rebuild there does not raise. For an already loaded configuration the keyword only rules the rebuild, like validate_input. The documented signatures pinned by tests/unit/api gain the keyword; the child entry points of those tests take the extra argument.
  • Tests. Loader (tests/unit/configuration/test_validation_tiers.py): the blocking problems are kept and logged at ERROR, the non-blocking ones at WARNING, the closing line, the default still raises, nothing is reported without blocking problems, load passes the keyword through. Command line (tests/unit/test_cli_run.py): a rainy days table without December (a blocking problem the January and February run never reads) exits 1 by default and runs with the option with the ERR lines on stderr; the option is silent without blocking problems; a forced run over a missing precipitation step starts and exits 1; a document that does not parse still exits 1; -s and --skip-inputs-validation with the option exit 2; the legacy spelling exits 2; the help lists the option. Subprocess (tests/integration/test_cli.py): the usage error, and a forced run over the same broken table that reproduces the goldens. API (tests/unit/api/test_model.py): both loaders, an in-process run, the isolated run with the keyword and with an already loaded configuration.
  • Docs: the rubem run -h block and a paragraph contrasting -s with the new option (exit codes, the usage error, what stays fatal, the output of a forced run) in the user guide; the keyword of the loaders and the subprocess rebuild on the Python API page; changelog entry under Added.

Related Issue

Motivation and context

  • Neither mode of rubem run let a user run past a blocking problem and still see it: the default stops with exit code 1, and -s runs blind, since the content checks do not run at all (the lookup table checks, the runoff coefficient domain, the series resolver checks and the grid cell size check among them). Exploring a dataset, or reproducing a published run whose inputs fail a check, needs a third mode that keeps the checks and their report but not the stop.

How has this been tested

  • python -m pytest -n auto -ra -p no:cacheprovider --ignore=tests/integration/doc: 1329 passed, 1 skipped (the byte-exact golden test, CI-only), on this branch (Linux, Python 3.13.7, PCRaster 4.4.2, GDAL 3.11.5).
  • uvx ruff@0.16.4 format --check . and uvx ruff@0.16.4 check .: clean. codespell 2.4.3 on the changed files: clean.
  • sphinx-build -W -b html on Python 3.13 from a clean export of the branch: no warnings.
  • The three published basins (Upper Iguaçu, Ipojuca and Piracicaba), three monthly steps each (January to March 2000), with one LDD computed per basin and pinned in every manifest so that the runs are comparable, and a copy of the rainy days table without December (a blocking problem those steps never read). Per basin: the baseline exits 0; the broken table exits 1 by default and writes nothing; with --allow-blocking-problems the run exits 0, the problem is logged at ERR with the "Simulation continues despite 1 blocking problem(s)." line, and its 36 output files are byte-identical to the baseline's; -s --allow-blocking-problems exits 2; the legacy spelling with the option exits 2. The dataset files were not modified (the manifests and the table copy live in a scratch directory).

Left as written, for the reviewer:

  • The open point of the issue, recording the blocking problems of a forced run in metadata.json (format 1.0 only), is not implemented here: it changes the metadata document and deserves its own decision.
  • The alternative of relaxing only the data domain problems and keeping the structural ones blocking is not taken either, as the issue leaves it: Problem carries no such attribute. A forced run over a structural problem starts and fails inside the run with exit code 1, which the user guide states and a test pins.
  • Add the rubem calibrate command #344 (rubem calibrate) is still open: when it rebases it finds the keyword on the loaders; whether its single validated load should take it is a decision for that PR.
  • The baseline runs of the published basins report four non-blocking problems (land use series gaps, a raster data rule violation, kc_max < kc_min, area fractions of class 0), untouched here.

Screenshots

  • N/A

By default every check of the input validation runs, the problems are
logged as warnings and a blocking one raises ConfigurationError, so the
run stops with exit code 1; with -s the content checks do not run at all.
Neither lets a user run past a blocking problem and still see it.

ModelConfiguration takes allow_blocking_problems=False. With it the same
checks run, every problem stays in ModelConfiguration.problems, the
blocking ones are logged at ERR, a final ERR line states that the
simulation continues despite N blocking problem(s), and the configuration
loads instead of raising. ModelConfiguration.load passes it through.

rubem run --allow-blocking-problems (no short form) hands the keyword
through. It cannot be combined with -s, which skips the very checks the
option exists to report: that is a usage error with exit code 2, raised
before anything else runs. Failures that are not problems (schema
validation, missing lookup table files, no raster format enabled, the
DEM/clone/georeference mismatch) stay fatal, and a forced run that fails
exits 1. The deprecated rubem -c <config> spelling does not take the
option.

Tests: the loader keeps and reports the problems at both levels, the
command line stops by default, runs with the option, refuses the
combination with -s, refuses the option on the legacy spelling, and a
forced run over a rainy days table without December (never read by the
January and February run) reproduces the goldens.
Model.from_file and Model.from_config take the keyword and hand it to
ModelConfiguration on the same path as validate_input; Model keeps it
next to the validation flag so that an isolated run rebuilds the
configuration in the subprocess with the same leniency instead of
raising ConfigurationError there. A configuration loaded elsewhere is
not checked again: for it the keyword only rules the rebuild.

The public signatures pinned by the tests gain the keyword; the child
entry points of the isolated-run tests take the extra argument.
The user guide shows the option in the rubem run -h block, contrasts it
with -s (checks skipped, nothing reported) and states the exit codes, the
usage error of the combination, the failures that stay fatal and what a
forced run prints. The Python API page describes the keyword of the
loaders and that an isolated run carries it across the process boundary.
@codecov

codecov Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.23810% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 92.87%. Comparing base (5165534) to head (cc0eaf8).

Files with missing lines Patch % Lines
rubem/api.py 87.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #355      +/-   ##
==========================================
+ Coverage   92.86%   92.87%   +0.01%     
==========================================
  Files          64       64              
  Lines        4357     4365       +8     
  Branches      556      558       +2     
==========================================
+ Hits         4046     4054       +8     
  Misses        248      248              
  Partials       63       63              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@soaressgabriel soaressgabriel self-assigned this Sep 22, 2026
@soaressgabriel
soaressgabriel merged commit dc80787 into main Sep 22, 2026
17 checks passed
@soaressgabriel
soaressgabriel deleted the feat/352-allow-blocking-problems branch September 22, 2026 15:58
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.

Add a run option that reports blocking configuration problems without stopping the simulation

2 participants