class at_time:
    actions = {}
 
    def __init__(self, time_of_day):
        self.time_of_day = time_of_day
 
    def __call__(self, func):
        self.actions.setdefault(func.__qualname__, {})[self.time_of_day] = func
        return self
 
    def __set_name__(self, owner, name):
        self.name = name
 
    def __get__(self, obj, objtype):
        def wrapper(time_of_day):
            for cls in objtype.__mro__:
                if func := self.actions.get(
                    '.'.join((cls.__qualname__, self.name)), {}).get(time_of_day):
                    return func(obj)
            raise ValueError(f'No {self.name} found in the {time_of_day} time')
        return wrapper
 
class PersonalChef():
    @at_time('morning')
    def cook(self):
        print("Cooking breakfast")
 
    @at_time('evening')
    def cook(self):
        print("Cooking dinner")
 
class PersonalChefUK(PersonalChef):
    @at_time('evening')
    def cook(self):
        print("Cooking supper")
 
PersonalChef().cook('morning')
PersonalChef().cook('evening')
PersonalChefUK().cook('morning')
PersonalChefUK().cook('evening')
				Y2xhc3MgYXRfdGltZToKICAgIGFjdGlvbnMgPSB7fQoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0aW1lX29mX2RheSk6CiAgICAgICAgc2VsZi50aW1lX29mX2RheSA9IHRpbWVfb2ZfZGF5CgogICAgZGVmIF9fY2FsbF9fKHNlbGYsIGZ1bmMpOgogICAgICAgIHNlbGYuYWN0aW9ucy5zZXRkZWZhdWx0KGZ1bmMuX19xdWFsbmFtZV9fLCB7fSlbc2VsZi50aW1lX29mX2RheV0gPSBmdW5jCiAgICAgICAgcmV0dXJuIHNlbGYKCiAgICBkZWYgX19zZXRfbmFtZV9fKHNlbGYsIG93bmVyLCBuYW1lKToKICAgICAgICBzZWxmLm5hbWUgPSBuYW1lCgogICAgZGVmIF9fZ2V0X18oc2VsZiwgb2JqLCBvYmp0eXBlKToKICAgICAgICBkZWYgd3JhcHBlcih0aW1lX29mX2RheSk6CiAgICAgICAgICAgIGZvciBjbHMgaW4gb2JqdHlwZS5fX21yb19fOgogICAgICAgICAgICAgICAgaWYgZnVuYyA6PSBzZWxmLmFjdGlvbnMuZ2V0KAogICAgICAgICAgICAgICAgICAgICcuJy5qb2luKChjbHMuX19xdWFsbmFtZV9fLCBzZWxmLm5hbWUpKSwge30pLmdldCh0aW1lX29mX2RheSk6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmMob2JqKQogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKGYnTm8ge3NlbGYubmFtZX0gZm91bmQgaW4gdGhlIHt0aW1lX29mX2RheX0gdGltZScpCiAgICAgICAgcmV0dXJuIHdyYXBwZXIKCmNsYXNzIFBlcnNvbmFsQ2hlZigpOgogICAgQGF0X3RpbWUoJ21vcm5pbmcnKQogICAgZGVmIGNvb2soc2VsZik6CiAgICAgICAgcHJpbnQoIkNvb2tpbmcgYnJlYWtmYXN0IikKCiAgICBAYXRfdGltZSgnZXZlbmluZycpCiAgICBkZWYgY29vayhzZWxmKToKICAgICAgICBwcmludCgiQ29va2luZyBkaW5uZXIiKQoKY2xhc3MgUGVyc29uYWxDaGVmVUsoUGVyc29uYWxDaGVmKToKICAgIEBhdF90aW1lKCdldmVuaW5nJykKICAgIGRlZiBjb29rKHNlbGYpOgogICAgICAgIHByaW50KCJDb29raW5nIHN1cHBlciIpCgpQZXJzb25hbENoZWYoKS5jb29rKCdtb3JuaW5nJykKUGVyc29uYWxDaGVmKCkuY29vaygnZXZlbmluZycpClBlcnNvbmFsQ2hlZlVLKCkuY29vaygnbW9ybmluZycpClBlcnNvbmFsQ2hlZlVLKCkuY29vaygnZXZlbmluZycp