stouputils.typing.extension_points module#
Decorators marking how a class is meant to be extended.
inheritable() flags a class designed to be subclassed, overridable() a working default a subclass may replace,
and hook() a method called at a fixed point of a flow, whose default does nothing so a subclass can act there.
They only set a boolean attribute and never wrap what they decorate, so they cost nothing at call time.
@inheritable
class Trainer:
def fit(self) -> None:
self.before_epoch()
self.train_epoch()
@hook
def before_epoch(self) -> None: ...
@overridable
def train_epoch(self) -> None:
...
- INHERITABLE_ATTRIBUTE: str = '__is_inheritable__'[source]#
Attribute set to True on a class decorated with
inheritable().
- OVERRIDABLE_ATTRIBUTE: str = '__is_overridable__'[source]#
Attribute set to True on the function behind a member decorated with
overridable().
- HOOK_ATTRIBUTE: str = '__is_hook__'[source]#
Attribute set to True on the function behind a member decorated with
hook().
- ClassMember = ClassMember[source]#
A type alias for anything defined in a class body that can be decorated
- inheritable(cls: T) T[source]#
Mark a class as meant to be subclassed, sets
__is_inheritable__to True.Nothing is enforced at runtime: it only tells the reader that subclassing is part of the class contract.
>>> @inheritable ... class Base: ... pass >>> Base.__is_inheritable__ True
- overridable(member: T) T[source]#
Mark a member as a default implementation that subclasses may replace, sets
__is_overridable__to True.Unlike
hook(), the default already does the job, and a subclass swaps it for another way of doing it. Nothing is enforced at runtime and the member is not wrapped. Stack it above@property,@classmethodor@staticmethod: the flag lands on the underlying function.>>> class Base: ... @overridable ... def run(self) -> None: ... ... ... @overridable ... @property ... def name(self) -> str: return "base" ... ... @overridable ... @classmethod ... def create(cls) -> None: ... ... >>> Base.run.__is_overridable__, Base.name.fget.__is_overridable__, Base.create.__is_overridable__ (True, True, True)
- hook(member: T) T[source]#
Mark a method as a hook, called at a fixed point of a flow, sets
__is_hook__to True.The caller may be the class itself, or code driving it from outside, such as a trainer calling a model. Unlike
overridable(), the default does nothing, or hands its input back unchanged: a subclass adds behaviour at that point. Nothing is enforced at runtime and the member is not wrapped.>>> class Runner: ... @hook ... def before_run(self) -> None: ... >>> Runner.before_run.__is_hook__ True
- set_member_flag(
- member: ClassMember,
- attribute: str,
Set
attributeto True on the function behind a class member.- Parameters:
member – Function, property (its getter is flagged), classmethod or staticmethod (their
__func__is flagged)