From 25cf6722319cb47b4bf4e44566b284b603a89668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Fri, 30 Aug 2019 14:44:57 +0200 Subject: [PATCH] Enable handlers to specify EventHandler type --- tfw/internals/event_handling/event_handler.py | 6 ++++- .../event_handler_factory_base.py | 15 ++++++++++-- .../event_handling/test_event_handler.py | 24 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/tfw/internals/event_handling/event_handler.py b/tfw/internals/event_handling/event_handler.py index d20cd05..a503649 100644 --- a/tfw/internals/event_handling/event_handler.py +++ b/tfw/internals/event_handling/event_handler.py @@ -1,5 +1,9 @@ -class EventHandler: +from .type_id_registry import TypeIdRegistryMixin + + +class EventHandler(TypeIdRegistryMixin): _instances = set() + _type_id_registry = {} def __init__(self, connector): type(self)._instances.add(self) diff --git a/tfw/internals/event_handling/event_handler_factory_base.py b/tfw/internals/event_handling/event_handler_factory_base.py index b62d9f1..dd76329 100644 --- a/tfw/internals/event_handling/event_handler_factory_base.py +++ b/tfw/internals/event_handling/event_handler_factory_base.py @@ -4,7 +4,7 @@ from .event_handler import EventHandler class EventHandlerFactoryBase: - def build(self, handler_stub, *, keys=None, event_handler_type=EventHandler): + def build(self, handler_stub, *, keys=None, event_handler_type=None): builder = EventHandlerBuilder(handler_stub, keys, event_handler_type) connector = self._build_connector() event_handler = builder.build(connector) @@ -21,7 +21,13 @@ class EventHandlerFactoryBase: class EventHandlerBuilder: def __init__(self, event_handler, supplied_keys, event_handler_type): self._analyzer = HandlerStubAnalyzer(event_handler, supplied_keys) - self._event_handler_type = event_handler_type + self._event_handler_type = self._determine_type(event_handler_type) + + def _determine_type(self, provided_type): + type_ = provided_type or self._analyzer.event_handler_type or EventHandler + if not issubclass(type_, EventHandler): + raise ValueError("No type supplied!") + return type_ def build(self, connector): event_handler = self._event_handler_type(connector) @@ -66,3 +72,8 @@ class HandlerStubAnalyzer: @property def cleanup(self): return self._event_handler.cleanup + + @property + def event_handler_type(self): + with suppress(AttributeError): + return EventHandler.get_type(self._event_handler.type_id) diff --git a/tfw/internals/event_handling/test_event_handler.py b/tfw/internals/event_handling/test_event_handler.py index 6398627..5082ca8 100644 --- a/tfw/internals/event_handling/test_event_handler.py +++ b/tfw/internals/event_handling/test_event_handler.py @@ -6,6 +6,8 @@ import pytest from .event_handler_factory_base import EventHandlerFactoryBase from .event_handler import EventHandler +from .control_event_handler import ControlEventHandler +from .fsm_aware_event_handler import FSMAwareEventHandler class MockEventHandlerFactory(EventHandlerFactoryBase): @@ -130,6 +132,28 @@ def test_build_from_simple_object(test_keys, test_msg): assert msg == test_msg +def test_build_type(): + class SomeControlHandler: + keys = ['cica'] + type_id = 'ControlEventHandler' + # pylint: disable=no-self-use + def handle_event(self, *_): + pass + + eh = MockEventHandlerFactory().build(SomeControlHandler()) + assert isinstance(eh, ControlEventHandler) + + eh = MockEventHandlerFactory().build(SomeControlHandler(), event_handler_type=EventHandler) + assert type(eh) == EventHandler # pylint: disable=unidiomatic-typecheck + + SomeControlHandler.type_id = 'FSMAwareEventHandler' + eh = MockEventHandlerFactory().build(SomeControlHandler()) + assert isinstance(eh, FSMAwareEventHandler) + + eh = MockEventHandlerFactory().build(lambda *_: None, keys=['cica']) + assert isinstance(eh, EventHandler) + + def test_build_from_callable(test_keys, test_msg): mock_eh = MockCallable()