python-statemachine 2.6.0__tar.gz → 3.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/.github/ISSUE_TEMPLATE.md +2 -0
  2. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/.github/workflows/python-package.yml +2 -2
  3. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/.github/workflows/release.yml +1 -1
  4. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/.pre-commit-config.yaml +7 -1
  5. python_statemachine-3.0.0/AGENTS.md +243 -0
  6. python_statemachine-3.0.0/PKG-INFO +414 -0
  7. python_statemachine-3.0.0/README.md +386 -0
  8. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/conftest.py +4 -2
  9. python_statemachine-3.0.0/docs/actions.md +642 -0
  10. python_statemachine-3.0.0/docs/api.md +161 -0
  11. python_statemachine-3.0.0/docs/async.md +201 -0
  12. python_statemachine-3.0.0/docs/behaviour.md +186 -0
  13. python_statemachine-3.0.0/docs/concepts.md +152 -0
  14. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/conf.py +2 -0
  15. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/contributing.md +130 -0
  16. python_statemachine-3.0.0/docs/diagram.md +142 -0
  17. python_statemachine-3.0.0/docs/error_handling.md +246 -0
  18. python_statemachine-3.0.0/docs/events.md +373 -0
  19. python_statemachine-3.0.0/docs/guards.md +396 -0
  20. python_statemachine-3.0.0/docs/how-to/coming_from_state_pattern.md +396 -0
  21. python_statemachine-3.0.0/docs/how-to/coming_from_transitions.md +963 -0
  22. python_statemachine-3.0.0/docs/images/internal_transition_sc.png +0 -0
  23. python_statemachine-3.0.0/docs/images/order_control_machine_initial.png +0 -0
  24. python_statemachine-3.0.0/docs/images/order_control_machine_initial_300dpi.png +0 -0
  25. python_statemachine-3.0.0/docs/images/order_control_machine_processing.png +0 -0
  26. python_statemachine-3.0.0/docs/images/readme_orderworkflow.png +0 -0
  27. python_statemachine-3.0.0/docs/images/readme_trafficlightmachine.png +0 -0
  28. python_statemachine-3.0.0/docs/images/test_state_machine_internal.png +0 -0
  29. python_statemachine-3.0.0/docs/images/transition_compound_cancel.png +0 -0
  30. python_statemachine-3.0.0/docs/images/transition_from_any.png +0 -0
  31. python_statemachine-3.0.0/docs/images/tutorial_coffeeorder.png +0 -0
  32. python_statemachine-3.0.0/docs/index.md +90 -0
  33. python_statemachine-3.0.0/docs/integrations.md +171 -0
  34. python_statemachine-3.0.0/docs/invoke.md +487 -0
  35. python_statemachine-3.0.0/docs/listeners.md +277 -0
  36. python_statemachine-3.0.0/docs/models.md +70 -0
  37. python_statemachine-3.0.0/docs/processing_model.md +317 -0
  38. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.0.0.md +4 -1
  39. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.2.0.md +14 -14
  40. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.3.0.md +13 -15
  41. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.4.0.md +19 -21
  42. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.5.0.md +35 -56
  43. python_statemachine-3.0.0/docs/releases/3.0.0.md +667 -0
  44. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/index.md +18 -6
  45. python_statemachine-3.0.0/docs/releases/upgrade_2x_to_3.md +477 -0
  46. python_statemachine-3.0.0/docs/statechart.md +286 -0
  47. python_statemachine-3.0.0/docs/states.md +230 -0
  48. python_statemachine-3.0.0/docs/timeout.md +92 -0
  49. python_statemachine-3.0.0/docs/transitions.md +386 -0
  50. python_statemachine-3.0.0/docs/tutorial.md +736 -0
  51. python_statemachine-3.0.0/docs/validations.md +280 -0
  52. python_statemachine-3.0.0/docs/weighted_transitions.md +234 -0
  53. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/pyproject.toml +26 -11
  54. python_statemachine-3.0.0/statemachine/__init__.py +21 -0
  55. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/callbacks.py +131 -38
  56. python_statemachine-3.0.0/statemachine/contrib/diagram.py +370 -0
  57. python_statemachine-3.0.0/statemachine/contrib/timeout.py +68 -0
  58. python_statemachine-3.0.0/statemachine/contrib/weighted.py +193 -0
  59. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/dispatcher.py +2 -2
  60. python_statemachine-3.0.0/statemachine/engines/async_.py +533 -0
  61. python_statemachine-3.0.0/statemachine/engines/base.py +943 -0
  62. python_statemachine-3.0.0/statemachine/engines/sync.py +208 -0
  63. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/event.py +90 -21
  64. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/event_data.py +26 -11
  65. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/events.py +12 -3
  66. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/exceptions.py +8 -4
  67. python_statemachine-3.0.0/statemachine/factory.py +359 -0
  68. python_statemachine-3.0.0/statemachine/graph.py +62 -0
  69. python_statemachine-3.0.0/statemachine/invoke.py +603 -0
  70. python_statemachine-3.0.0/statemachine/io/__init__.py +225 -0
  71. python_statemachine-3.0.0/statemachine/io/scxml/actions.py +649 -0
  72. python_statemachine-3.0.0/statemachine/io/scxml/invoke.py +233 -0
  73. python_statemachine-3.0.0/statemachine/io/scxml/parser.py +473 -0
  74. python_statemachine-3.0.0/statemachine/io/scxml/processor.py +263 -0
  75. python_statemachine-3.0.0/statemachine/io/scxml/schema.py +175 -0
  76. python_statemachine-3.0.0/statemachine/locale/en/LC_MESSAGES/statemachine.po +133 -0
  77. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/locale/hi_IN/LC_MESSAGES/statemachine.po +51 -26
  78. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/locale/pt_BR/LC_MESSAGES/statemachine.po +51 -26
  79. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/locale/zh_CN/LC_MESSAGES/statemachine.po +47 -26
  80. python_statemachine-3.0.0/statemachine/orderedset.py +118 -0
  81. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/registry.py +4 -10
  82. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/signature.py +3 -1
  83. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/spec_parser.py +50 -9
  84. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/state.py +227 -26
  85. python_statemachine-3.0.0/statemachine/statemachine.py +547 -0
  86. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/states.py +22 -19
  87. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/transition.py +46 -8
  88. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/transition_list.py +7 -0
  89. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/transition_mixin.py +6 -2
  90. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/utils.py +2 -1
  91. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/conftest.py +144 -22
  92. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/django_project/workflow/statemachines.py +4 -2
  93. python_statemachine-3.0.0/tests/examples/__init__.py +0 -0
  94. python_statemachine-3.0.0/tests/examples/ai_shell_machine.py +568 -0
  95. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/air_conditioner_machine.py +3 -3
  96. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/all_actions_machine.py +5 -4
  97. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/async_guess_the_number_machine.py +9 -7
  98. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/async_without_loop_machine.py +4 -4
  99. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/enum_campaign_machine.py +13 -15
  100. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/guess_the_number_machine.py +4 -3
  101. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/lor_machine.py +11 -10
  102. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/order_control_machine.py +5 -3
  103. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/order_control_rich_model_machine.py +7 -4
  104. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/persistent_model_machine.py +6 -6
  105. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/recursive_event_machine.py +3 -2
  106. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/reusing_transitions_machine.py +3 -3
  107. python_statemachine-3.0.0/tests/examples/statechart_cleanup_machine.py +111 -0
  108. python_statemachine-3.0.0/tests/examples/statechart_compound_machine.py +97 -0
  109. python_statemachine-3.0.0/tests/examples/statechart_delayed_machine.py +189 -0
  110. python_statemachine-3.0.0/tests/examples/statechart_error_handling_machine.py +104 -0
  111. python_statemachine-3.0.0/tests/examples/statechart_eventless_machine.py +99 -0
  112. python_statemachine-3.0.0/tests/examples/statechart_history_machine.py +125 -0
  113. python_statemachine-3.0.0/tests/examples/statechart_in_condition_machine.py +115 -0
  114. python_statemachine-3.0.0/tests/examples/statechart_parallel_machine.py +97 -0
  115. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/traffic_light_machine.py +4 -4
  116. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/user_machine.py +5 -4
  117. python_statemachine-3.0.0/tests/examples/weighted_idle_machine.py +41 -0
  118. python_statemachine-3.0.0/tests/scxml/__init__.py +0 -0
  119. python_statemachine-3.0.0/tests/scxml/conftest.py +74 -0
  120. python_statemachine-3.0.0/tests/scxml/test_microwave.py +130 -0
  121. python_statemachine-3.0.0/tests/scxml/test_scxml_cases.py +101 -0
  122. python_statemachine-3.0.0/tests/scxml/w3c/LICENSE +11 -0
  123. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test144.scxml +33 -0
  124. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test145.scxml +31 -0
  125. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test147.scxml +36 -0
  126. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test148.scxml +36 -0
  127. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test149.scxml +32 -0
  128. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test150.scxml +46 -0
  129. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test151.scxml +46 -0
  130. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test152.scxml +52 -0
  131. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test153.scxml +45 -0
  132. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test155.scxml +31 -0
  133. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test156.scxml +34 -0
  134. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test158.scxml +31 -0
  135. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test159.scxml +26 -0
  136. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test172.scxml +25 -0
  137. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test173.scxml +26 -0
  138. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test174.scxml +26 -0
  139. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test175.scxml +34 -0
  140. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test176.scxml +36 -0
  141. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test179.scxml +24 -0
  142. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test183.scxml +26 -0
  143. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test185.scxml +27 -0
  144. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test186.scxml +39 -0
  145. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test187.scxml +40 -0
  146. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test189.scxml +29 -0
  147. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test190.scxml +45 -0
  148. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test191.scxml +40 -0
  149. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test192.scxml +57 -0
  150. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test194.scxml +26 -0
  151. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test198.scxml +26 -0
  152. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test199.scxml +23 -0
  153. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test200.scxml +23 -0
  154. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test205.scxml +36 -0
  155. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test207.scxml +63 -0
  156. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test208.scxml +26 -0
  157. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test210.scxml +28 -0
  158. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test215.scxml +41 -0
  159. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test216.scxml +33 -0
  160. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test216sub1.scxml +8 -0
  161. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test220.scxml +33 -0
  162. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test223.scxml +40 -0
  163. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test224.scxml +43 -0
  164. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test225.scxml +49 -0
  165. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test226.scxml +50 -0
  166. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test226sub1.scxml +18 -0
  167. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test228.scxml +44 -0
  168. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test229.scxml +54 -0
  169. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test232.scxml +51 -0
  170. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test233.scxml +46 -0
  171. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test234.scxml +77 -0
  172. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test235.scxml +34 -0
  173. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test236.scxml +51 -0
  174. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test237.scxml +52 -0
  175. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test239.scxml +42 -0
  176. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test239sub1.scxml +7 -0
  177. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test240.scxml +77 -0
  178. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test241.scxml +109 -0
  179. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test242.scxml +64 -0
  180. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test242sub1.scxml +7 -0
  181. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test243.scxml +46 -0
  182. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test244.scxml +49 -0
  183. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test245.scxml +46 -0
  184. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test247.scxml +32 -0
  185. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test252.scxml +58 -0
  186. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test253.scxml +80 -0
  187. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test276.scxml +27 -0
  188. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test276sub1.scxml +24 -0
  189. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test277.scxml +39 -0
  190. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test279.scxml +32 -0
  191. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test280.scxml +40 -0
  192. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test286.scxml +30 -0
  193. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test287.scxml +30 -0
  194. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test294.scxml +39 -0
  195. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test298.scxml +34 -0
  196. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test302.scxml +25 -0
  197. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test303.scxml +31 -0
  198. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test304.scxml +24 -0
  199. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test309.scxml +24 -0
  200. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test310.scxml +28 -0
  201. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test311.scxml +27 -0
  202. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test312.scxml +30 -0
  203. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test318.scxml +38 -0
  204. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test319.scxml +30 -0
  205. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test321.scxml +25 -0
  206. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test322.scxml +47 -0
  207. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test323.scxml +25 -0
  208. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test324.scxml +32 -0
  209. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test325.scxml +27 -0
  210. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test326.scxml +46 -0
  211. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test329.scxml +63 -0
  212. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test330.scxml +38 -0
  213. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test331.scxml +70 -0
  214. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test332.scxml +40 -0
  215. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test333.scxml +25 -0
  216. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test335.scxml +25 -0
  217. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test336.scxml +36 -0
  218. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test337.scxml +25 -0
  219. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test338.scxml +49 -0
  220. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test339.scxml +26 -0
  221. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test342.scxml +36 -0
  222. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test343.scxml +36 -0
  223. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test344.scxml +32 -0
  224. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test346.scxml +67 -0
  225. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test347.scxml +53 -0
  226. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test348.scxml +28 -0
  227. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test349.scxml +41 -0
  228. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test350.scxml +34 -0
  229. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test351.scxml +59 -0
  230. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test352.scxml +39 -0
  231. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test354.scxml +63 -0
  232. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test355.scxml +25 -0
  233. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test364.scxml +81 -0
  234. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test372.scxml +36 -0
  235. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test375.scxml +36 -0
  236. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test376.scxml +33 -0
  237. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test377.scxml +41 -0
  238. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test378.scxml +36 -0
  239. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test387.scxml +61 -0
  240. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test388.scxml +76 -0
  241. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test396.scxml +27 -0
  242. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test399.scxml +77 -0
  243. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test401.scxml +27 -0
  244. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test402.scxml +51 -0
  245. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test403a.scxml +48 -0
  246. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test403b.scxml +43 -0
  247. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test403c.scxml +54 -0
  248. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test404.scxml +71 -0
  249. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test405.scxml +78 -0
  250. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test406.scxml +76 -0
  251. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test407.scxml +31 -0
  252. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test409.scxml +45 -0
  253. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test411.scxml +44 -0
  254. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test412.scxml +66 -0
  255. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test413.scxml +59 -0
  256. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test416.scxml +33 -0
  257. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test417.scxml +43 -0
  258. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test419.scxml +27 -0
  259. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test421.scxml +35 -0
  260. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test422.scxml +86 -0
  261. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test423.scxml +36 -0
  262. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test487.scxml +27 -0
  263. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test488.scxml +34 -0
  264. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test495.scxml +35 -0
  265. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test496.scxml +28 -0
  266. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test500.scxml +27 -0
  267. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test501.scxml +31 -0
  268. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test503.scxml +48 -0
  269. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test504.scxml +81 -0
  270. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test505.scxml +58 -0
  271. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test506.scxml +64 -0
  272. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test521.scxml +34 -0
  273. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test525.scxml +31 -0
  274. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test527.scxml +29 -0
  275. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test528.scxml +34 -0
  276. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test529.scxml +27 -0
  277. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test530.scxml +39 -0
  278. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test533.scxml +74 -0
  279. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test550.scxml +26 -0
  280. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test551.scxml +28 -0
  281. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test552.scxml +24 -0
  282. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test552.txt +1 -0
  283. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test553.scxml +34 -0
  284. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test554.scxml +36 -0
  285. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test570.scxml +48 -0
  286. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test576.scxml +45 -0
  287. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test579.scxml +63 -0
  288. python_statemachine-3.0.0/tests/scxml/w3c/mandatory/test580.scxml +46 -0
  289. python_statemachine-3.0.0/tests/scxml/w3c/optional/test193.scxml +30 -0
  290. python_statemachine-3.0.0/tests/scxml/w3c/optional/test201.scxml +25 -0
  291. python_statemachine-3.0.0/tests/scxml/w3c/optional/test278.scxml +32 -0
  292. python_statemachine-3.0.0/tests/scxml/w3c/optional/test444.scxml +23 -0
  293. python_statemachine-3.0.0/tests/scxml/w3c/optional/test445.scxml +22 -0
  294. python_statemachine-3.0.0/tests/scxml/w3c/optional/test446.scxml +28 -0
  295. python_statemachine-3.0.0/tests/scxml/w3c/optional/test446.txt +1 -0
  296. python_statemachine-3.0.0/tests/scxml/w3c/optional/test448.scxml +39 -0
  297. python_statemachine-3.0.0/tests/scxml/w3c/optional/test449.scxml +19 -0
  298. python_statemachine-3.0.0/tests/scxml/w3c/optional/test451.scxml +22 -0
  299. python_statemachine-3.0.0/tests/scxml/w3c/optional/test452.scxml +39 -0
  300. python_statemachine-3.0.0/tests/scxml/w3c/optional/test453.scxml +28 -0
  301. python_statemachine-3.0.0/tests/scxml/w3c/optional/test456.scxml +26 -0
  302. python_statemachine-3.0.0/tests/scxml/w3c/optional/test457.scxml +63 -0
  303. python_statemachine-3.0.0/tests/scxml/w3c/optional/test459.scxml +46 -0
  304. python_statemachine-3.0.0/tests/scxml/w3c/optional/test460.scxml +31 -0
  305. python_statemachine-3.0.0/tests/scxml/w3c/optional/test509.scxml +26 -0
  306. python_statemachine-3.0.0/tests/scxml/w3c/optional/test510.scxml +31 -0
  307. python_statemachine-3.0.0/tests/scxml/w3c/optional/test518.scxml +27 -0
  308. python_statemachine-3.0.0/tests/scxml/w3c/optional/test519.scxml +27 -0
  309. python_statemachine-3.0.0/tests/scxml/w3c/optional/test520.scxml +31 -0
  310. python_statemachine-3.0.0/tests/scxml/w3c/optional/test522.scxml +29 -0
  311. python_statemachine-3.0.0/tests/scxml/w3c/optional/test531.scxml +28 -0
  312. python_statemachine-3.0.0/tests/scxml/w3c/optional/test532.scxml +28 -0
  313. python_statemachine-3.0.0/tests/scxml/w3c/optional/test534.scxml +26 -0
  314. python_statemachine-3.0.0/tests/scxml/w3c/optional/test557.scxml +34 -0
  315. python_statemachine-3.0.0/tests/scxml/w3c/optional/test557.txt +4 -0
  316. python_statemachine-3.0.0/tests/scxml/w3c/optional/test558.scxml +33 -0
  317. python_statemachine-3.0.0/tests/scxml/w3c/optional/test558.txt +3 -0
  318. python_statemachine-3.0.0/tests/scxml/w3c/optional/test560.scxml +25 -0
  319. python_statemachine-3.0.0/tests/scxml/w3c/optional/test561.scxml +31 -0
  320. python_statemachine-3.0.0/tests/scxml/w3c/optional/test562.scxml +28 -0
  321. python_statemachine-3.0.0/tests/scxml/w3c/optional/test567.scxml +39 -0
  322. python_statemachine-3.0.0/tests/scxml/w3c/optional/test569.scxml +21 -0
  323. python_statemachine-3.0.0/tests/scxml/w3c/optional/test577.scxml +26 -0
  324. python_statemachine-3.0.0/tests/scxml/w3c/optional/test578.scxml +25 -0
  325. python_statemachine-3.0.0/tests/test_async.py +557 -0
  326. python_statemachine-3.0.0/tests/test_async_futures.py +341 -0
  327. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_callbacks.py +43 -5
  328. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_callbacks_isolation.py +5 -3
  329. python_statemachine-3.0.0/tests/test_class_listeners.py +477 -0
  330. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_conditions_algebra.py +10 -7
  331. python_statemachine-3.0.0/tests/test_contrib_diagram.py +377 -0
  332. python_statemachine-3.0.0/tests/test_contrib_timeout.py +139 -0
  333. python_statemachine-3.0.0/tests/test_copy.py +190 -0
  334. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_dispatcher.py +4 -2
  335. python_statemachine-3.0.0/tests/test_error_execution.py +1132 -0
  336. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_events.py +43 -21
  337. python_statemachine-3.0.0/tests/test_fellowship_quest.py +452 -0
  338. python_statemachine-3.0.0/tests/test_invoke.py +1072 -0
  339. python_statemachine-3.0.0/tests/test_io.py +46 -0
  340. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_listener.py +2 -27
  341. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_mixins.py +1 -1
  342. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_mock_compatibility.py +2 -2
  343. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_multiple_destinations.py +22 -10
  344. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_profiling.py +5 -2
  345. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_registry.py +1 -4
  346. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_rtc.py +46 -92
  347. python_statemachine-3.0.0/tests/test_scxml_units.py +1040 -0
  348. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_spec_parser.py +61 -60
  349. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_state.py +31 -2
  350. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_state_callbacks.py +2 -2
  351. python_statemachine-3.0.0/tests/test_statechart_compound.py +341 -0
  352. python_statemachine-3.0.0/tests/test_statechart_delayed.py +100 -0
  353. python_statemachine-3.0.0/tests/test_statechart_donedata.py +198 -0
  354. python_statemachine-3.0.0/tests/test_statechart_error.py +83 -0
  355. python_statemachine-3.0.0/tests/test_statechart_eventless.py +174 -0
  356. python_statemachine-3.0.0/tests/test_statechart_history.py +224 -0
  357. python_statemachine-3.0.0/tests/test_statechart_in_condition.py +162 -0
  358. python_statemachine-3.0.0/tests/test_statechart_parallel.py +275 -0
  359. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_statemachine.py +329 -85
  360. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_statemachine_bounded_transitions.py +2 -2
  361. python_statemachine-3.0.0/tests/test_statemachine_compat.py +374 -0
  362. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_statemachine_inheritance.py +3 -3
  363. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_threading.py +37 -55
  364. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_transition_list.py +42 -0
  365. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_transitions.py +110 -40
  366. python_statemachine-3.0.0/tests/test_validators.py +277 -0
  367. python_statemachine-3.0.0/tests/test_weighted_transitions.py +458 -0
  368. python_statemachine-3.0.0/tests/testcases/__init__.py +0 -0
  369. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/testcases/issue308.md +16 -10
  370. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/testcases/issue384_multiple_observers.md +5 -5
  371. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/testcases/issue449.md +6 -6
  372. python_statemachine-3.0.0/tests/testcases/test_issue434.py +75 -0
  373. python_statemachine-3.0.0/tests/testcases/test_issue480.py +56 -0
  374. python_statemachine-3.0.0/tests/testcases/test_issue509.py +63 -0
  375. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/uv.lock +225 -561
  376. python_statemachine-2.6.0/AGENTS.md +0 -114
  377. python_statemachine-2.6.0/PKG-INFO +0 -433
  378. python_statemachine-2.6.0/README.md +0 -403
  379. python_statemachine-2.6.0/docs/actions.md +0 -463
  380. python_statemachine-2.6.0/docs/api.md +0 -81
  381. python_statemachine-2.6.0/docs/async.md +0 -186
  382. python_statemachine-2.6.0/docs/diagram.md +0 -154
  383. python_statemachine-2.6.0/docs/guards.md +0 -277
  384. python_statemachine-2.6.0/docs/images/order_control_machine_initial.png +0 -0
  385. python_statemachine-2.6.0/docs/images/order_control_machine_initial_300dpi.png +0 -0
  386. python_statemachine-2.6.0/docs/images/order_control_machine_processing.png +0 -0
  387. python_statemachine-2.6.0/docs/images/readme_trafficlightmachine.png +0 -0
  388. python_statemachine-2.6.0/docs/images/test_state_machine_internal.png +0 -0
  389. python_statemachine-2.6.0/docs/index.md +0 -33
  390. python_statemachine-2.6.0/docs/integrations.md +0 -90
  391. python_statemachine-2.6.0/docs/listeners.md +0 -105
  392. python_statemachine-2.6.0/docs/mixins.md +0 -93
  393. python_statemachine-2.6.0/docs/models.md +0 -27
  394. python_statemachine-2.6.0/docs/processing_model.md +0 -138
  395. python_statemachine-2.6.0/docs/readme.md +0 -2
  396. python_statemachine-2.6.0/docs/states.md +0 -166
  397. python_statemachine-2.6.0/docs/transitions.md +0 -378
  398. python_statemachine-2.6.0/statemachine/__init__.py +0 -9
  399. python_statemachine-2.6.0/statemachine/contrib/diagram.py +0 -242
  400. python_statemachine-2.6.0/statemachine/engines/async_.py +0 -158
  401. python_statemachine-2.6.0/statemachine/engines/base.py +0 -40
  402. python_statemachine-2.6.0/statemachine/engines/sync.py +0 -158
  403. python_statemachine-2.6.0/statemachine/factory.py +0 -261
  404. python_statemachine-2.6.0/statemachine/graph.py +0 -20
  405. python_statemachine-2.6.0/statemachine/locale/en/LC_MESSAGES/statemachine.po +0 -107
  406. python_statemachine-2.6.0/statemachine/statemachine.py +0 -334
  407. python_statemachine-2.6.0/tests/test_async.py +0 -279
  408. python_statemachine-2.6.0/tests/test_contrib_diagram.py +0 -90
  409. python_statemachine-2.6.0/tests/test_copy.py +0 -232
  410. python_statemachine-2.6.0/tests/testcases/issue434.md +0 -87
  411. python_statemachine-2.6.0/tests/testcases/issue480.md +0 -43
  412. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/.git-blame-ignore-revs +0 -0
  413. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/.github/FUNDING.yml +0 -0
  414. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/.gitignore +0 -0
  415. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/.readthedocs.yaml +0 -0
  416. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/CLAUDE.md +0 -0
  417. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/LICENSE +0 -0
  418. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/contributing.md +0 -0
  419. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/_static/custom_machine.css +0 -0
  420. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/authors.md +0 -0
  421. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/images/_oc_machine_processing.svg +0 -0
  422. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/images/lab_approval_machine_accepted.png +0 -0
  423. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/images/oc_machine_processing.svg +0 -0
  424. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/images/python-statemachine.png +0 -0
  425. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/images/traffic_light_machine.png +0 -0
  426. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/installation.md +0 -0
  427. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.1.0.md +0 -0
  428. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.2.0.md +0 -0
  429. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.3.0.md +0 -0
  430. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.4.2.md +0 -0
  431. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.5.0.md +0 -0
  432. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.5.1.md +0 -0
  433. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.6.0.md +0 -0
  434. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.6.1.md +0 -0
  435. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.6.2.md +0 -0
  436. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.7.0.md +0 -0
  437. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.7.1.md +0 -0
  438. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.8.0.md +0 -0
  439. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/0.9.0.md +0 -0
  440. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/1.0.0.md +0 -0
  441. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/1.0.1.md +0 -0
  442. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/1.0.2.md +0 -0
  443. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/1.0.3.md +0 -0
  444. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.1.0.md +0 -0
  445. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.1.1.md +0 -0
  446. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.1.2.md +0 -0
  447. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.3.1.md +0 -0
  448. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.3.2.md +0 -0
  449. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.3.3.md +0 -0
  450. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.3.4.md +0 -0
  451. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.3.5.md +0 -0
  452. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.3.6.md +0 -0
  453. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/docs/releases/2.6.0.md +0 -0
  454. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/contrib/__init__.py +0 -0
  455. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/engines/__init__.py +0 -0
  456. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/i18n.py +0 -0
  457. {python_statemachine-2.6.0/tests → python_statemachine-3.0.0/statemachine/io/scxml}/__init__.py +0 -0
  458. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/mixins.py +0 -0
  459. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/model.py +0 -0
  460. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/statemachine/py.typed +0 -0
  461. {python_statemachine-2.6.0/tests/django_project/workflow → python_statemachine-3.0.0/tests}/__init__.py +0 -0
  462. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/django_project/app.py +0 -0
  463. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/django_project/core/__init__,.py +0 -0
  464. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/django_project/core/settings.py +0 -0
  465. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/django_project/core/wsgi.py +0 -0
  466. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/django_project/manage.py +0 -0
  467. {python_statemachine-2.6.0/tests/examples → python_statemachine-3.0.0/tests/django_project/workflow}/__init__.py +0 -0
  468. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/django_project/workflow/apps.py +0 -0
  469. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/django_project/workflow/models.py +0 -0
  470. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/django_project/workflow/tests.py +0 -0
  471. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/examples/README.rst +0 -0
  472. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/helpers.py +0 -0
  473. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/models.py +0 -0
  474. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/scrape_images.py +0 -0
  475. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_actions.py +0 -0
  476. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_examples.py +0 -0
  477. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_signature.py +0 -0
  478. {python_statemachine-2.6.0 → python_statemachine-3.0.0}/tests/test_signature_positional_only.py +0 -0
@@ -13,3 +13,5 @@ Tell us what happened, what went wrong, and what you expected to happen.
13
13
  Paste the command(s) you ran and the output.
14
14
  If there was a crash, please include the traceback here.
15
15
  ```
16
+
17
+ If you're reporting a bug, consider providing a complete example that can be used directly in the automated tests. We allways write tests to reproduce the issue in order to avoid future regressions.
@@ -15,7 +15,7 @@ jobs:
15
15
  strategy:
16
16
  fail-fast: false
17
17
  matrix:
18
- python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
18
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
19
19
 
20
20
  steps:
21
21
  - uses: actions/checkout@v4
@@ -46,7 +46,7 @@ jobs:
46
46
  #----------------------------------------------
47
47
  - name: Test with pytest
48
48
  run: |
49
- uv run pytest --cov-report=xml:coverage.xml
49
+ uv run pytest -n auto --cov --cov-report=xml:coverage.xml
50
50
  uv run coverage xml
51
51
  #----------------------------------------------
52
52
  # upload coverage
@@ -33,7 +33,7 @@ jobs:
33
33
 
34
34
  - name: Test
35
35
  run: |
36
- uv run pytest
36
+ uv run pytest -n auto --cov
37
37
 
38
38
  - name: Build
39
39
  run: |
@@ -25,9 +25,15 @@ repos:
25
25
  types: [python]
26
26
  language: system
27
27
  pass_filenames: false
28
+ - id: pyright
29
+ name: Pyright
30
+ entry: uv run pyright statemachine/
31
+ types: [python]
32
+ language: system
33
+ pass_filenames: false
28
34
  - id: pytest
29
35
  name: Pytest
30
- entry: uv run pytest
36
+ entry: uv run pytest -n auto --cov-fail-under=100
31
37
  types: [python]
32
38
  language: system
33
39
  pass_filenames: false
@@ -0,0 +1,243 @@
1
+ # python-statemachine
2
+
3
+ Python Finite State Machines made easy.
4
+
5
+ ## Project overview
6
+
7
+ A library for building finite state machines in Python, with support for sync and async engines,
8
+ Django integration, diagram generation, and a flexible callback/listener system.
9
+
10
+ - **Source code:** `statemachine/`
11
+ - **Tests:** `tests/`
12
+ - **Documentation:** `docs/` (Sphinx + MyST Markdown, hosted on ReadTheDocs)
13
+
14
+ ## Architecture
15
+
16
+ - `statemachine.py` — Core `StateMachine` and `StateChart` classes
17
+ - `factory.py` — `StateMachineMetaclass` handles class construction, state/transition validation
18
+ - `state.py` / `event.py` — Descriptor-based `State` and `Event` definitions
19
+ - `transition.py` / `transition_list.py` — Transition logic and composition (`|` operator)
20
+ - `callbacks.py` — Priority-based callback registry (`CallbackPriority`, `CallbackGroup`)
21
+ - `dispatcher.py` — Listener/observer pattern, `callable_method` wraps callables with signature adaptation
22
+ - `signature.py` — `SignatureAdapter` for dependency injection into callbacks
23
+ - `engines/base.py` — Shared engine logic (microstep, transition selection, error handling)
24
+ - `engines/sync.py`, `engines/async_.py` — Sync and async processing loops
25
+ - `registry.py` — Global state machine registry (used by `MachineMixin`)
26
+ - `mixins.py` — `MachineMixin` for domain model integration (e.g., Django models)
27
+ - `spec_parser.py` — Boolean expression parser for condition guards
28
+ - `contrib/diagram.py` — Diagram generation via pydot/Graphviz
29
+
30
+ ## Processing model
31
+
32
+ The engine follows the SCXML run-to-completion (RTC) model with two processing levels:
33
+
34
+ - **Microstep**: atomic execution of one transition set (before → exit → on → enter → after).
35
+ - **Macrostep**: complete processing cycle for one external event; repeats microsteps until
36
+ the machine reaches a **stable configuration** (no eventless transitions enabled, internal
37
+ queue empty).
38
+
39
+ ### Event queues
40
+
41
+ - `send()` → **external queue** (processed after current macrostep ends).
42
+ - `raise_()` → **internal queue** (processed within the current macrostep, before external events).
43
+
44
+ ### Error handling (`catch_errors_as_events`)
45
+
46
+ - `StateChart` has `catch_errors_as_events=True` by default; `StateMachine` has `False`.
47
+ - Errors are caught at the **block level** (per onentry/onexit/transition `on` block), not per
48
+ microstep. This means `after` callbacks still run even when an action raises — making
49
+ `after_<event>()` a natural **finalize** hook (runs on both success and failure paths).
50
+ - `error.execution` is dispatched as an internal event; define transitions for it to handle
51
+ errors within the statechart.
52
+ - Error during `error.execution` handling → ignored to prevent infinite loops.
53
+
54
+ #### `on_error` asymmetry: transition `on` vs onentry/onexit
55
+
56
+ Transition `on` content uses `on_error` **only for non-`error.execution` events**. During
57
+ `error.execution` processing, `on_error` is disabled for transition `on` content — errors
58
+ propagate to `microstep()` where `_send_error_execution` ignores them. This prevents infinite
59
+ loops in self-transition error handlers (e.g., `error_execution = s1.to(s1, on="handler")`
60
+ where `handler` raises). `onentry`/`onexit` blocks always use `on_error` regardless of the
61
+ current event.
62
+
63
+ ### Eventless transitions
64
+
65
+ - Bare transition statements (not assigned to a variable) are **eventless** — they fire
66
+ automatically when their guard condition is met.
67
+ - Assigned transitions (e.g., `go = s1.to(s2)`) create **named events**.
68
+ - `error_` prefix naming convention: `error_X` auto-registers both `error_X` and `error.X`
69
+ event names (explicit `id=` takes precedence).
70
+
71
+ ### Callback conventions
72
+
73
+ - Generic callbacks (always available): `prepare_event()`, `before_transition()`,
74
+ `on_transition()`, `on_exit_state()`, `on_enter_state()`, `after_transition()`.
75
+ - Event-specific: `before_<event>()`, `on_<event>()`, `after_<event>()`.
76
+ - State-specific: `on_enter_<state>()`, `on_exit_<state>()`.
77
+ - `on_error_execution()` works via naming convention but **only** when a transition for
78
+ `error.execution` is declared — it is NOT a generic callback.
79
+
80
+ ### Invoke (`<invoke>`)
81
+
82
+ - `invoke.py` — `InvokeManager` on the engine manages the lifecycle: `mark_for_invoke()`,
83
+ `cancel_for_state()`, `spawn_pending_sync/async()`, `send_to_child()`.
84
+ - `_cleanup_terminated()` only removes invocations that are both terminated **and** cancelled.
85
+ A terminated-but-not-cancelled invocation means the handler's `run()` returned but the owning
86
+ state is still active — it must stay in `_active` so `send_to_child()` can still route events.
87
+ - **Child machine constructor blocks** in the processing loop. Use a listener pattern (e.g.,
88
+ `_ChildRefSetter`) to capture the child reference during the first `on_enter_state`, before
89
+ the loop spins.
90
+ - `#_<invokeid>` send target: routed via `_send_to_invoke()` in `io/scxml/actions.py` →
91
+ `InvokeManager.send_to_child()` → handler's `on_event()`.
92
+ - **Tests with blocking threads**: use `threading.Event.wait(timeout=)` instead of
93
+ `time.sleep()` for interruptible waits — avoids thread leak errors in teardown.
94
+
95
+ ## Environment setup
96
+
97
+ ```bash
98
+ uv sync --all-extras --dev
99
+ pre-commit install
100
+ ```
101
+
102
+ ## Running tests
103
+
104
+ Always use `uv` to run commands. Also, use a timeout to avoid being stuck in the case of a leaked thread or infinite loop:
105
+
106
+ ```bash
107
+ # Run all tests (parallel)
108
+ timeout 120 uv run pytest -n 4
109
+
110
+ # Run a specific test file
111
+ uv run pytest tests/test_signature.py
112
+
113
+ # Run a specific test
114
+ uv run pytest tests/test_signature.py::TestSignatureAdapter::test_wrap_fn_single_positional_parameter
115
+
116
+ # Skip slow tests
117
+ uv run pytest -m "not slow"
118
+ ```
119
+
120
+ When trying to run all tests, prefer to use xdist (`-n`) as some SCXML tests uses timeout of 30s to verify fallback mechanism.
121
+ Don't specify the directory `tests/`, because this will exclude doctests from both source modules (`--doctest-modules`) and markdown docs
122
+ (`--doctest-glob=*.md`) (enabled by default):
123
+
124
+ ```bash
125
+ timeout 120 uv run pytest -n 4
126
+ ```
127
+
128
+ Testes normally run under 60s (~40s on average), so take a closer look if they take longer, it can be a regression.
129
+
130
+ When analyzing warnings or extensive output, run the tests **once** saving the output to a file
131
+ (`> /tmp/pytest-output.txt 2>&1`), then analyze the file — instead of running the suite
132
+ repeatedly with different greps.
133
+
134
+ Coverage is enabled by default (`--cov` is in `pyproject.toml`'s `addopts`). To generate a
135
+ coverage report to a file, pass `--cov-report` **in addition to** `--cov`:
136
+
137
+ ```bash
138
+ # JSON report (machine-readable, includes missing_lines per file)
139
+ timeout 120 uv run pytest -n auto --cov=statemachine --cov-report=json:cov.json
140
+
141
+ # Terminal report with missing lines
142
+ timeout 120 uv run pytest -n auto --cov=statemachine --cov-report=term-missing
143
+ ```
144
+
145
+ Note: `--cov=statemachine` is required to activate coverage collection; `--cov-report`
146
+ alone only changes the output format.
147
+
148
+ ### Testing both sync and async engines
149
+
150
+ Use the `sm_runner` fixture (from `tests/conftest.py`) when you need to test the same
151
+ statechart on both sync and async engines. It is parametrized with `["sync", "async"]`
152
+ and provides `start()` / `send()` helpers that handle engine selection automatically:
153
+
154
+ ```python
155
+ async def test_something(self, sm_runner):
156
+ sm = await sm_runner.start(MyStateChart)
157
+ await sm_runner.send(sm, "some_event")
158
+ assert "expected_state" in sm.configuration_values
159
+ ```
160
+
161
+ Do **not** manually add async no-op listeners or duplicate test classes — prefer `sm_runner`.
162
+
163
+ ## Linting and formatting
164
+
165
+ ```bash
166
+ # Lint
167
+ uv run ruff check .
168
+
169
+ # Auto-fix lint issues
170
+ uv run ruff check --fix .
171
+
172
+ # Format
173
+ uv run ruff format .
174
+
175
+ # Type check
176
+ uv run mypy statemachine/ tests/
177
+ ```
178
+
179
+ ## Code style
180
+
181
+ - **Formatter/Linter:** ruff (line length 99, target Python 3.9)
182
+ - **Rules:** pycodestyle, pyflakes, isort, pyupgrade, flake8-comprehensions, flake8-bugbear, flake8-pytest-style
183
+ - **Imports:** single-line, sorted by isort. **Always prefer top-level imports** — only use
184
+ lazy (in-function) imports when strictly necessary to break circular dependencies
185
+ - **Docstrings:** Google convention
186
+ - **Naming:** PascalCase for classes, snake_case for functions/methods, UPPER_SNAKE_CASE for constants
187
+ - **Type hints:** used throughout; `TYPE_CHECKING` for circular imports
188
+ - Pre-commit hooks enforce ruff + mypy + pytest
189
+
190
+ ## Design principles
191
+
192
+ - **Use GRASP/SOLID patterns to guide decisions.** When refactoring or designing, explicitly
193
+ apply patterns like Information Expert, Single Responsibility, and Law of Demeter to decide
194
+ where logic belongs — don't just pick a convenient location.
195
+ - **Information Expert (GRASP):** Place logic in the module/class that already has the
196
+ knowledge it needs. If a method computes a result, it should signal or return it rather
197
+ than forcing another method to recompute the same thing.
198
+ - **Law of Demeter:** Methods should depend only on the data they need, not on the
199
+ objects that contain it. Pass the specific value (e.g., a `Future`) rather than the
200
+ parent object (e.g., `TriggerData`) — this reduces coupling and removes the need for
201
+ null-checks on intermediate accessors.
202
+ - **Single Responsibility:** Each module, class, and function should have one clear reason
203
+ to change. Functions and types belong in the module that owns their domain (e.g.,
204
+ event-name helpers belong in `event.py`, not in `factory.py`).
205
+ - **Interface Segregation:** Depend on narrow interfaces. If a helper only needs one field
206
+ from a dataclass, accept that field directly.
207
+ - **Decouple infrastructure from domain:** Modules like `signature.py` and `dispatcher.py` are
208
+ general-purpose (signature adaptation, listener/observer pattern) and intentionally not coupled
209
+ to the state machine domain. Prefer this separation even for modules that are only used
210
+ internally — it keeps responsibilities clear and the code easier to reason about.
211
+ - **Favor small, focused modules:** When adding new functionality, consider whether it can live in
212
+ its own module with a well-defined boundary, rather than growing an existing one.
213
+
214
+ ## Building documentation
215
+
216
+ ```bash
217
+ # Build HTML docs
218
+ uv run sphinx-build docs docs/_build/html
219
+
220
+ # Live reload for development
221
+ uv run sphinx-autobuild docs docs/_build/html --re-ignore "auto_examples/.*"
222
+ ```
223
+
224
+ ### Documentation code examples
225
+
226
+ All code examples in `docs/*.md` **must** be testable doctests (using ```` ```py ```` with
227
+ `>>>` prompts), not plain ```` ```python ```` blocks. The test suite collects them via
228
+ `--doctest-glob=*.md`. If an example cannot be expressed as a doctest (e.g., it requires
229
+ real concurrency), write it as a unit test in `tests/` and reference it from the docs instead.
230
+
231
+ ## Git workflow
232
+
233
+ - Main branch: `develop`
234
+ - PRs target `develop`
235
+ - Releases are tagged as `v*.*.*`
236
+ - Signed commits preferred (`git commit -s`)
237
+ - Use [Conventional Commits](https://www.conventionalcommits.org/) messages
238
+ (e.g., `feat:`, `fix:`, `refactor:`, `test:`, `docs:`, `chore:`, `perf:`)
239
+
240
+ ## Security
241
+
242
+ - Do not commit secrets, credentials, or `.env` files
243
+ - Validate at system boundaries; trust internal code