from abc import abstractmethod, ABCMeta


class Hook(ABCMeta):
    @abstractmethod
    def func1(self, runner):
        pass

    @abstractmethod
    def func2(self, runner):
        pass

    @abstractmethod
    def func3(self, runner):
        pass


class MyHook(Hook):
    def func1(self, runner):
        pass

    def func2(self, runner):
        pass

    def func3(self, runner):
        pass


class Runner():
    def __init__(self):
        self.hook = None

    def register_hook(self, hook):
        self.hook = hook

    def runner_main(self):
        pass

    def call_hook(self, hook_name):
        getattr(self.hook, hook_name)(self)

    def run(self):
        if self.hook:
            self.call_hook('func1')
        self.runner_main()
        if self.hook:
            self.call_hook('func2')
            self.call_hook('func3')
