python-statemachine 2.6.0__py3-none-any.whl → 3.0.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.
- python_statemachine-3.0.0.dist-info/METADATA +414 -0
- python_statemachine-3.0.0.dist-info/RECORD +48 -0
- {python_statemachine-2.6.0.dist-info → python_statemachine-3.0.0.dist-info}/WHEEL +1 -1
- statemachine/__init__.py +14 -2
- statemachine/callbacks.py +131 -38
- statemachine/contrib/diagram.py +178 -50
- statemachine/contrib/timeout.py +68 -0
- statemachine/contrib/weighted.py +193 -0
- statemachine/dispatcher.py +2 -2
- statemachine/engines/async_.py +492 -117
- statemachine/engines/base.py +921 -18
- statemachine/engines/sync.py +158 -108
- statemachine/event.py +90 -21
- statemachine/event_data.py +26 -11
- statemachine/events.py +12 -3
- statemachine/exceptions.py +8 -4
- statemachine/factory.py +165 -67
- statemachine/graph.py +46 -4
- statemachine/invoke.py +603 -0
- statemachine/io/__init__.py +225 -0
- statemachine/io/scxml/__init__.py +0 -0
- statemachine/io/scxml/actions.py +649 -0
- statemachine/io/scxml/invoke.py +233 -0
- statemachine/io/scxml/parser.py +473 -0
- statemachine/io/scxml/processor.py +263 -0
- statemachine/io/scxml/schema.py +175 -0
- statemachine/locale/en/LC_MESSAGES/statemachine.po +65 -39
- statemachine/locale/hi_IN/LC_MESSAGES/statemachine.po +51 -26
- statemachine/locale/pt_BR/LC_MESSAGES/statemachine.po +51 -26
- statemachine/locale/zh_CN/LC_MESSAGES/statemachine.po +47 -26
- statemachine/orderedset.py +118 -0
- statemachine/registry.py +4 -10
- statemachine/signature.py +3 -1
- statemachine/spec_parser.py +50 -9
- statemachine/state.py +227 -26
- statemachine/statemachine.py +292 -79
- statemachine/states.py +22 -19
- statemachine/transition.py +46 -8
- statemachine/transition_list.py +7 -0
- statemachine/transition_mixin.py +6 -2
- statemachine/utils.py +2 -1
- python_statemachine-2.6.0.dist-info/METADATA +0 -433
- python_statemachine-2.6.0.dist-info/RECORD +0 -37
- {python_statemachine-2.6.0.dist-info → python_statemachine-3.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-statemachine
|
|
3
|
+
Version: 3.0.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>=2.0.0; extra == 'diagrams'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# Python StateMachine
|
|
30
|
+
|
|
31
|
+
[](https://pypi.python.org/pypi/python-statemachine)
|
|
32
|
+
[](https://pepy.tech/project/python-statemachine)
|
|
33
|
+
[](https://pypi.python.org/pypi/python-statemachine)
|
|
34
|
+
[](https://codecov.io/gh/fgmacedo/python-statemachine)
|
|
35
|
+
[](https://python-statemachine.readthedocs.io/en/latest/?badge=latest)
|
|
36
|
+
[](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
|
+

|
|
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:
|
|
109
|
+
|
|
110
|
+
```py
|
|
111
|
+
>>> # This example will only run on automated tests if dot is present
|
|
112
|
+
>>> getfixture("requires_dot_installed")
|
|
113
|
+
>>> img_path = "docs/images/readme_trafficlightmachine.png"
|
|
114
|
+
>>> sm._graph().write_png(img_path)
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+

|
|
119
|
+
|
|
120
|
+
Parameters are injected into callbacks automatically — the library inspects the
|
|
121
|
+
signature and provides only the arguments each callback needs:
|
|
122
|
+
|
|
123
|
+
```py
|
|
124
|
+
>>> sm.send("cycle")
|
|
125
|
+
'Running cycle from green to yellow'
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
## Guards and conditional transitions
|
|
131
|
+
|
|
132
|
+
Use `cond=` and `unless=` to add guards. When multiple transitions share the same
|
|
133
|
+
event, declaration order determines priority:
|
|
134
|
+
|
|
135
|
+
```py
|
|
136
|
+
>>> from statemachine import StateChart, State
|
|
137
|
+
|
|
138
|
+
>>> class ApprovalWorkflow(StateChart):
|
|
139
|
+
... pending = State(initial=True)
|
|
140
|
+
... approved = State(final=True)
|
|
141
|
+
... rejected = State(final=True)
|
|
142
|
+
...
|
|
143
|
+
... review = (
|
|
144
|
+
... pending.to(approved, cond="is_valid")
|
|
145
|
+
... | pending.to(rejected)
|
|
146
|
+
... )
|
|
147
|
+
...
|
|
148
|
+
... def is_valid(self, score: int = 0):
|
|
149
|
+
... return score >= 70
|
|
150
|
+
|
|
151
|
+
>>> sm = ApprovalWorkflow()
|
|
152
|
+
>>> sm.send("review", score=50)
|
|
153
|
+
>>> sm.rejected.is_active
|
|
154
|
+
True
|
|
155
|
+
|
|
156
|
+
>>> sm = ApprovalWorkflow()
|
|
157
|
+
>>> sm.send("review", score=85)
|
|
158
|
+
>>> sm.approved.is_active
|
|
159
|
+
True
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The first transition whose guard passes wins. When `score < 70`, `is_valid` returns
|
|
164
|
+
`False` so the second transition (no guard — always matches) fires instead.
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
## Compound states — hierarchy
|
|
168
|
+
|
|
169
|
+
Break complex behavior into hierarchical levels with `State.Compound`. Entering a
|
|
170
|
+
compound activates both the parent and its `initial` child. Exiting removes the
|
|
171
|
+
parent and all descendants:
|
|
172
|
+
|
|
173
|
+
```py
|
|
174
|
+
>>> from statemachine import StateChart, State
|
|
175
|
+
|
|
176
|
+
>>> class DocumentWorkflow(StateChart):
|
|
177
|
+
... class editing(State.Compound):
|
|
178
|
+
... draft = State(initial=True)
|
|
179
|
+
... review = State()
|
|
180
|
+
... submit = draft.to(review)
|
|
181
|
+
... revise = review.to(draft)
|
|
182
|
+
...
|
|
183
|
+
... published = State(final=True)
|
|
184
|
+
... approve = editing.to(published)
|
|
185
|
+
|
|
186
|
+
>>> sm = DocumentWorkflow()
|
|
187
|
+
>>> set(sm.configuration_values) == {"editing", "draft"}
|
|
188
|
+
True
|
|
189
|
+
|
|
190
|
+
>>> sm.send("submit")
|
|
191
|
+
>>> "review" in sm.configuration_values
|
|
192
|
+
True
|
|
193
|
+
|
|
194
|
+
>>> sm.send("approve")
|
|
195
|
+
>>> set(sm.configuration_values) == {"published"}
|
|
196
|
+
True
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
## Parallel states — concurrency
|
|
202
|
+
|
|
203
|
+
`State.Parallel` activates all child regions simultaneously. Events in one
|
|
204
|
+
region don't affect others. A `done.state` event fires only when **all**
|
|
205
|
+
regions reach a final state:
|
|
206
|
+
|
|
207
|
+
```py
|
|
208
|
+
>>> from statemachine import StateChart, State
|
|
209
|
+
|
|
210
|
+
>>> class DeployPipeline(StateChart):
|
|
211
|
+
... class deploy(State.Parallel):
|
|
212
|
+
... class build(State.Compound):
|
|
213
|
+
... compiling = State(initial=True)
|
|
214
|
+
... compiled = State(final=True)
|
|
215
|
+
... finish_build = compiling.to(compiled)
|
|
216
|
+
... class tests(State.Compound):
|
|
217
|
+
... running = State(initial=True)
|
|
218
|
+
... passed = State(final=True)
|
|
219
|
+
... finish_tests = running.to(passed)
|
|
220
|
+
... released = State(final=True)
|
|
221
|
+
... done_state_deploy = deploy.to(released)
|
|
222
|
+
|
|
223
|
+
>>> sm = DeployPipeline()
|
|
224
|
+
>>> "compiling" in sm.configuration_values and "running" in sm.configuration_values
|
|
225
|
+
True
|
|
226
|
+
|
|
227
|
+
>>> sm.send("finish_build")
|
|
228
|
+
>>> "compiled" in sm.configuration_values and "running" in sm.configuration_values
|
|
229
|
+
True
|
|
230
|
+
|
|
231
|
+
>>> sm.send("finish_tests")
|
|
232
|
+
>>> set(sm.configuration_values) == {"released"}
|
|
233
|
+
True
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
## History states
|
|
239
|
+
|
|
240
|
+
`HistoryState()` records which child was active when a compound is exited.
|
|
241
|
+
Re-entering via the history pseudo-state restores the previous child instead
|
|
242
|
+
of starting from the initial one:
|
|
243
|
+
|
|
244
|
+
```py
|
|
245
|
+
>>> from statemachine import HistoryState, StateChart, State
|
|
246
|
+
|
|
247
|
+
>>> class EditorWithHistory(StateChart):
|
|
248
|
+
... class editor(State.Compound):
|
|
249
|
+
... source = State(initial=True)
|
|
250
|
+
... visual = State()
|
|
251
|
+
... h = HistoryState()
|
|
252
|
+
... toggle = source.to(visual) | visual.to(source)
|
|
253
|
+
... settings = State()
|
|
254
|
+
... open_settings = editor.to(settings)
|
|
255
|
+
... back = settings.to(editor.h)
|
|
256
|
+
|
|
257
|
+
>>> sm = EditorWithHistory()
|
|
258
|
+
>>> sm.send("toggle")
|
|
259
|
+
>>> "visual" in sm.configuration_values
|
|
260
|
+
True
|
|
261
|
+
|
|
262
|
+
>>> sm.send("open_settings")
|
|
263
|
+
>>> sm.send("back")
|
|
264
|
+
>>> "visual" in sm.configuration_values
|
|
265
|
+
True
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Use `HistoryState(type="deep")` for deep history that remembers the exact leaf
|
|
270
|
+
state across nested compounds.
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
## Eventless transitions
|
|
274
|
+
|
|
275
|
+
Transitions without an event trigger fire automatically. With a guard, they
|
|
276
|
+
fire after any event processing when the condition is met:
|
|
277
|
+
|
|
278
|
+
```py
|
|
279
|
+
>>> from statemachine import StateChart, State
|
|
280
|
+
|
|
281
|
+
>>> class AutoCounter(StateChart):
|
|
282
|
+
... counting = State(initial=True)
|
|
283
|
+
... done = State(final=True)
|
|
284
|
+
...
|
|
285
|
+
... counting.to(done, cond="limit_reached")
|
|
286
|
+
... increment = counting.to.itself(internal=True, on="do_increment")
|
|
287
|
+
...
|
|
288
|
+
... count = 0
|
|
289
|
+
...
|
|
290
|
+
... def do_increment(self):
|
|
291
|
+
... self.count += 1
|
|
292
|
+
... def limit_reached(self):
|
|
293
|
+
... return self.count >= 3
|
|
294
|
+
|
|
295
|
+
>>> sm = AutoCounter()
|
|
296
|
+
>>> sm.send("increment")
|
|
297
|
+
>>> sm.send("increment")
|
|
298
|
+
>>> "counting" in sm.configuration_values
|
|
299
|
+
True
|
|
300
|
+
|
|
301
|
+
>>> sm.send("increment")
|
|
302
|
+
>>> "done" in sm.configuration_values
|
|
303
|
+
True
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
## Error handling
|
|
309
|
+
|
|
310
|
+
When using `StateChart`, runtime exceptions in callbacks are caught and
|
|
311
|
+
turned into `error.execution` events. Define a transition for that event
|
|
312
|
+
to handle errors within the state machine itself:
|
|
313
|
+
|
|
314
|
+
```py
|
|
315
|
+
>>> from statemachine import StateChart, State
|
|
316
|
+
|
|
317
|
+
>>> class ResilientService(StateChart):
|
|
318
|
+
... running = State(initial=True)
|
|
319
|
+
... failed = State(final=True)
|
|
320
|
+
...
|
|
321
|
+
... process = running.to(running, on="do_work")
|
|
322
|
+
... error_execution = running.to(failed)
|
|
323
|
+
...
|
|
324
|
+
... def do_work(self):
|
|
325
|
+
... raise RuntimeError("something broke")
|
|
326
|
+
|
|
327
|
+
>>> sm = ResilientService()
|
|
328
|
+
>>> sm.send("process")
|
|
329
|
+
>>> sm.failed.is_active
|
|
330
|
+
True
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
## Async support
|
|
336
|
+
|
|
337
|
+
Async callbacks just work — same API, no changes needed. The engine
|
|
338
|
+
detects async callbacks and switches to the async engine automatically:
|
|
339
|
+
|
|
340
|
+
```py
|
|
341
|
+
>>> import asyncio
|
|
342
|
+
>>> from statemachine import StateChart, State
|
|
343
|
+
|
|
344
|
+
>>> class AsyncWorkflow(StateChart):
|
|
345
|
+
... idle = State(initial=True)
|
|
346
|
+
... done = State(final=True)
|
|
347
|
+
...
|
|
348
|
+
... finish = idle.to(done)
|
|
349
|
+
...
|
|
350
|
+
... async def on_finish(self):
|
|
351
|
+
... return 42
|
|
352
|
+
|
|
353
|
+
>>> async def run():
|
|
354
|
+
... sm = AsyncWorkflow()
|
|
355
|
+
... result = await sm.finish()
|
|
356
|
+
... print(f"Result: {result}")
|
|
357
|
+
... print(sm.done.is_active)
|
|
358
|
+
|
|
359
|
+
>>> asyncio.run(run())
|
|
360
|
+
Result: 42
|
|
361
|
+
True
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
## More features
|
|
367
|
+
|
|
368
|
+
There's a lot more to explore:
|
|
369
|
+
|
|
370
|
+
- **DoneData** on final states — pass structured data to `done.state` handlers
|
|
371
|
+
- **Delayed events** — schedule events with `sm.send("event", delay=500)`
|
|
372
|
+
- **`In(state)` conditions** — cross-region guards in parallel states
|
|
373
|
+
- **`prepare_event`** callback — inject custom data into all callbacks
|
|
374
|
+
- **Observer pattern** — register external listeners to watch events and state changes
|
|
375
|
+
- **Django integration** — auto-discover state machines in Django apps with `MachineMixin`
|
|
376
|
+
- **Diagram generation** — from the CLI, at runtime, or in Jupyter notebooks
|
|
377
|
+
- **Dictionary-based definitions** — create state machines from data structures
|
|
378
|
+
- **Internationalization** — error messages in multiple languages
|
|
379
|
+
|
|
380
|
+
Full documentation: https://python-statemachine.readthedocs.io
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
## Installing
|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
pip install python-statemachine
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
To generate diagrams, install with the `diagrams` extra (requires
|
|
390
|
+
[Graphviz](https://graphviz.org/)):
|
|
391
|
+
|
|
392
|
+
```
|
|
393
|
+
pip install python-statemachine[diagrams]
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
## Contributing
|
|
398
|
+
|
|
399
|
+
- If you found this project helpful, please consider giving it a star on GitHub.
|
|
400
|
+
|
|
401
|
+
- **Contribute code**: If you would like to contribute code, please submit a pull
|
|
402
|
+
request. For more information on how to contribute, please see our [contributing.md](contributing.md) file.
|
|
403
|
+
|
|
404
|
+
- **Report bugs**: If you find any bugs, please report them by opening an issue
|
|
405
|
+
on our GitHub issue tracker.
|
|
406
|
+
|
|
407
|
+
- **Suggest features**: If you have an idea for a new feature, or feel something is harder than it should be,
|
|
408
|
+
please let us know by opening an issue on our GitHub issue tracker.
|
|
409
|
+
|
|
410
|
+
- **Documentation**: Help improve documentation by submitting pull requests.
|
|
411
|
+
|
|
412
|
+
- **Promote the project**: Help spread the word by sharing on social media,
|
|
413
|
+
writing a blog post, or giving a talk about it. Tag me on Twitter
|
|
414
|
+
[@fgmacedo](https://twitter.com/fgmacedo) so I can share it too!
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
statemachine/__init__.py,sha256=KP0MJDUTjW1ds6_fMRp5ijZdyVERZjr8bPi5z28dEx4,445
|
|
2
|
+
statemachine/callbacks.py,sha256=mY_RAl86240vG2C94ij6AdD7CgsIM8mr0wvpSAMAPv0,14644
|
|
3
|
+
statemachine/dispatcher.py,sha256=xvA1Kf1xGQivHTpaGm_HC22vqAmE_tTm9LQwyVLRWLE,7841
|
|
4
|
+
statemachine/event.py,sha256=OFYe1ra46VXmlIEOt6Daj1exxws2FgatV5O8htcrTs8,7287
|
|
5
|
+
statemachine/event_data.py,sha256=4pDNcrlhqTTIaP_IlcmyB4g8kJkjj6XNb33rHKAQ924,3076
|
|
6
|
+
statemachine/events.py,sha256=OPg7DgocYfe5TCsLd-gLGp9BPInHGSHgeYu4yyQjUIk,1224
|
|
7
|
+
statemachine/exceptions.py,sha256=gXFvDsEtIxKdcGrRG9mwDgXqFQDXfw8v66_VXaQgGr4,1305
|
|
8
|
+
statemachine/factory.py,sha256=UlLLzh5VxGd2V3MalpQ-Amg7LmC4UsJF5ww7wEyCaIM,13442
|
|
9
|
+
statemachine/graph.py,sha256=r-8L7jXab1_VLtVu-Ig8bpe4Szo-r6WDFTdbfcepyZM,1981
|
|
10
|
+
statemachine/i18n.py,sha256=NLvGseaORmQ0G-V_J8tkjoxh_piWMOm2CI6mBQpLamc,362
|
|
11
|
+
statemachine/invoke.py,sha256=3hFzMXACEtxdUCi97_6gOHrvQYJRDGjk3sF-OdgAFpU,23384
|
|
12
|
+
statemachine/mixins.py,sha256=8qxZZfBwVdFcr3oPFVWHGzgmAubH6VgQus5x3c6VEE0,1706
|
|
13
|
+
statemachine/model.py,sha256=OylI3FjMiHpYyDl9mtK1zEJMeSvemaN4giQDonpc8kI,211
|
|
14
|
+
statemachine/orderedset.py,sha256=PjbegcS7WPJAzC7jQ411_JrFJYEz6mmLRsAZ7aI9BWc,2543
|
|
15
|
+
statemachine/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
statemachine/registry.py,sha256=onT8U5QgYlCSJxgxvi_TY1c1oDetHykOwnyiFk5qoN0,756
|
|
17
|
+
statemachine/signature.py,sha256=N8Vt4X3YOA-NB8oidPAbYZxBgqZm6GYAiuHxBWb1l1s,9922
|
|
18
|
+
statemachine/spec_parser.py,sha256=Io0J5D9s-nu2YdgUlr2cSethGfCS0pSLNmxMCXdwMqQ,8307
|
|
19
|
+
statemachine/state.py,sha256=X1gKN1p75eUKL_Zkso3lDXFIsjNVEGlu05zXocgszKo,16349
|
|
20
|
+
statemachine/statemachine.py,sha256=VBm0X-lpN4701e0TuA_WXC1c79x46mE7qB2PrGTvOas,20281
|
|
21
|
+
statemachine/states.py,sha256=kWo7y95ikXxNmcf_-J2UoMIwd3NaIdxpHMfoHr3cQ_Y,4934
|
|
22
|
+
statemachine/transition.py,sha256=x9hhxIEyQ7tqsvaXkHg1bVO5hMAjemgHfZhyuypHoOY,6936
|
|
23
|
+
statemachine/transition_list.py,sha256=6NAyOGEgoGOzTYiLfPM21CBVI1tPO63ZIwbaZlqOPI4,4376
|
|
24
|
+
statemachine/transition_mixin.py,sha256=XGGd2J4DnFrqIpeej3QFDOuqI0CAiYwnIb8-_9DpemA,2993
|
|
25
|
+
statemachine/utils.py,sha256=tyJqMSQLKcKMwV7xI0oepNVw1Pse243gS7JKvIQWtUk,1080
|
|
26
|
+
statemachine/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
statemachine/contrib/diagram.py,sha256=tGKbw6w7FExev8H6hXpfR4L0Inh9c__z84f5lmtPpOY,11803
|
|
28
|
+
statemachine/contrib/timeout.py,sha256=VXkdLpxNeUKihkbtLv8XTWdG-meQlSFtxJfcxXgV8Uw,2251
|
|
29
|
+
statemachine/contrib/weighted.py,sha256=jcKkm25df6NnzBzuss1-ewDEasZ_CyME03xgJXrwcso,6866
|
|
30
|
+
statemachine/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
statemachine/engines/async_.py,sha256=4oURLGw0DGRQbootRUY5WhOBIkxoFqykghTW4K6SIXs,22629
|
|
32
|
+
statemachine/engines/base.py,sha256=QfCjQyEIWTcOd5lJtFq7u6SUMZA6PDyUPlY2T4unn3E,37467
|
|
33
|
+
statemachine/engines/sync.py,sha256=Z7ItPaKzFwFmm6NSheuekevsYmlmSOmHJs_au0U0D8M,9251
|
|
34
|
+
statemachine/io/__init__.py,sha256=1J_oVSWrWmx9bLrGU-YoWyO-YYbO6T9Z6vUAnerKe3Q,8739
|
|
35
|
+
statemachine/io/scxml/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
+
statemachine/io/scxml/actions.py,sha256=sxDuJb6AY6TJy6PZpEXBmAclRcnlYytpDcnNKpb_gS4,22447
|
|
37
|
+
statemachine/io/scxml/invoke.py,sha256=raRStlMBOfxto6KIkCbi3jJ3UQ3QfuT0ezn4B48A670,8443
|
|
38
|
+
statemachine/io/scxml/parser.py,sha256=zggZwu0rHZNWDaJTHD2XC3MrCy_bi4CNHStfWE9NHgU,16582
|
|
39
|
+
statemachine/io/scxml/processor.py,sha256=_hjW4VTuzbPK2q5a7dp2kYMBcbRBZFbjz-wJKSZLI8I,9467
|
|
40
|
+
statemachine/io/scxml/schema.py,sha256=xNpW_nkS2Z_hye5p1WLr8VhuM85Nic2HqRLCnoFN3ss,3927
|
|
41
|
+
statemachine/locale/en/LC_MESSAGES/statemachine.po,sha256=m6Fb8W-AQnSPTxYMZ8Xw68rScY4tjZ3wh8KVZQedDE0,4581
|
|
42
|
+
statemachine/locale/hi_IN/LC_MESSAGES/statemachine.po,sha256=3le5j-3QqZ6zW0dE0rBEID9EfOkilyk66IFWSI68aG0,7035
|
|
43
|
+
statemachine/locale/pt_BR/LC_MESSAGES/statemachine.po,sha256=3OYJ_WUKIxmve4yDvIZ9PHBuXYQHCgHXx9bQC1pnIsI,5037
|
|
44
|
+
statemachine/locale/zh_CN/LC_MESSAGES/statemachine.po,sha256=PjOMlWHdgzFXxvjTV1ZgYhOL3NeDpAxlMnJFHsPFdS4,4605
|
|
45
|
+
python_statemachine-3.0.0.dist-info/METADATA,sha256=3nqo-g3T-ibZKRoIVgzEGex90C-rwTgchEexdZDORAE,12121
|
|
46
|
+
python_statemachine-3.0.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
47
|
+
python_statemachine-3.0.0.dist-info/licenses/LICENSE,sha256=zcP7TsJMqaFxuTvLRZPT7nJl3_ppjxR9Z76BE9pL5zc,1074
|
|
48
|
+
python_statemachine-3.0.0.dist-info/RECORD,,
|
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__ = "
|
|
11
|
+
__version__ = "3.0.0"
|
|
8
12
|
|
|
9
|
-
__all__ = [
|
|
13
|
+
__all__ = [
|
|
14
|
+
"StateChart",
|
|
15
|
+
"StateMachine",
|
|
16
|
+
"State",
|
|
17
|
+
"HistoryState",
|
|
18
|
+
"HistoryType",
|
|
19
|
+
"Event",
|
|
20
|
+
"TModel",
|
|
21
|
+
]
|