# Path: rep0st/framework/decorator.py
# class DecoratorProcessor(ABC):
# 
#   @abstractmethod
#   def process(self, bindings: List[Any]) -> None:
#     pass
# 
#   def methods_by_decorated_name(
#       self, bindings: List[Any],
#       search_name: str) -> Iterator[Tuple[Type, T, Callable[[Any], Any]]]:
#     for binding in bindings:
#       interface = binding
#       for name, fun in inspect.getmembers(interface):
#         data = getattr(fun, '__' + search_name + '__', None)
#         if data is not None:
#           yield (interface, data, fun)
# 
#   @staticmethod
#   def wrap_function(instance: Any, fun: Callable,
#                     injector: Injector) -> Callable:
#     fun = types.MethodType(fun, instance)
# 
#     @functools.wraps(fun)
#     def wrapper(*args: Any, **kwargs: Any) -> Any:
#       return injector.call_with_injection(
#           callable=fun, args=args, kwargs=kwargs)
# 
#     return wrapper  # type: ignore


import logging
import signal
import types
from collections import namedtuple
from typing import Any, Callable, Dict, Iterator, List, Tuple, Type
from injector import Binder, Injector, Module, inject, multiprovider, singleton
from rep0st.framework.decorator import DecoratorProcessor
    signal_handler.register_handler(signal.SIGQUIT, self.handle_shutdown)
    self.injector = injector

  def process(self, bindings: List[Any]) -> None:
    found: Iterator[Tuple[Type, _OnShutdownConfiguration,
                          Callable[[Any],
                                   Any]]] = self.methods_by_decorated_name(
                                       bindings, 'on_shutdown')
    for interface, on_shutdown_configuration, fun in found:
      full_fun_name = "{}.{}.{}".format(interface.__module__,
                                        interface.__class__.__name__,
                                        fun.__name__)
      log.info("Discovered method %s for on_shutdown", full_fun_name)
      self.methods.append(types.MethodType(fun, self.injector.get(interface)))

  def handle_shutdown(self):
    log.debug("Executing methods marked @on_shutdown()")
    for method in self.methods:
      method()


class SignalHandlerModule(Module):

  def configure(self, binder: Binder):
    binder.bind(SignalHandler)
    binder.bind(OnShutdownProcessor)

  @multiprovider
  def provide_decorator_processor(
      self,

# Path: rep0st/framework/decorator.py
# class DecoratorProcessor(ABC):
# 
#   @abstractmethod
#   def process(self, bindings: List[Any]) -> None:
#     pass
# 
#   def methods_by_decorated_name(
#       self, bindings: List[Any],
#       search_name: str) -> Iterator[Tuple[Type, T, Callable[[Any], Any]]]:
#     for binding in bindings:
#       interface = binding
#       for name, fun in inspect.getmembers(interface):
#         data = getattr(fun, '__' + search_name + '__', None)
#         if data is not None:
#           yield (interface, data, fun)
# 
#   @staticmethod
#   def wrap_function(instance: Any, fun: Callable,
#                     injector: Injector) -> Callable:
#     fun = types.MethodType(fun, instance)
# 
#     @functools.wraps(fun)
#     def wrapper(*args: Any, **kwargs: Any) -> Any:
#       return injector.call_with_injection(
#           callable=fun, args=args, kwargs=kwargs)
# 
#     return wrapper  # type: ignore


# Path: rep0st/framework/signal_handler.py
import logging
import signal
import types
from collections import namedtuple
from typing import Any, Callable, Dict, Iterator, List, Tuple, Type
from injector import Binder, Injector, Module, inject, multiprovider, singleton
from rep0st.framework.decorator import DecoratorProcessor

    signal_handler.register_handler(signal.SIGQUIT, self.handle_shutdown)
    self.injector = injector

  def process(self, bindings: List[Any]) -> None:
    found: Iterator[Tuple[Type, _OnShutdownConfiguration,
                          Callable[[Any],
                                   Any]]] = self.methods_by_decorated_name(
                                       bindings, 'on_shutdown')
    for interface, on_shutdown_configuration, fun in found:
      full_fun_name = "{}.{}.{}".format(interface.__module__,
                                        interface.__class__.__name__,
                                        fun.__name__)
      log.info("Discovered method %s for on_shutdown", full_fun_name)
      self.methods.append(types.MethodType(fun, self.injector.get(interface)))

  def handle_shutdown(self):
    log.debug("Executing methods marked @on_shutdown()")
    for method in self.methods:
      method()


class SignalHandlerModule(Module):

  def configure(self, binder: Binder):
    binder.bind(SignalHandler)
    binder.bind(OnShutdownProcessor)

  @multiprovider
  def provide_decorator_processor(
      self,

      on_shutdown_processor: OnShutdownProcessor) -> List[DecoratorProcessor]: