Skip to content

fix(io): materialize transition validators from dict definitions#629

Closed
csentis wants to merge 1 commit into
fgmacedo:developfrom
csentis:fix/io-materialize-validators
Closed

fix(io): materialize transition validators from dict definitions#629
csentis wants to merge 1 commit into
fgmacedo:developfrom
csentis:fix/io-materialize-validators

Conversation

@csentis

@csentis csentis commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

create_machine_class_from_definition builds each Transition with cond, unless, on, before, and after from the definition — but dropped validators. So a validators entry in a dict/JSON definition was silently ignored and never ran at send(). The TransitionDict TypedDict also mistyped validators as bool.

This PR:

  • threads validators through to Transition(...) in create_machine_class_from_definition;
  • corrects the TransitionDict.validators annotation to the same callback-spec union as cond/unless;
  • adds a regression test (tests/test_io.py::TestTransitionValidators) proving a definition-supplied validator runs and aborts on send() (the test fails without the production change).

Why

Transition.__init__ already accepts validators=; only the dict adapter wasn't passing it. Validators are the documented explicit-rejection channel (raise with a reason) — without this, dict/JSON-defined machines can't use it.

Notes

  • Two-line production change + type fix; no behavior change for definitions that don't set validators.
  • ruff check clean; pytest tests/test_io.py green (4 passed).

Closes #628

create_machine_class_from_definition threaded cond/unless/on/before/after
into Transition(), but dropped validators — so a 'validators' entry in a
dict/JSON definition was silently ignored and never ran at send(). The
TransitionDict TypedDict also mistyped validators as bool.

Pass validators through to Transition() and fix the type to the same
callback-spec union as cond/unless. Adds a regression test proving a
definition-supplied validator runs (and aborts) on send().

Closes #<issue>.

Signed-off-by: Christian Sentis <christian.sentis@icloud.com>
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (10b063f) to head (2c90212).

Additional details and impacted files
@@            Coverage Diff            @@
##           develop      #629   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           42        42           
  Lines         4976      4976           
  Branches       812       812           
=========================================
  Hits          4976      4976           
Flag Coverage Δ
unittests 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

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

@fgmacedo

Copy link
Copy Markdown
Owner

Hi @csentis, thanks for the careful fix and the regression test. You spotted a real bug: a validators entry in a dict/JSON definition was silently dropped, and the TransitionDict type was wrong too.

I've merged your change into develop via cherry-pick, with your authorship preserved. I couldn't merge the PR directly because the io/ module was refactored after you opened it: TransitionDict and create_machine_class_from_definition moved out of statemachine/io/__init__.py into a new statemachine/io/class_factory.py, which is what caused the conflict. Your two-line change applied cleanly to the new location, and your test came along unchanged.

One tiny follow-up on top (separate commit, not yours): the test asserted on sm.current_state, which is now deprecated in favor of configuration, so I switched it to assert "s1" in sm.configuration_values to avoid the deprecation warning.

Closing this PR since the commit is already on develop. Thanks again for the contribution!

@fgmacedo fgmacedo closed this Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

validators in a dict/JSON transition definition is silently dropped

2 participants