Skip to content

Commit

Permalink
Deprecate passing an interpreter to bind_property_statechart
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreDecan committed Aug 26, 2018
1 parent 8629405 commit 3aeba77
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 30 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ Changelog
Unreleased
----------

- (Added) Some documentation about running multiple statecharts.
- (Added) Documentation about concurrently running multiple statecharts.
- (Added) An ``unbind`` method for an ``Interpreter``.
- (Added) A ``setdefault`` function that can be used in the preamble and actions of a statechart to assign default values to variables.
- (Changed) Meta-Event *step started* has a ``time`` attribute.
- (Fixed) Internal events are processed before external ones (regression introduced in 1.3.0).
- (Fixed) Hook-errors reported by ``sismic-bdd`` CLI are a little bit more verbose (`#81 <https://github.com/AlexandreDecan/sismic/issues/81>`__).
- (Fixed) Optional transition for ``testing.transition_is_processed``, as previously promised by its documentation but not implemented.
- (Removed) Internal module ``sismic.interpreter.queue``.
- (Deprecated) Passing an interpreter to ``bind_property_statechart`` is deprecated, use ``interpreter_klass`` instead.


1.3.0 (2018-07-06)
Expand All @@ -25,7 +26,7 @@ situations when many transitions are triggered for a single source state:
- (Added) Interpreter's ``_select_transitions`` gets two new parameters, ``eventless_first`` and ``inner_first``.
Both default to ``True`` and can be used in subclasses to change the default semantics of the interpreter.

The current time of an interpreter is now clock-based driven, thanks to the `Clock` base class and its implementations.
The current time of an interpreter is now clock-based driven, thanks to the ``Clock`` base class and its implementations.

- (Added) A ``sismic.clock`` module with a ``Clock`` base class and three direct implementations,
namely ``SimulatedClock``, ``UtcClock`` and ``SynchronizedClock``. A ``SimulatedClock`` allows to manually or automatically
Expand Down
10 changes: 4 additions & 6 deletions docs/properties.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ being executed. Those meta-events are automatically send to any previously bound

To bind a property statechart to an interpreter, it suffices to provide the property statechart as a
parameter of the :py:meth:`~sismic.interpreter.Interpreter.bind_property_statechart` method of an interpreter.
This method accepts either a :py:class:`~sismic.model.Statechart` or an :py:class:`~sismic.interpreter.Interpreter`
instance.

When a property statechart is bound to an interpreter, its internal clock (the
:py:attr:`~sismic.interpreter.Interpreter.time` attribute) is automatically synchronised with the one of the
interpreter.
This method accepts a :py:class:`~sismic.model.Statechart` instance that is used to create an interpreter for
the property statechart. This method also accepts an optional ``interpreter_klass`` parameter as a callable accepting
a :py:class:`~sismic.model.Statechart` and a named parameter ``clock`` (a :py:class:`~sismic.clock.Clock`instance)
and is used to build an interpreter for the property statechart.
If a property statechart reaches a final state during its execution, then the property is considered as not
satisfied, and a :py:class:`~sismic.exceptions.PropertyStatechartError` is raised.
Expand Down
31 changes: 17 additions & 14 deletions sismic/interpreter/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,10 @@ def unbind(self, interpreter_or_callable: Union['Interpreter', Callable[[Event],
else:
self._bound.remove(interpreter_or_callable)

def bind_property_statechart(self, statechart_or_interpreter: Union[Statechart, 'Interpreter']) -> None:
def bind_property_statechart(self, statechart: Statechart, *, interpreter_klass: Callable[[Statechart, Clock], 'Interpreter']=None) -> None:
"""
Bind a property statechart to the current interpreter.
A property statechart receives meta-events from the current interpreter depending on what happens:
- *step started*: when a macro step starts. The current time of the step is available through the ``time`` attribute.
Expand All @@ -166,24 +167,26 @@ def bind_property_statechart(self, statechart_or_interpreter: Union[Statechart,
Additionally, MetaEvent instances that are sent from within the statechart are directly passed to all
bound property statecharts. This allows more advanced communication and synchronisation patterns with
the bound property statecharts.
bound property statecharts.
The internal clock of all property statecharts will be synced with the one of the current interpreter.
The internal clock of all property statecharts is synced with the one of the current interpreter.
As soon as a property statechart reaches a final state, a ``PropertyStatechartError`` will be raised,
implicitly meaning that the property expressed by the corresponding property statechart is not satisfied.
meaning that the property expressed by the corresponding property statechart is not satisfied.
Since Sismic 1.4.0, passing an interpreter as first argument is deprecated.
:param statechart_or_interpreter: A property statechart or an interpreter of a property statechart.
:param statechart: A statechart instance.
:param interpreter_klass: An optional callable that accepts a statechart as first parameter and a
named parameter clock. Default to Interpreter.
"""
# Create interpreter if required
if isinstance(statechart_or_interpreter, Statechart):
interpreter = Interpreter(statechart_or_interpreter)
if isinstance(statechart, Interpreter):
warnings.warn('Passing an interpreter to bind_property_statechart is deprecated since 1.4.0. Use interpreter_klass instead.', DeprecationWarning)
interpreter = statechart
interpreter.clock = SynchronizedClock(self)
else:
interpreter = statechart_or_interpreter

# Sync clock
interpreter.clock = SynchronizedClock(self)

# Add to the list of properties
interpreter_klass = Interpreter if interpreter_klass is None else interpreter_klass
interpreter = interpreter_klass(statechart, clock=SynchronizedClock(self))

self._bound_properties.append(interpreter)

def queue(self, event_or_name: Union[str, Event], *events_or_names: Union[str, Event]) -> 'Interpreter':
Expand Down
22 changes: 14 additions & 8 deletions tests/test_property.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,23 @@
class TestInterpreterMetaEvents:
@pytest.fixture
def property_statechart(self, microwave, mocker):
# Create mock for property
property = mocker.MagicMock(name='Interpreter', spec=microwave)
property.queue = mocker.MagicMock(return_value=None)
property.execute = mocker.MagicMock(return_value=None)
property.final = False
property.time = 0
prop_sc = mocker.MagicMock(name='Interpreter', spec=microwave)
prop_sc.queue = mocker.MagicMock(return_value=None)
prop_sc.execute = mocker.MagicMock(return_value=None)
prop_sc.final = False
prop_sc.time = 0

def prop_sc_call(statechart, clock):
return prop_sc

# Bind it
microwave.bind_property_statechart(property)
microwave.bind_property_statechart(None, interpreter_klass=prop_sc_call)

return property
return prop_sc

def test_deprecated_interpreter(self, microwave):
with pytest.warns(DeprecationWarning):
microwave.bind_property_statechart(microwave)

def test_synchronised_time(self, microwave, property_statechart):
assert microwave.time == property_statechart.time
Expand Down

0 comments on commit 3aeba77

Please sign in to comment.