Skip to content

Transition kinds: kind=external|local|internal across Python, YAML and SCXML #723

Open

Description

@fgmacedo

Why

Transition types today are a boolean internal= whose meaning depends on the source state, and it does not line up with either UML or SCXML. One parameter with three values, consistent across Python, JSON/YAML and SCXML, and between UML and SCXML, removes that ambiguity. Decided by the maintainer during #696 (which only fixes B3/B4/B7 and stays as is).

Design

kind on transitions: external (default), local, internal.

kind UML SCXML Exit/entry
external external type="external" domain is the LCCA
local local type="internal" with a compound source and descendant targets domain is the source; the source is not exited
internal internal transition without target none; configuration unchanged

to(None) is equivalent to kind="internal" (already the current behavior).

Strict validation (InvalidDefinition):

  • internal: target equal to the source or no target, on any kind of state.
  • local: source must not be atomic; every target must be a proper descendant of the source. local targeting the source itself is invalid (UML 2.5.1).
  • Passing both kind= and the deprecated internal= on the same transition (Python or native document) is invalid, even when they agree.

local with a parallel source follows XState v5 (verified by running it): the parallel state is not exited; all its regions exit and re-enter their defaults. SCXML-family engines exit the parallel; the final configuration is the same.

Engine: get_transition_domain has three branches: internal (no exit/entry), local (domain is the source), external (domain is the LCCA). The special case for atomic sources goes away in 4.0 together with the alias.

SCXML reader resolves section 3.13 at parse time: no target becomes internal; type="internal" with a compound source and descendant targets becomes local; everything else becomes external.

Native format: kind as an enum in the JSON Schema, kept in sync with io/native.py.

Diagrams: internal drawn as an action inside the state; local and external as arrows.

Compatibility (3.x)

internal=True stays as a deprecated alias with DeprecationWarning, mapped to today's behavior:

  • self-transition on an atomic state: internal;
  • compound source to a descendant: local;
  • self-transition on a compound or parallel state, and parallel source to a descendant: external.

The warning names the kind that matches that specific transition, so migration is mechanical. enable_self_transition_entries (deprecated in #696) points to the same migration. Both are removed in 4.0.

Acceptance

  • Validation tests for every invalid combination above.
  • One machine written in Python, YAML and SCXML produces the same trace for each kind.
  • Docs: transitions page with the UML/SCXML table; release notes; a "3.x to 4.0" upgrade page with the migration table.
  • W3C SCXML and PSSM suites unchanged or improved.

Refs #692, #696

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementumlUML state machine semantics, tracked in #692

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions