code: def register_hook(self, hook, event_type=None):
          
          if event_type is not None:
              assert type(event_type) is int, "register hooks with int values"
              return self.hooks[event_type].append(hook)
  
          for event_type in EventType._fields:
              func = getattr(hook, event_type, None)
              if callable(func):
                  event_value = getattr(EventType, event_type)
                  self.register_hook(func, event_value)
docs: If ``event_type`` is provided, then ``hook`` will be called whenever
          that event is fired.
  
          If no ``event_type`` is specifid, but ``hook`` implements any methods
          with names matching an event hook, then those will be registered with
          their corresponding events. This allows for more stateful, class-based
          event handlers.