python-statemachine 2.6.0__py3-none-any.whl → 3.1.0__py3-none-any.whl

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 (55) hide show
  1. python_statemachine-3.1.0.dist-info/METADATA +421 -0
  2. python_statemachine-3.1.0.dist-info/RECORD +58 -0
  3. {python_statemachine-2.6.0.dist-info → python_statemachine-3.1.0.dist-info}/WHEEL +1 -1
  4. statemachine/__init__.py +14 -2
  5. statemachine/callbacks.py +131 -38
  6. statemachine/configuration.py +162 -0
  7. statemachine/contrib/diagram/__init__.py +237 -0
  8. statemachine/contrib/diagram/__main__.py +6 -0
  9. statemachine/contrib/diagram/extract.py +288 -0
  10. statemachine/contrib/diagram/formatter.py +137 -0
  11. statemachine/contrib/diagram/model.py +63 -0
  12. statemachine/contrib/diagram/renderers/__init__.py +0 -0
  13. statemachine/contrib/diagram/renderers/dot.py +532 -0
  14. statemachine/contrib/diagram/renderers/mermaid.py +348 -0
  15. statemachine/contrib/diagram/renderers/table.py +105 -0
  16. statemachine/contrib/diagram/sphinx_ext.py +280 -0
  17. statemachine/contrib/timeout.py +68 -0
  18. statemachine/contrib/weighted.py +193 -0
  19. statemachine/dispatcher.py +2 -2
  20. statemachine/engines/async_.py +489 -118
  21. statemachine/engines/base.py +929 -18
  22. statemachine/engines/sync.py +153 -108
  23. statemachine/event.py +101 -22
  24. statemachine/event_data.py +28 -13
  25. statemachine/events.py +13 -4
  26. statemachine/exceptions.py +8 -4
  27. statemachine/factory.py +203 -68
  28. statemachine/graph.py +46 -4
  29. statemachine/invoke.py +641 -0
  30. statemachine/io/__init__.py +225 -0
  31. statemachine/io/scxml/__init__.py +0 -0
  32. statemachine/io/scxml/actions.py +650 -0
  33. statemachine/io/scxml/invoke.py +233 -0
  34. statemachine/io/scxml/parser.py +473 -0
  35. statemachine/io/scxml/processor.py +263 -0
  36. statemachine/io/scxml/schema.py +175 -0
  37. statemachine/locale/en/LC_MESSAGES/statemachine.po +95 -42
  38. statemachine/locale/hi_IN/LC_MESSAGES/statemachine.po +85 -35
  39. statemachine/locale/pt_BR/LC_MESSAGES/statemachine.po +86 -34
  40. statemachine/locale/zh_CN/LC_MESSAGES/statemachine.po +79 -33
  41. statemachine/orderedset.py +118 -0
  42. statemachine/registry.py +4 -10
  43. statemachine/signature.py +3 -1
  44. statemachine/spec_parser.py +50 -9
  45. statemachine/state.py +214 -66
  46. statemachine/statemachine.py +298 -102
  47. statemachine/states.py +22 -19
  48. statemachine/transition.py +46 -8
  49. statemachine/transition_list.py +7 -0
  50. statemachine/transition_mixin.py +6 -2
  51. statemachine/utils.py +20 -1
  52. python_statemachine-2.6.0.dist-info/METADATA +0 -433
  53. python_statemachine-2.6.0.dist-info/RECORD +0 -37
  54. statemachine/contrib/diagram.py +0 -242
  55. {python_statemachine-2.6.0.dist-info → python_statemachine-3.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,421 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-statemachine
3
+ Version: 3.1.0
4
+ Summary: Python Finite State Machines made easy.
5
+ Project-URL: homepage, https://github.com/fgmacedo/python-statemachine
6
+ Author-email: Fernando Macedo <fgmacedo@gmail.com>
7
+ Maintainer-email: Fernando Macedo <fgmacedo@gmail.com>
8
+ License: MIT License
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Framework :: AsyncIO
12
+ Classifier: Framework :: Django
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Natural Language :: English
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Home Automation
23
+ Classifier: Topic :: Software Development :: Libraries
24
+ Requires-Python: >=3.9
25
+ Provides-Extra: diagrams
26
+ Requires-Dist: pydot>=4.0.1; extra == 'diagrams'
27
+ Description-Content-Type: text/markdown
28
+
29
+ # Python StateMachine
30
+
31
+ [![pypi](https://img.shields.io/pypi/v/python-statemachine.svg)](https://pypi.python.org/pypi/python-statemachine)
32
+ [![downloads total](https://static.pepy.tech/badge/python-statemachine)](https://pepy.tech/project/python-statemachine)
33
+ [![downloads](https://img.shields.io/pypi/dm/python-statemachine.svg)](https://pypi.python.org/pypi/python-statemachine)
34
+ [![Coverage report](https://codecov.io/gh/fgmacedo/python-statemachine/branch/develop/graph/badge.svg)](https://codecov.io/gh/fgmacedo/python-statemachine)
35
+ [![Documentation Status](https://readthedocs.org/projects/python-statemachine/badge/?version=latest)](https://python-statemachine.readthedocs.io/en/latest/?badge=latest)
36
+ [![GitHub commits since last release (main)](https://img.shields.io/github/commits-since/fgmacedo/python-statemachine/main/develop)](https://github.com/fgmacedo/python-statemachine/compare/main...develop)
37
+
38
+ Expressive [statecharts](https://statecharts.dev/) and [FSMs](https://en.wikipedia.org/wiki/Finite-state_machine) for modern Python.
39
+
40
+ <div align="center">
41
+
42
+ ![](https://github.com/fgmacedo/python-statemachine/blob/develop/docs/images/python-statemachine.png?raw=true)
43
+
44
+ </div>
45
+
46
+ Welcome to python-statemachine, an intuitive and powerful state machine library designed for a
47
+ great developer experience. Define flat state machines or full statecharts with compound states,
48
+ parallel regions, and history — all with a clean, _pythonic_, declarative API that works in both
49
+ sync and async Python codebases.
50
+
51
+
52
+ ## Quick start
53
+
54
+ ```py
55
+ >>> from statemachine import StateChart, State
56
+
57
+ >>> class TrafficLightMachine(StateChart):
58
+ ... "A traffic light machine"
59
+ ... green = State(initial=True)
60
+ ... yellow = State()
61
+ ... red = State()
62
+ ...
63
+ ... cycle = (
64
+ ... green.to(yellow)
65
+ ... | yellow.to(red)
66
+ ... | red.to(green)
67
+ ... )
68
+ ...
69
+ ... def before_cycle(self, event: str, source: State, target: State):
70
+ ... return f"Running {event} from {source.id} to {target.id}"
71
+ ...
72
+ ... def on_enter_red(self):
73
+ ... print("Don't move.")
74
+ ...
75
+ ... def on_exit_red(self):
76
+ ... print("Go ahead!")
77
+
78
+ ```
79
+
80
+ Create an instance and send events:
81
+
82
+ ```py
83
+ >>> sm = TrafficLightMachine()
84
+ >>> sm.send("cycle")
85
+ 'Running cycle from green to yellow'
86
+
87
+ >>> sm.send("cycle")
88
+ Don't move.
89
+ 'Running cycle from yellow to red'
90
+
91
+ >>> sm.send("cycle")
92
+ Go ahead!
93
+ 'Running cycle from red to green'
94
+
95
+ ```
96
+
97
+ Check which states are active:
98
+
99
+ ```py
100
+ >>> sm.configuration
101
+ OrderedSet([State('Green', id='green', value='green', initial=True, final=False, parallel=False)])
102
+
103
+ >>> sm.green.is_active
104
+ True
105
+
106
+ ```
107
+
108
+ Generate a diagram or get a text representation with f-strings:
109
+
110
+ ```py
111
+ >>> print(f"{sm:md}")
112
+ | State | Event | Guard | Target |
113
+ | ------ | ----- | ----- | ------ |
114
+ | Green | Cycle | | Yellow |
115
+ | Yellow | Cycle | | Red |
116
+ | Red | Cycle | | Green |
117
+ <BLANKLINE>
118
+
119
+ ```
120
+
121
+ ```python
122
+ sm._graph().write_png("traffic_light.png")
123
+ ```
124
+
125
+ ![](https://raw.githubusercontent.com/fgmacedo/python-statemachine/develop/docs/images/readme_trafficlightmachine.png)
126
+
127
+ Parameters are injected into callbacks automatically — the library inspects the
128
+ signature and provides only the arguments each callback needs:
129
+
130
+ ```py
131
+ >>> sm.send("cycle")
132
+ 'Running cycle from green to yellow'
133
+
134
+ ```
135
+
136
+
137
+ ## Guards and conditional transitions
138
+
139
+ Use `cond=` and `unless=` to add guards. When multiple transitions share the same
140
+ event, declaration order determines priority:
141
+
142
+ ```py
143
+ >>> from statemachine import StateChart, State
144
+
145
+ >>> class ApprovalWorkflow(StateChart):
146
+ ... pending = State(initial=True)
147
+ ... approved = State(final=True)
148
+ ... rejected = State(final=True)
149
+ ...
150
+ ... review = (
151
+ ... pending.to(approved, cond="is_valid")
152
+ ... | pending.to(rejected)
153
+ ... )
154
+ ...
155
+ ... def is_valid(self, score: int = 0):
156
+ ... return score >= 70
157
+
158
+ >>> sm = ApprovalWorkflow()
159
+ >>> sm.send("review", score=50)
160
+ >>> sm.rejected.is_active
161
+ True
162
+
163
+ >>> sm = ApprovalWorkflow()
164
+ >>> sm.send("review", score=85)
165
+ >>> sm.approved.is_active
166
+ True
167
+
168
+ ```
169
+
170
+ The first transition whose guard passes wins. When `score < 70`, `is_valid` returns
171
+ `False` so the second transition (no guard — always matches) fires instead.
172
+
173
+
174
+ ## Compound states — hierarchy
175
+
176
+ Break complex behavior into hierarchical levels with `State.Compound`. Entering a
177
+ compound activates both the parent and its `initial` child. Exiting removes the
178
+ parent and all descendants:
179
+
180
+ ```py
181
+ >>> from statemachine import StateChart, State
182
+
183
+ >>> class DocumentWorkflow(StateChart):
184
+ ... class editing(State.Compound):
185
+ ... draft = State(initial=True)
186
+ ... review = State()
187
+ ... submit = draft.to(review)
188
+ ... revise = review.to(draft)
189
+ ...
190
+ ... published = State(final=True)
191
+ ... approve = editing.to(published)
192
+
193
+ >>> sm = DocumentWorkflow()
194
+ >>> set(sm.configuration_values) == {"editing", "draft"}
195
+ True
196
+
197
+ >>> sm.send("submit")
198
+ >>> "review" in sm.configuration_values
199
+ True
200
+
201
+ >>> sm.send("approve")
202
+ >>> set(sm.configuration_values) == {"published"}
203
+ True
204
+
205
+ ```
206
+
207
+
208
+ ## Parallel states — concurrency
209
+
210
+ `State.Parallel` activates all child regions simultaneously. Events in one
211
+ region don't affect others. A `done.state` event fires only when **all**
212
+ regions reach a final state:
213
+
214
+ ```py
215
+ >>> from statemachine import StateChart, State
216
+
217
+ >>> class DeployPipeline(StateChart):
218
+ ... class deploy(State.Parallel):
219
+ ... class build(State.Compound):
220
+ ... compiling = State(initial=True)
221
+ ... compiled = State(final=True)
222
+ ... finish_build = compiling.to(compiled)
223
+ ... class tests(State.Compound):
224
+ ... running = State(initial=True)
225
+ ... passed = State(final=True)
226
+ ... finish_tests = running.to(passed)
227
+ ... released = State(final=True)
228
+ ... done_state_deploy = deploy.to(released)
229
+
230
+ >>> sm = DeployPipeline()
231
+ >>> "compiling" in sm.configuration_values and "running" in sm.configuration_values
232
+ True
233
+
234
+ >>> sm.send("finish_build")
235
+ >>> "compiled" in sm.configuration_values and "running" in sm.configuration_values
236
+ True
237
+
238
+ >>> sm.send("finish_tests")
239
+ >>> set(sm.configuration_values) == {"released"}
240
+ True
241
+
242
+ ```
243
+
244
+
245
+ ## History states
246
+
247
+ `HistoryState()` records which child was active when a compound is exited.
248
+ Re-entering via the history pseudo-state restores the previous child instead
249
+ of starting from the initial one:
250
+
251
+ ```py
252
+ >>> from statemachine import HistoryState, StateChart, State
253
+
254
+ >>> class EditorWithHistory(StateChart):
255
+ ... class editor(State.Compound):
256
+ ... source = State(initial=True)
257
+ ... visual = State()
258
+ ... h = HistoryState()
259
+ ... toggle = source.to(visual) | visual.to(source)
260
+ ... settings = State()
261
+ ... open_settings = editor.to(settings)
262
+ ... back = settings.to(editor.h)
263
+
264
+ >>> sm = EditorWithHistory()
265
+ >>> sm.send("toggle")
266
+ >>> "visual" in sm.configuration_values
267
+ True
268
+
269
+ >>> sm.send("open_settings")
270
+ >>> sm.send("back")
271
+ >>> "visual" in sm.configuration_values
272
+ True
273
+
274
+ ```
275
+
276
+ Use `HistoryState(type="deep")` for deep history that remembers the exact leaf
277
+ state across nested compounds.
278
+
279
+
280
+ ## Eventless transitions
281
+
282
+ Transitions without an event trigger fire automatically. With a guard, they
283
+ fire after any event processing when the condition is met:
284
+
285
+ ```py
286
+ >>> from statemachine import StateChart, State
287
+
288
+ >>> class AutoCounter(StateChart):
289
+ ... counting = State(initial=True)
290
+ ... done = State(final=True)
291
+ ...
292
+ ... counting.to(done, cond="limit_reached")
293
+ ... increment = counting.to.itself(internal=True, on="do_increment")
294
+ ...
295
+ ... count = 0
296
+ ...
297
+ ... def do_increment(self):
298
+ ... self.count += 1
299
+ ... def limit_reached(self):
300
+ ... return self.count >= 3
301
+
302
+ >>> sm = AutoCounter()
303
+ >>> sm.send("increment")
304
+ >>> sm.send("increment")
305
+ >>> "counting" in sm.configuration_values
306
+ True
307
+
308
+ >>> sm.send("increment")
309
+ >>> "done" in sm.configuration_values
310
+ True
311
+
312
+ ```
313
+
314
+
315
+ ## Error handling
316
+
317
+ When using `StateChart`, runtime exceptions in callbacks are caught and
318
+ turned into `error.execution` events. Define a transition for that event
319
+ to handle errors within the state machine itself:
320
+
321
+ ```py
322
+ >>> from statemachine import StateChart, State
323
+
324
+ >>> class ResilientService(StateChart):
325
+ ... running = State(initial=True)
326
+ ... failed = State(final=True)
327
+ ...
328
+ ... process = running.to(running, on="do_work")
329
+ ... error_execution = running.to(failed)
330
+ ...
331
+ ... def do_work(self):
332
+ ... raise RuntimeError("something broke")
333
+
334
+ >>> sm = ResilientService()
335
+ >>> sm.send("process")
336
+ >>> sm.failed.is_active
337
+ True
338
+
339
+ ```
340
+
341
+
342
+ ## Async support
343
+
344
+ Async callbacks just work — same API, no changes needed. The engine
345
+ detects async callbacks and switches to the async engine automatically:
346
+
347
+ ```py
348
+ >>> import asyncio
349
+ >>> from statemachine import StateChart, State
350
+
351
+ >>> class AsyncWorkflow(StateChart):
352
+ ... idle = State(initial=True)
353
+ ... done = State(final=True)
354
+ ...
355
+ ... finish = idle.to(done)
356
+ ...
357
+ ... async def on_finish(self):
358
+ ... return 42
359
+
360
+ >>> async def run():
361
+ ... sm = AsyncWorkflow()
362
+ ... result = await sm.finish()
363
+ ... print(f"Result: {result}")
364
+ ... print(sm.done.is_active)
365
+
366
+ >>> asyncio.run(run())
367
+ Result: 42
368
+ True
369
+
370
+ ```
371
+
372
+
373
+ ## More features
374
+
375
+ There's a lot more to explore:
376
+
377
+ - **DoneData** on final states — pass structured data to `done.state` handlers
378
+ - **Delayed events** — schedule events with `sm.send("event", delay=500)`
379
+ - **`In(state)` conditions** — cross-region guards in parallel states
380
+ - **`prepare_event`** callback — inject custom data into all callbacks
381
+ - **Observer pattern** — register external listeners to watch events and state changes
382
+ - **Django integration** — auto-discover state machines in Django apps with `MachineMixin`
383
+ - **Diagram generation** — via f-strings (`f"{sm:mermaid}"`), CLI, Sphinx directive, or Jupyter
384
+ - **Dictionary-based definitions** — create state machines from data structures
385
+ - **Internationalization** — error messages in multiple languages
386
+
387
+ Full documentation: https://python-statemachine.readthedocs.io
388
+
389
+
390
+ ## Installing
391
+
392
+ ```
393
+ pip install python-statemachine
394
+ ```
395
+
396
+ To generate diagrams, install with the `diagrams` extra (requires
397
+ [Graphviz](https://graphviz.org/)):
398
+
399
+ ```
400
+ pip install python-statemachine[diagrams]
401
+ ```
402
+
403
+
404
+ ## Contributing
405
+
406
+ - If you found this project helpful, please consider giving it a star on GitHub.
407
+
408
+ - **Contribute code**: If you would like to contribute code, please submit a pull
409
+ request. For more information on how to contribute, please see our [contributing.md](contributing.md) file.
410
+
411
+ - **Report bugs**: If you find any bugs, please report them by opening an issue
412
+ on our GitHub issue tracker.
413
+
414
+ - **Suggest features**: If you have an idea for a new feature, or feel something is harder than it should be,
415
+ please let us know by opening an issue on our GitHub issue tracker.
416
+
417
+ - **Documentation**: Help improve documentation by submitting pull requests.
418
+
419
+ - **Promote the project**: Help spread the word by sharing on social media,
420
+ writing a blog post, or giving a talk about it. Tag me on Twitter
421
+ [@fgmacedo](https://twitter.com/fgmacedo) so I can share it too!
@@ -0,0 +1,58 @@
1
+ statemachine/__init__.py,sha256=ULem4I0OFrhvgXyaka9WLO8OJimg8LtFKKrfG1Zc7Rs,445
2
+ statemachine/callbacks.py,sha256=mY_RAl86240vG2C94ij6AdD7CgsIM8mr0wvpSAMAPv0,14644
3
+ statemachine/configuration.py,sha256=pt3Sq323bZKymnjQzLotqkNVkgqNHh3pmSIXLxk-obA,5453
4
+ statemachine/dispatcher.py,sha256=xvA1Kf1xGQivHTpaGm_HC22vqAmE_tTm9LQwyVLRWLE,7841
5
+ statemachine/event.py,sha256=d_Ky5ph30Os305BceN4x-rftZH-h8G1U5ei34-66lnI,7669
6
+ statemachine/event_data.py,sha256=7_hoE0cp-0uW71Kk3erO3eYM6anTT5X3slGMcehIGIo,3111
7
+ statemachine/events.py,sha256=11GyX8GYpsSwvW0v1b4zHUGhzKRoqNjQYtuDj8NvqOM,1212
8
+ statemachine/exceptions.py,sha256=gXFvDsEtIxKdcGrRG9mwDgXqFQDXfw8v66_VXaQgGr4,1305
9
+ statemachine/factory.py,sha256=HQc2Hn1irg96Rkygn2E21YAxFV5PRYiXYh4tTKVWBbc,14706
10
+ statemachine/graph.py,sha256=r-8L7jXab1_VLtVu-Ig8bpe4Szo-r6WDFTdbfcepyZM,1981
11
+ statemachine/i18n.py,sha256=NLvGseaORmQ0G-V_J8tkjoxh_piWMOm2CI6mBQpLamc,362
12
+ statemachine/invoke.py,sha256=ydYBzP5pi67r9GYmDd6fT169MZkLM4lgpYcbuSyX3Ok,24874
13
+ statemachine/mixins.py,sha256=8qxZZfBwVdFcr3oPFVWHGzgmAubH6VgQus5x3c6VEE0,1706
14
+ statemachine/model.py,sha256=OylI3FjMiHpYyDl9mtK1zEJMeSvemaN4giQDonpc8kI,211
15
+ statemachine/orderedset.py,sha256=PjbegcS7WPJAzC7jQ411_JrFJYEz6mmLRsAZ7aI9BWc,2543
16
+ statemachine/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ statemachine/registry.py,sha256=onT8U5QgYlCSJxgxvi_TY1c1oDetHykOwnyiFk5qoN0,756
18
+ statemachine/signature.py,sha256=N8Vt4X3YOA-NB8oidPAbYZxBgqZm6GYAiuHxBWb1l1s,9922
19
+ statemachine/spec_parser.py,sha256=Io0J5D9s-nu2YdgUlr2cSethGfCS0pSLNmxMCXdwMqQ,8307
20
+ statemachine/state.py,sha256=Sb25t3tAyUfUEP9B8FS7wf_kPaCugVnHeGP0OAOqZWo,15441
21
+ statemachine/statemachine.py,sha256=K2f-MwRkvpnq_9vs7NlqeTkCaeX1eepSZl7XPAUF3V4,19977
22
+ statemachine/states.py,sha256=kWo7y95ikXxNmcf_-J2UoMIwd3NaIdxpHMfoHr3cQ_Y,4934
23
+ statemachine/transition.py,sha256=x9hhxIEyQ7tqsvaXkHg1bVO5hMAjemgHfZhyuypHoOY,6936
24
+ statemachine/transition_list.py,sha256=6NAyOGEgoGOzTYiLfPM21CBVI1tPO63ZIwbaZlqOPI4,4376
25
+ statemachine/transition_mixin.py,sha256=XGGd2J4DnFrqIpeej3QFDOuqI0CAiYwnIb8-_9DpemA,2993
26
+ statemachine/utils.py,sha256=taCgrsRDcQQLweyq607AVZyI0NMukRP-HGpO8TiVNgk,1527
27
+ statemachine/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ statemachine/contrib/timeout.py,sha256=VXkdLpxNeUKihkbtLv8XTWdG-meQlSFtxJfcxXgV8Uw,2251
29
+ statemachine/contrib/weighted.py,sha256=jcKkm25df6NnzBzuss1-ewDEasZ_CyME03xgJXrwcso,6866
30
+ statemachine/contrib/diagram/__init__.py,sha256=NaVy7LWly8fTJNxjaXoRlWdYQ7cwbuNQPN0BMW6ATrI,7532
31
+ statemachine/contrib/diagram/__main__.py,sha256=iPpiz09xKqtAjrhONS99OYp6R2dQ6Anbhw1qPIN8ELo,80
32
+ statemachine/contrib/diagram/extract.py,sha256=RmjsTpOkbQxwYS_m5BS1VWisef5vHtTRmmwe_Dq3wMk,9891
33
+ statemachine/contrib/diagram/formatter.py,sha256=SeNKdt5jzKIDNUPHD0xZQ0cb_zsQbwrucoZtMVXL0og,4758
34
+ statemachine/contrib/diagram/model.py,sha256=ZspysRy8WbJn4VDYkjoYe0mtao2dT9i6T005ehW5BxA,1498
35
+ statemachine/contrib/diagram/sphinx_ext.py,sha256=HcEXU-aYz8da02XPkZKpF5HDF0XPBGGg9FCz8MtI1C8,10338
36
+ statemachine/contrib/diagram/renderers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ statemachine/contrib/diagram/renderers/dot.py,sha256=jzKBXJ_m9olnQLXu8SXbFgtdvbFyt5Ukr5uZNjXU0X8,19913
38
+ statemachine/contrib/diagram/renderers/mermaid.py,sha256=jY6cUW9A_P8xLHISrSijx3GlpIl_Gnj3SgayspYq7DI,13526
39
+ statemachine/contrib/diagram/renderers/table.py,sha256=iIdWnVgV7_PY8piSC-WWbEixZSksqXTOujAk6jrO7FQ,3736
40
+ statemachine/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
+ statemachine/engines/async_.py,sha256=Wtm3GRm2y9gWTevdPkJgnpY7RzZ97HVewWtwgDenoeU,22552
42
+ statemachine/engines/base.py,sha256=bVPYyl_AWWzfjFWiLnDiofdOyb40pojr2qu--C4MHvQ,37993
43
+ statemachine/engines/sync.py,sha256=F_bt4z1KLLcFCP77E9SNWDJMWiMTexE0iOU2XAd_x5A,9153
44
+ statemachine/io/__init__.py,sha256=1J_oVSWrWmx9bLrGU-YoWyO-YYbO6T9Z6vUAnerKe3Q,8739
45
+ statemachine/io/scxml/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ statemachine/io/scxml/actions.py,sha256=M1fAsuf0gJlnpMWXgoxCwpOk2MQSh8wBvtupp38T9n8,22491
47
+ statemachine/io/scxml/invoke.py,sha256=raRStlMBOfxto6KIkCbi3jJ3UQ3QfuT0ezn4B48A670,8443
48
+ statemachine/io/scxml/parser.py,sha256=zggZwu0rHZNWDaJTHD2XC3MrCy_bi4CNHStfWE9NHgU,16582
49
+ statemachine/io/scxml/processor.py,sha256=_hjW4VTuzbPK2q5a7dp2kYMBcbRBZFbjz-wJKSZLI8I,9467
50
+ statemachine/io/scxml/schema.py,sha256=xNpW_nkS2Z_hye5p1WLr8VhuM85Nic2HqRLCnoFN3ss,3927
51
+ statemachine/locale/en/LC_MESSAGES/statemachine.po,sha256=exLJzm2uGsLWbggRKvgLzqqBstusQWu38HC0IMxEI6g,5338
52
+ statemachine/locale/hi_IN/LC_MESSAGES/statemachine.po,sha256=aAA-ZsZt0SWM5zykZMuaQQli0DWS-yKkMM7lnXHIF10,7948
53
+ statemachine/locale/pt_BR/LC_MESSAGES/statemachine.po,sha256=4Gc2vilchzx1-zTmQqJgweFz_wHzEJBjUG4bgR0xlNI,5814
54
+ statemachine/locale/zh_CN/LC_MESSAGES/statemachine.po,sha256=X51ghMEP9ZNda9HZO0hcYez4HdXuvi-0GXKay2S3ZIQ,5369
55
+ python_statemachine-3.1.0.dist-info/METADATA,sha256=-Hi9lHdURp725XVA52Ew2j6PGKWN1xN2Y1caBTVtCYg,12249
56
+ python_statemachine-3.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
57
+ python_statemachine-3.1.0.dist-info/licenses/LICENSE,sha256=zcP7TsJMqaFxuTvLRZPT7nJl3_ppjxR9Z76BE9pL5zc,1074
58
+ python_statemachine-3.1.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.28.0
2
+ Generator: hatchling 1.29.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
statemachine/__init__.py CHANGED
@@ -1,9 +1,21 @@
1
1
  from .event import Event
2
+ from .state import HistoryState
3
+ from .state import HistoryType
2
4
  from .state import State
5
+ from .statemachine import StateChart
3
6
  from .statemachine import StateMachine
7
+ from .statemachine import TModel
4
8
 
5
9
  __author__ = """Fernando Macedo"""
6
10
  __email__ = "fgmacedo@gmail.com"
7
- __version__ = "2.6.0"
11
+ __version__ = "3.1.0"
8
12
 
9
- __all__ = ["StateMachine", "State", "Event"]
13
+ __all__ = [
14
+ "StateChart",
15
+ "StateMachine",
16
+ "State",
17
+ "HistoryState",
18
+ "HistoryType",
19
+ "Event",
20
+ "TModel",
21
+ ]