events.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. """
  2. Dirt Simple Events
  3. A Dispatcher (or a subclass of Dispatcher) stores event handlers that
  4. are 'fired' simple event objects when interesting things happen.
  5. Create a dispatcher:
  6. ```python
  7. >>> d = Dispatcher()
  8. ```
  9. Now create a handler for the event and subscribe it to the dispatcher
  10. to handle Event events. A handler is a simple function or method that
  11. accepts the event as an argument:
  12. ```python
  13. >>> def handler1(event): print(repr(event))
  14. >>> d.subscribe(Event, handler1) # doctest: +ELLIPSIS
  15. <rdflib.events.Dispatcher object at ...>
  16. ```
  17. Now dispatch a new event into the dispatcher, and see handler1 get
  18. fired:
  19. ```python
  20. >>> d.dispatch(Event(foo='bar', data='yours', used_by='the event handlers'))
  21. <rdflib.events.Event ['data', 'foo', 'used_by']>
  22. ```
  23. """
  24. from __future__ import annotations
  25. from typing import Any, Dict, Optional
  26. __all__ = ["Event", "Dispatcher"]
  27. class Event:
  28. """
  29. An event is a container for attributes. The source of an event
  30. creates this object, or a subclass, gives it any kind of data that
  31. the events handlers need to handle the event, and then calls
  32. notify(event).
  33. The target of an event registers a function to handle the event it
  34. is interested with subscribe(). When a sources calls
  35. notify(event), each subscriber to that event will be called in no
  36. particular order.
  37. """
  38. def __init__(self, **kw):
  39. self.__dict__.update(kw)
  40. def __repr__(self):
  41. attrs = sorted(self.__dict__.keys())
  42. return "<rdflib.events.Event %s>" % ([a for a in attrs],)
  43. class Dispatcher:
  44. """
  45. An object that can dispatch events to a privately managed group of
  46. subscribers.
  47. """
  48. _dispatch_map: Optional[Dict[Any, Any]] = None
  49. def set_map(self, amap: Dict[Any, Any]):
  50. self._dispatch_map = amap
  51. return self
  52. def get_map(self):
  53. return self._dispatch_map
  54. def subscribe(self, event_type, handler):
  55. """Subscribe the given handler to an event_type. Handlers
  56. are called in the order they are subscribed.
  57. """
  58. if self._dispatch_map is None:
  59. self.set_map({})
  60. # type error: error: Item "None" of "Optional[Dict[Any, Any]]" has no attribute "get"
  61. lst = self._dispatch_map.get(event_type, None) # type: ignore[union-attr]
  62. if lst is None:
  63. lst = [handler]
  64. else:
  65. lst.append(handler)
  66. # type error: Unsupported target for indexed assignment ("Optional[Dict[Any, Any]]")
  67. self._dispatch_map[event_type] = lst # type: ignore[index]
  68. return self
  69. def dispatch(self, event):
  70. """Dispatch the given event to the subscribed handlers for
  71. the event's type"""
  72. if self._dispatch_map is not None:
  73. lst = self._dispatch_map.get(type(event), None)
  74. if lst is None:
  75. raise ValueError("unknown event type: %s" % type(event))
  76. for l_ in lst:
  77. l_(event)