Skip to content

fix: mark compound states nested in parallel states as active - #652

Merged
fgmacedo merged 4 commits into
fgmacedo:developfrom
MartinBernstorff:fix/nested-parallel-is-active
Oct 11, 2026
Merged

fgmacedo merged 4 commits into
fgmacedo:developfrom
MartinBernstorff:fix/nested-parallel-is-active

Conversation

@MartinBernstorff

@MartinBernstorff MartinBernstorff commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #651

I haven't dug into the code myself; I had an LLM write this, and glanced at the solution. Feel free to close.

A compound state nested inside a parallel region was reported as inactive
when reached through an attribute chain (e.g. `sm.door.shut`), even though
it was present in the configuration. `sm.shut` (accessed directly) worked
because it resolves to an `InstanceState` proxy, but `sm.door.shut`
returned the raw class-level `State`, whose `is_active` is a stale
attribute fixed to `False`.

Root cause: `InstanceState.__init__` ran `_init_states()`, which set the
raw child `State` objects directly on the proxy's `__dict__` (bypassing
the delegating `__getattr__`) and mutated the shared raw children's
`parent`. Now children are resolved lazily: `__getattr__` maps a declared
child (or history) state to the machine's per-instance proxy via the new
`Configuration.instance_state()`, so `is_active` is consistent regardless
of access path.

Fixes fgmacedo#651

Signed-off-by: Martin Bernstorff <martinbernstorff@gmail.com>

@fgmacedo fgmacedo left a comment •

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @MartinBernstorff, welcome! This is your first contribution here, and the minimal reproducer in #651 plus the PR with a test made this quick to verify. Thanks for the time you put into it.

Blocking: parent reached from a proxy regressed to the raw State (inline, with a one-line fix). The other comments are non-blocking.

Comment thread statemachine/state.py Outdated
Comment thread statemachine/state.py Outdated
Comment thread tests/test_statechart_parallel.py
Comment thread statemachine/configuration.py Outdated
@codecov

codecov Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (cb3bc41) to head (f1ec945).

Additional details and impacted files
@@            Coverage Diff            @@
##           develop      #652   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           52        52           
  Lines         5648      5651    +3     
  Branches       887       888    +1     
=========================================
+ Hits          5648      5651    +3     
Flag Coverage Δ
unittests 100.00% <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.

Review follow-up for fgmacedo#652:

- resolve every State-valued attribute of an InstanceState to its
  per-instance proxy, so `parent` no longer returns the raw State
- hand the instance_states mapping to the proxy at construction instead
  of reaching it through `machine._config`
- pin proxy identity and cross-instance isolation in tests
- unify assertion argument order (Sonar S3415)

Signed-off-by: Fernando Macedo <fgmacedo@gmail.com>
Signed-off-by: Fernando Macedo <fgmacedo@gmail.com>
@sonarqubecloud

Copy link
Copy Markdown

@fgmacedo
fgmacedo merged commit 0de640a into fgmacedo:develop Oct 11, 2026
10 checks passed
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.

bug: compound states nested in parallel states are not marked as active

2 participants