Skip to content

@slot decorator

Decorator which enables hooks functionality on a specific class method.

Decorated methods get additional nested methods:

  • :obj:onetl.hooks.slot.Slot.bind
  • :obj:onetl.hooks.slot.Slot.suspend_hooks
  • :obj:onetl.hooks.slot.Slot.resume_hooks
  • :obj:onetl.hooks.slot.Slot.skip_hooks

.. note::

Supported method types are:

* Regular methods
* ``@classmethod``
* ``@staticmethod``

It is not allowed to use this decorator over ``_private`` and ``__protected`` methods and ``@property``.
But is allowed to use on ``__dunder__`` methods, like ``__init__``.

.. versionadded:: 0.7.0

Examples:

.. code:: python

from onetl.hooks import support_hooks, slot, hook


@support_hooks
class MyClass:
    @slot
    def my_method(self, arg): ...

    @slot  # decorator should be on top of all other decorators
    @classmethod
    def class_method(cls): ...

    @slot  # decorator should be on top of all other decorators
    @staticmethod
    def static_method(arg): ...


@MyClass.my_method.bind
@hook
def callback1(self, arg): ...


@MyClass.class_method.bind
@hook
def callback2(cls): ...


@MyClass.static_method.bind
@hook
def callback3(arg): ...


obj = MyClass()
obj.my_method(1)  # will execute callback1(obj, 1)
MyClass.class_method(2)  # will execute callback2(MyClass, 2)
MyClass.static_method(3)  # will execute callback3(3)

Bases: Protocol

Protocol which is implemented by a method after applying :obj:~slot decorator.

.. versionadded:: 0.7.0

__hooks__ property

Collection of hooks bound to the slot

resume_hooks()

Resume all hooks bound to the slot.

.. note::

If hook is disabled by :obj:`onetl.hooks.hook.Hook.disable`, it will stay disabled.
You should call :obj:`onetl.hooks.hook.Hook.enable` explicitly.

Examples:

.. code:: python

from onetl.hooks.hook import hook, support_hooks, slot


@support_hooks
class MyClass:
    @slot
    def my_method(self, arg): ...


@MyClass.my_method.bind
@hook
def callback1(self, arg): ...


obj = MyClass()
obj.my_method(1)  # will call callback1(obj, 1)

MyClass.my_method.suspend_hooks()
obj.my_method(1)  # will NOT call callback1

MyClass.my_method.resume_hooks()
obj.my_method(2)  # will call callback1(obj, 2)

skip_hooks()

Context manager which temporary stops all the hooks bound to the slot.

.. note::

If hooks were stopped by :obj:`~suspend_hooks`, they will not be resumed
after exiting the context/decorated function.
You should call :obj:`~resume_hooks` explicitly.

Examples:

.. tabs::

.. code-tab:: py Context manager syntax

    from onetl.hooks.hook import hook, support_hooks, slot


    @support_hooks
    class MyClass:
        @slot
        def my_method(self, arg):
            ...


    @MyClass.my_method.bind
    @hook
    def callback1(self, arg):
        ...

    obj = MyClass()
    obj.my_method(1)  # will call callback1(obj, 1)

    with MyClass.my_method.skip_hooks():
        obj.my_method(1)  # will NOT call callback1

    obj.my_method(2)  # will call callback1(obj, 2)

.. code-tab:: py Decorator syntax

    from onetl.hooks.hook import hook, support_hooks, slot


    @support_hooks
    class MyClass:
        @slot
        def my_method(self, arg):
            ...


    @MyClass.my_method.bind
    @hook
    def callback1(self, arg):
        ...

    @MyClass.my_method.skip_hooks()
    def method_without_hooks(obj, arg):
        obj.my_method(arg)


    obj = MyClass()
    obj.my_method(1)  # will call callback1(obj, 1)

    method_without_hooks(obj, 1)  # will NOT call callback1

    obj.my_method(2)  # will call callback1(obj, 2)

suspend_hooks()

Stop all the hooks bound to the slot.

Examples:

.. code:: python

from onetl.hooks.hook import hook, support_hooks, slot


@support_hooks
class MyClass:
    @slot
    def my_method(self, arg): ...


@MyClass.my_method.bind
@hook
def callback1(self, arg): ...


obj = MyClass()
obj.my_method(1)  # will call callback1(obj, 1)

MyClass.my_method.suspend_hooks()
obj.my_method(1)  # will NOT call callback1