Skip to content

BUG: validation in stochastic/ that survives python -O - #1111

Merged
Gui-FernandesBR merged 1 commit into
RocketPy-Team:developfrom
thc1006:bug/validation-that-survives-optimisation
Aug 8, 2026
Merged

BUG: validation in stochastic/ that survives python -O#1111
Gui-FernandesBR merged 1 commit into
RocketPy-Team:developfrom
thc1006:bug/validation-that-survives-optimisation

Conversation

@thc1006

@thc1006 thc1006 commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Addresses the TODO at the top of stochastic_model.py, and the point you raised on #1102:

# TODO: Stop using assert in production code. Use exceptions instead.

The reason it matters is that the optimiser removes them, so the checks stop running and malformed input reaches the model instead of being refused:

StochasticModel(obj, mass=("not a number", 0.5))

  python      AssertionError: 'mass': First item of tuple must be an int or float
  python -O   accepted, mass = ('not a number', 0.5, <bound method Generator.normal>)

That model then fails somewhere later with something that does not point back at the tuple that caused it.

Twenty one of them, all in stochastic/:

file count
stochastic_model.py 13
stochastic_environment.py 3
stochastic_flight.py 3
stochastic_aero_surfaces.py 1
stochastic_parachute.py 1, the one #1103 did not reach

Converted through the AST rather than by hand, so the condition and the message are the ones that were already there. ruff then collapsed not (x in y) to not in where it applied.

AssertionError is kept rather than swapped for TypeError or ValueError. The docstrings document it and callers catching it should keep working. Changing the type is a separate decision from making the check run at all, and I would rather not fold the two together.

Two kinds of test. One reads each module and fails on a reintroduced assert, which is the mechanism. The other runs a child interpreter under -O, because in process the assert is still compiled in and an ordinary test passes either way. Reintroducing one assert fails both, which is how I checked they have teeth.

Also moves two imports in test_custom_sampler.py to the top of the file. pylint reports C0415 on them on develop today, from the cherry-pick of 23be0bab, so pylint rocketpy/ tests/ docs/ currently exits 16 rather than 0.

Local: ruff and format clean, pylint exit 0, 2086 passed and 44 skipped.

`stochastic_model.py` has carried this as a TODO:

    # TODO: Stop using assert in production code. Use exceptions instead.

The reason it matters is that the optimiser removes them, so the checks stop
running and malformed input reaches the model:

    StochasticModel(obj, mass=("not a number", 0.5))

    python      AssertionError
    python -O   accepted, mass = ('not a number', 0.5, <Generator.normal>)

That model then fails somewhere later with something that does not point back
at the tuple that caused it.

Twenty one of them, all in stochastic/: thirteen in stochastic_model.py, three
each in stochastic_environment.py and stochastic_flight.py, one in
stochastic_aero_surfaces.py, and the one in stochastic_parachute.py that RocketPy-Team#1103
did not reach. Converted mechanically through the AST, so the condition and the
message are the ones that were there.

AssertionError is kept rather than swapped for TypeError or ValueError. The
docstrings document it, and callers catching it should keep working. Changing
the type is a separate decision from making the check run at all.

Two kinds of test. One reads each module and fails on a reintroduced `assert`,
which is the mechanism. The other runs a child interpreter under -O, because in
process the assert is still compiled in and the check would pass either way.

Also moves two imports in test_custom_sampler.py to the top of the file, which
pylint flags as C0415 on develop today.

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
@thc1006
thc1006 requested a review from a team as a code owner August 8, 2026 14:08
@codecov

codecov Bot commented Aug 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 21.42857% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.51%. Comparing base (e0ff281) to head (a91c508).
⚠️ Report is 40 commits behind head on develop.

Files with missing lines Patch % Lines
rocketpy/stochastic/stochastic_model.py 30.76% 18 Missing ⚠️
rocketpy/stochastic/stochastic_environment.py 0.00% 6 Missing ⚠️
rocketpy/stochastic/stochastic_flight.py 16.66% 5 Missing ⚠️
rocketpy/stochastic/stochastic_aero_surfaces.py 0.00% 2 Missing ⚠️
rocketpy/stochastic/stochastic_parachute.py 0.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1111      +/-   ##
===========================================
+ Coverage    82.18%   82.51%   +0.33%     
===========================================
  Files          122      128       +6     
  Lines        16355    16617     +262     
===========================================
+ Hits         13441    13712     +271     
+ Misses        2914     2905       -9     

☔ 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.

thc1006 added a commit to thc1006/RocketPy that referenced this pull request Aug 8, 2026
Two boundaries on `random_seed` that the docstring implied more of than it
should. Both were raised on review.

What a seed reproduces is the sampled values. With `include_function_data=True`
a record also carries a `Function`'s signature hash and serialised source,
which describe the object rather than the value drawn for it, so a run under
spawn or forkserver writes different ones for the same inputs. The
cross-start-method test measured six such fields and filters exactly them.

And it is scoped to one environment. NumPy promises a stream only for the same
BitGenerator, seed, call sequence, build and machine, and reserves the right to
change what `default_rng` returns. A seed fixes the lineage of a run; it is not
an archive format that survives a version bump.

Also moves two imports in test_custom_sampler.py to the top of the file. They
arrived on develop with the cherry-pick of 23be0ba, which was the version
before that fix, and pylint exits 16 on them. RocketPy-Team#1111 does the same thing as part
of a wider change; this is here because it is what turns this branch's lint red.

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
@Gui-FernandesBR
Gui-FernandesBR merged commit 25271f4 into RocketPy-Team:develop Aug 8, 2026
11 checks passed
@thc1006
thc1006 deleted the bug/validation-that-survives-optimisation branch August 8, 2026 17:55
Gui-FernandesBR pushed a commit to thc1006/RocketPy that referenced this pull request Aug 12, 2026
Two boundaries on `random_seed` that the docstring implied more of than it
should. Both were raised on review.

What a seed reproduces is the sampled values. With `include_function_data=True`
a record also carries a `Function`'s signature hash and serialised source,
which describe the object rather than the value drawn for it, so a run under
spawn or forkserver writes different ones for the same inputs. The
cross-start-method test measured six such fields and filters exactly them.

And it is scoped to one environment. NumPy promises a stream only for the same
BitGenerator, seed, call sequence, build and machine, and reserves the right to
change what `default_rng` returns. A seed fixes the lineage of a run; it is not
an archive format that survives a version bump.

Also moves two imports in test_custom_sampler.py to the top of the file. They
arrived on develop with the cherry-pick of 23be0ba, which was the version
before that fix, and pylint exits 16 on them. RocketPy-Team#1111 does the same thing as part
of a wider change; this is here because it is what turns this branch's lint red.

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
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.

2 participants