python-statemachine 2.3.0__py3-none-any.whl → 2.3.2__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.
@@ -1,15 +1,10 @@
1
- from typing import TYPE_CHECKING
2
-
3
- from .callbacks import BoolCallbackMeta
4
- from .callbacks import CallbackMetaList
1
+ from .callbacks import CallbackGroup
5
2
  from .callbacks import CallbackPriority
3
+ from .callbacks import CallbackSpecList
6
4
  from .event import same_event_cond_builder
7
5
  from .events import Events
8
6
  from .exceptions import InvalidDefinition
9
7
 
10
- if TYPE_CHECKING:
11
- from .event_data import EventData
12
-
13
8
 
14
9
  class Transition:
15
10
  """A transition holds reference to the source and target state.
@@ -57,13 +52,20 @@ class Transition:
57
52
  raise InvalidDefinition("Internal transitions should be self-transitions.")
58
53
 
59
54
  self._events = Events().add(event)
60
- self.validators = CallbackMetaList().add(validators, priority=CallbackPriority.INLINE)
61
- self.before = CallbackMetaList().add(before, priority=CallbackPriority.INLINE)
62
- self.on = CallbackMetaList().add(on, priority=CallbackPriority.INLINE)
63
- self.after = CallbackMetaList().add(after, priority=CallbackPriority.INLINE)
55
+ self._specs = CallbackSpecList()
56
+ self.validators = self._specs.grouper(CallbackGroup.VALIDATOR).add(
57
+ validators, priority=CallbackPriority.INLINE
58
+ )
59
+ self.before = self._specs.grouper(CallbackGroup.BEFORE).add(
60
+ before, priority=CallbackPriority.INLINE
61
+ )
62
+ self.on = self._specs.grouper(CallbackGroup.ON).add(on, priority=CallbackPriority.INLINE)
63
+ self.after = self._specs.grouper(CallbackGroup.AFTER).add(
64
+ after, priority=CallbackPriority.INLINE
65
+ )
64
66
  self.cond = (
65
- CallbackMetaList(factory=BoolCallbackMeta)
66
- .add(cond, priority=CallbackPriority.INLINE)
67
+ self._specs.grouper(CallbackGroup.COND)
68
+ .add(cond, priority=CallbackPriority.INLINE, expected_value=True)
67
69
  .add(unless, priority=CallbackPriority.INLINE, expected_value=False)
68
70
  )
69
71
 
@@ -81,51 +83,37 @@ class Transition:
81
83
  on = self.on.add
82
84
  after = self.after.add
83
85
 
84
- before("before_transition", priority=CallbackPriority.GENERIC, suppress_errors=True)
85
- on("on_transition", priority=CallbackPriority.GENERIC, suppress_errors=True)
86
+ before("before_transition", priority=CallbackPriority.GENERIC, is_convention=True)
87
+ on("on_transition", priority=CallbackPriority.GENERIC, is_convention=True)
86
88
 
87
89
  for event in self._events:
88
90
  same_event_cond = same_event_cond_builder(event)
89
91
  before(
90
92
  f"before_{event}",
91
93
  priority=CallbackPriority.NAMING,
92
- suppress_errors=True,
94
+ is_convention=True,
93
95
  cond=same_event_cond,
94
96
  )
95
97
  on(
96
98
  f"on_{event}",
97
99
  priority=CallbackPriority.NAMING,
98
- suppress_errors=True,
100
+ is_convention=True,
99
101
  cond=same_event_cond,
100
102
  )
101
103
  after(
102
104
  f"after_{event}",
103
105
  priority=CallbackPriority.NAMING,
104
- suppress_errors=True,
106
+ is_convention=True,
105
107
  cond=same_event_cond,
106
108
  )
107
109
 
108
110
  after(
109
111
  "after_transition",
110
112
  priority=CallbackPriority.AFTER,
111
- suppress_errors=True,
113
+ is_convention=True,
112
114
  )
113
115
 
114
- def _add_observer(self, register):
115
- register(self.validators)
116
- register(self.cond)
117
- register(self.before)
118
- register(self.on)
119
- register(self.after)
120
-
121
- def _check_callbacks(self, check):
122
- check(self.validators)
123
- check(self.cond)
124
- check(self.before)
125
- check(self.on)
126
- check(self.after)
127
-
128
- def match(self, event):
116
+ def match(self, event: str):
129
117
  return self._events.match(event)
130
118
 
131
119
  @property
@@ -138,14 +126,3 @@ class Transition:
138
126
 
139
127
  def add_event(self, value):
140
128
  self._events.add(value)
141
-
142
- async def execute(self, event_data: "EventData"):
143
- machine = event_data.machine
144
- args, kwargs = event_data.args, event_data.extended_kwargs
145
- await machine._callbacks_registry[self.validators].call(*args, **kwargs)
146
- if not await machine._callbacks_registry[self.cond].all(*args, **kwargs):
147
- return False
148
-
149
- result = await machine._activate(event_data)
150
- event_data.result = result
151
- return True
@@ -1,25 +1,22 @@
1
- from typing import TYPE_CHECKING
2
1
  from typing import Callable
3
2
  from typing import Iterable
4
3
  from typing import List
5
4
 
5
+ from .transition import Transition
6
6
  from .utils import ensure_iterable
7
7
 
8
- if TYPE_CHECKING:
9
- from .transition import Transition
10
-
11
8
 
12
9
  class TransitionList:
13
10
  """A list-like container of :ref:`transitions` with callback functions."""
14
11
 
15
- def __init__(self, transitions: "Iterable | None" = None):
12
+ def __init__(self, transitions: "Iterable[Transition] | None" = None):
16
13
  """
17
14
  Args:
18
15
  transitions: An iterable of `Transition` objects.
19
16
  Defaults to `None`.
20
17
 
21
18
  """
22
- self.transitions = list(transitions) if transitions else []
19
+ self.transitions: List[Transition] = list(transitions) if transitions else []
23
20
 
24
21
  def __repr__(self):
25
22
  """Return a string representation of the :ref:`TransitionList`."""
@@ -53,11 +50,12 @@ class TransitionList:
53
50
  transitions = ensure_iterable(transition)
54
51
 
55
52
  for transition in transitions:
53
+ assert isinstance(transition, Transition) # makes mypy happy
56
54
  self.transitions.append(transition)
57
55
 
58
56
  return self
59
57
 
60
- def __getitem__(self, index: int):
58
+ def __getitem__(self, index: int) -> "Transition":
61
59
  """Returns the :ref:`transition` at the specified ``index``.
62
60
 
63
61
  Args:
@@ -136,7 +134,7 @@ class TransitionList:
136
134
  Returns:
137
135
  The `f` callable.
138
136
  """
139
- return self._add_callback(f, "cond")
137
+ return self._add_callback(f, "cond", expected_value=True)
140
138
 
141
139
  def unless(self, f: Callable):
142
140
  """Adds a ``unless`` :ref:`guards` callback with expected value ``False`` to every
statemachine/utils.py CHANGED
@@ -1,4 +1,8 @@
1
1
  import asyncio
2
+ import threading
3
+
4
+ _cached_loop = threading.local()
5
+ """Loop that will be used when the SM is running in a synchronous context. One loop per thread."""
2
6
 
3
7
 
4
8
  def qualname(cls):
@@ -23,11 +27,13 @@ def ensure_iterable(obj):
23
27
 
24
28
  def run_async_from_sync(coroutine):
25
29
  """
26
- Run an async coroutine from a synchronous context.
30
+ Compatibility layer to run an async coroutine from a synchronous context.
27
31
  """
32
+ global _cached_loop
28
33
  try:
29
- loop = asyncio.get_running_loop()
30
- return asyncio.ensure_future(coroutine)
34
+ asyncio.get_running_loop()
35
+ return coroutine
31
36
  except RuntimeError:
32
- loop = asyncio.get_event_loop()
33
- return loop.run_until_complete(coroutine)
37
+ if not hasattr(_cached_loop, "loop"):
38
+ _cached_loop.loop = asyncio.new_event_loop()
39
+ return _cached_loop.loop.run_until_complete(coroutine)
@@ -1,28 +0,0 @@
1
- statemachine/__init__.py,sha256=Omi4-IXrTE0oLfO3oF75OqMYBI9TrbZeBzZIkt-F0rU,192
2
- statemachine/callbacks.py,sha256=D1mb3Ky18S1jk0-ursuJljqDv63WZShnMvMK_S1Hi9k,8846
3
- statemachine/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- statemachine/contrib/diagram.py,sha256=CTlNRtAHEzCCzRUlxkiyzJOCOp1CohihdD0_7pHrx4c,7004
5
- statemachine/dispatcher.py,sha256=Zizr_Qaj2BfuHu5VbbnNh1giT_pUVLe4mekHj6Ca2dk,5075
6
- statemachine/event.py,sha256=lfJUSvkDQTnk1COueuV--xQD4o6GeaI94Y8tTOmiS6s,2304
7
- statemachine/event_data.py,sha256=nxOfypngK-78A77gj4pS-oxLx9zl1S9wnSt_rTiCyZA,2257
8
- statemachine/events.py,sha256=rUbiTX-QGoo7zzmQMEeWeLrIVnp9zhicdRIm34CoAVI,731
9
- statemachine/exceptions.py,sha256=RWq1vTjajxt8CzfYCD4DfI2nrgkfCPBL0DjRDOzKkQI,1086
10
- statemachine/factory.py,sha256=pAfRUuO474FekxrUZkKr8NkQqQ59vOu4dRHSD8Dr9rI,7982
11
- statemachine/graph.py,sha256=KtwB1CYckaLjTgQD9tEeuaEzJje9q3fPVpBViW5TgSk,487
12
- statemachine/i18n.py,sha256=NLvGseaORmQ0G-V_J8tkjoxh_piWMOm2CI6mBQpLamc,362
13
- statemachine/locale/en/LC_MESSAGES/statemachine.po,sha256=zJYaV2DxrHdPngDOt1bji8-lPOZMSDjWG83Ypru5DOI,2126
14
- statemachine/locale/pt_BR/LC_MESSAGES/statemachine.po,sha256=SPrt-KaCBCKQq7PoOMtyyqU1bihrw_3MPL_NbqZzTVs,3214
15
- statemachine/mixins.py,sha256=B8WB3EGyZpMWAQg4Nw3kUMCfswgmLCChDpOQdxR28eE,1017
16
- statemachine/model.py,sha256=OylI3FjMiHpYyDl9mtK1zEJMeSvemaN4giQDonpc8kI,211
17
- statemachine/registry.py,sha256=RnVBRS3I_6Tm2OMgXMB_ewX7zQaslqEfhXFOhbqIkG4,959
18
- statemachine/signature.py,sha256=aGoKxC36mTO60GGICVlyduhhB2nKVOXOOHepcBG2Uws,7809
19
- statemachine/state.py,sha256=bZki0DyemZa-aVAfollQCmpXxesWONzUmE28eDfqz3o,8315
20
- statemachine/statemachine.py,sha256=5r8vtbMFQtOq9W8UmaWBN_SIzOHkO-4JfPysHfdoB8w,13827
21
- statemachine/states.py,sha256=gdGemJYF9k-cifs9Tk0Pe_-1u1Lanf3l08o0t8wAMgg,4203
22
- statemachine/transition.py,sha256=fo6B-XlHDqU8TNrDXBSn4GStdGUrZbcfbEgtsdESmrk,5412
23
- statemachine/transition_list.py,sha256=DatsmMWgK0YK30Nrj-josVvlTgeGapKutzYur9-puF8,5949
24
- statemachine/utils.py,sha256=FVtvT1lBSP3mRrYM-wxsX2pV_NZwSDsoBW4syIpACeE,798
25
- python_statemachine-2.3.0.dist-info/LICENSE,sha256=zcP7TsJMqaFxuTvLRZPT7nJl3_ppjxR9Z76BE9pL5zc,1074
26
- python_statemachine-2.3.0.dist-info/METADATA,sha256=ubb6vnMCYaYyz486RJW5r1dKKu_emWD7Rwc4x2S7lyY,14361
27
- python_statemachine-2.3.0.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
28
- python_statemachine-2.3.0.dist-info/RECORD,,