python-statemachine 2.3.3__tar.gz → 2.3.4__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 (31) hide show
  1. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/PKG-INFO +1 -1
  2. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/pyproject.toml +8 -7
  3. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/__init__.py +1 -1
  4. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/callbacks.py +9 -4
  5. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/dispatcher.py +13 -5
  6. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/statemachine.py +14 -7
  7. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/states.py +7 -6
  8. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/LICENSE +0 -0
  9. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/README.md +0 -0
  10. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/contrib/__init__.py +0 -0
  11. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/contrib/diagram.py +0 -0
  12. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/engines/__init__.py +0 -0
  13. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/engines/async_.py +0 -0
  14. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/engines/sync.py +0 -0
  15. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/event.py +0 -0
  16. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/event_data.py +0 -0
  17. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/events.py +0 -0
  18. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/exceptions.py +0 -0
  19. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/factory.py +0 -0
  20. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/graph.py +0 -0
  21. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/i18n.py +0 -0
  22. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/locale/en/LC_MESSAGES/statemachine.po +0 -0
  23. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/locale/pt_BR/LC_MESSAGES/statemachine.po +0 -0
  24. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/mixins.py +0 -0
  25. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/model.py +0 -0
  26. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/registry.py +0 -0
  27. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/signature.py +0 -0
  28. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/state.py +0 -0
  29. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/transition.py +0 -0
  30. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/transition_list.py +0 -0
  31. {python_statemachine-2.3.3 → python_statemachine-2.3.4}/statemachine/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-statemachine
3
- Version: 2.3.3
3
+ Version: 2.3.4
4
4
  Summary: Python Finite State Machines made easy.
5
5
  Home-page: https://github.com/fgmacedo/python-statemachine
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-statemachine"
3
- version = "2.3.3"
3
+ version = "2.3.4"
4
4
  description = "Python Finite State Machines made easy."
5
5
  authors = ["Fernando Macedo <fgmacedo@gmail.com>"]
6
6
  maintainers = [
@@ -56,12 +56,13 @@ django = { version = "^5.0.3", python = ">3.10" }
56
56
  pytest-django = { version = "^4.8.0", python = ">3.8" }
57
57
 
58
58
  [tool.poetry.group.docs.dependencies]
59
- Sphinx = "*"
60
- sphinx-rtd-theme = "2.0.0"
61
- myst-parser = "*"
62
- sphinx-gallery = "*"
63
- pillow = "*"
64
- sphinx-autobuild = "*"
59
+ Sphinx = { version = "*", python = ">3.8" }
60
+ myst-parser = { version = "*", python = ">3.8" }
61
+ sphinx-gallery = { version = "*", python = ">3.8" }
62
+ pillow = { version ="*", python = ">3.8" }
63
+ sphinx-autobuild = { version = "*", python = ">3.8" }
64
+ furo = { version = "^2024.5.6", python = ">3.8" }
65
+ sphinx-copybutton = { version = "^0.5.2", python = ">3.8" }
65
66
 
66
67
  [build-system]
67
68
  requires = ["poetry-core"]
@@ -3,6 +3,6 @@ from .statemachine import StateMachine
3
3
 
4
4
  __author__ = """Fernando Macedo"""
5
5
  __email__ = "fgmacedo@gmail.com"
6
- __version__ = "2.3.3"
6
+ __version__ = "2.3.4"
7
7
 
8
8
  __all__ = ["StateMachine", "State"]
@@ -3,6 +3,7 @@ from bisect import insort
3
3
  from collections import defaultdict
4
4
  from collections import deque
5
5
  from enum import IntEnum
6
+ from enum import IntFlag
6
7
  from enum import auto
7
8
  from inspect import isawaitable
8
9
  from inspect import iscoroutinefunction
@@ -26,10 +27,14 @@ class CallbackPriority(IntEnum):
26
27
  AFTER = 40
27
28
 
28
29
 
29
- class SpecReference(IntEnum):
30
- NAME = 1
31
- CALLABLE = 2
32
- PROPERTY = 3
30
+ class SpecReference(IntFlag):
31
+ NAME = auto()
32
+ CALLABLE = auto()
33
+ PROPERTY = auto()
34
+
35
+
36
+ SPECS_ALL = SpecReference.NAME | SpecReference.CALLABLE | SpecReference.PROPERTY
37
+ SPECS_SAFE = SpecReference.NAME
33
38
 
34
39
 
35
40
  class CallbackGroup(IntEnum):
@@ -8,8 +8,8 @@ from typing import Iterable
8
8
  from typing import Set
9
9
  from typing import Tuple
10
10
 
11
- from statemachine.callbacks import SpecReference
12
-
11
+ from .callbacks import SPECS_ALL
12
+ from .callbacks import SpecReference
13
13
  from .signature import SignatureAdapter
14
14
 
15
15
  if TYPE_CHECKING:
@@ -54,10 +54,18 @@ class Listeners:
54
54
  all_attrs = set().union(*(listener.all_attrs for listener in listeners))
55
55
  return cls(listeners, all_attrs)
56
56
 
57
- def resolve(self, specs: "CallbackSpecList", registry):
57
+ def resolve(
58
+ self,
59
+ specs: "CallbackSpecList",
60
+ registry,
61
+ allowed_references: SpecReference = SPECS_ALL,
62
+ ):
58
63
  found_convention_specs = specs.conventional_specs & self.all_attrs
59
64
  filtered_specs = [
60
- spec for spec in specs if not spec.is_convention or spec.func in found_convention_specs
65
+ spec
66
+ for spec in specs
67
+ if spec.reference in allowed_references
68
+ and (not spec.is_convention or spec.func in found_convention_specs)
61
69
  ]
62
70
  if not filtered_specs:
63
71
  return
@@ -101,7 +109,7 @@ class Listeners:
101
109
  if func is not None and func.__func__ is spec.func:
102
110
  return callable_method(spec.attr_name, func, config.resolver_id)
103
111
 
104
- return callable_method(spec.func, spec.func, None)
112
+ return callable_method(spec.attr_name, spec.func, None)
105
113
 
106
114
  def _search_name(self, name) -> Generator["Callable", None, None]:
107
115
  for config in self.items:
@@ -9,11 +9,11 @@ from typing import Any
9
9
  from typing import Dict
10
10
  from typing import List
11
11
 
12
- from statemachine.graph import iterate_states_and_transitions
13
- from statemachine.utils import run_async_from_sync
14
-
12
+ from .callbacks import SPECS_ALL
13
+ from .callbacks import SPECS_SAFE
15
14
  from .callbacks import CallbacksExecutor
16
15
  from .callbacks import CallbacksRegistry
16
+ from .callbacks import SpecReference
17
17
  from .dispatcher import Listener
18
18
  from .dispatcher import Listeners
19
19
  from .engines.async_ import AsyncEngine
@@ -24,8 +24,10 @@ from .exceptions import InvalidDefinition
24
24
  from .exceptions import InvalidStateValue
25
25
  from .exceptions import TransitionNotAllowed
26
26
  from .factory import StateMachineMetaclass
27
+ from .graph import iterate_states_and_transitions
27
28
  from .i18n import _
28
29
  from .model import Model
30
+ from .utils import run_async_from_sync
29
31
 
30
32
  if TYPE_CHECKING:
31
33
  from .state import State
@@ -177,8 +179,12 @@ class StateMachine(metaclass=StateMachineMetaclass):
177
179
  continue
178
180
  setattr(target, event.name, trigger)
179
181
 
180
- def _add_listener(self, listeners: "Listeners"):
181
- register = partial(listeners.resolve, registry=self._callbacks_registry)
182
+ def _add_listener(self, listeners: "Listeners", allowed_references: SpecReference = SPECS_ALL):
183
+ register = partial(
184
+ listeners.resolve,
185
+ registry=self._callbacks_registry,
186
+ allowed_references=allowed_references,
187
+ )
182
188
  for visited in iterate_states_and_transitions(self.states):
183
189
  register(visited._specs)
184
190
 
@@ -210,7 +216,7 @@ class StateMachine(metaclass=StateMachineMetaclass):
210
216
  def add_observer(self, *observers):
211
217
  """Add a listener."""
212
218
  warnings.warn(
213
- """The `add_observer` was rebranded to `add_listener`.""",
219
+ """Method `add_observer` has been renamed to `add_listener`.""",
214
220
  DeprecationWarning,
215
221
  stacklevel=2,
216
222
  )
@@ -228,7 +234,8 @@ class StateMachine(metaclass=StateMachineMetaclass):
228
234
  """
229
235
  self._listeners.update({o: None for o in listeners})
230
236
  return self._add_listener(
231
- Listeners.from_listeners(Listener.from_obj(o) for o in listeners)
237
+ Listeners.from_listeners(Listener.from_obj(o) for o in listeners),
238
+ allowed_references=SPECS_SAFE,
232
239
  )
233
240
 
234
241
  def _repr_html_(self):
@@ -102,12 +102,13 @@ class States:
102
102
  ... def on_enter_completed(self):
103
103
  ... print("Completed!")
104
104
 
105
- .. note::
106
- Given that you assign the response of ``States.from_enum`` to a class level
107
- variable on your :ref:`StateMachine` you're good to go, you can use any name to assign
108
- this response, on this example we used ``_`` to indicate that the name does not matter.
109
- The variable of type :ref:`States (class)` will be inspected by the metaclass and the
110
- inner :ref:`State` instances assigned to the state machine.
105
+ .. tip::
106
+ When you assign the result of ``States.from_enum`` to a class-level variable in your
107
+ :ref:`StateMachine`, you're all set. You can use any name for this variable. In this
108
+ example, we used ``_`` to show that the name doesn't matter. The metaclass will inspect
109
+ the variable of type :ref:`States (class)` and automatically assign the inner
110
+ :ref:`State` instances to the state machine.
111
+
111
112
 
112
113
  Everything else is similar, the ``Enum`` is only used to declare the :ref:`State`
113
114
  instances.