from contextlib import suppress from .event_handler import EventHandler class EventHandlerFactoryBase: def build(self, handler_stub, *, keys=None, event_handler_type=EventHandler): builder = EventHandlerBuilder(handler_stub, keys, event_handler_type) connector = self._build_connector() event_handler = builder.build(connector) handler_stub.connector = connector with suppress(AttributeError): handler_stub.start() event_handler.start() return event_handler def _build_connector(self): raise NotImplementedError() 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 def build(self, connector): event_handler = self._event_handler_type(connector) connector.subscribe(*self._try_get_keys(event_handler)) event_handler.handle_event = self._analyzer.handle_event with suppress(AttributeError): event_handler.cleanup = self._analyzer.cleanup return event_handler def _try_get_keys(self, event_handler): try: return self._analyzer.keys except ValueError: with suppress(AttributeError): return event_handler.keys raise class HandlerStubAnalyzer: def __init__(self, event_handler, supplied_keys): self._event_handler = event_handler self._supplied_keys = supplied_keys @property def keys(self): if self._supplied_keys is None: try: return self._event_handler.keys except AttributeError: raise ValueError('No keys supplied!') return self._supplied_keys @property def handle_event(self): try: return self._event_handler.handle_event except AttributeError: if callable(self._event_handler): return self._event_handler raise ValueError('Object must implement handle_event or be a callable!') @property def cleanup(self): return self._event_handler.cleanup