refactor: annotation with __future__.annotations
Adds `from __future__ import annotations` to the top of every module,
right below the module's docstring. Replaces any usages of t.List,
t.Dict, t.Set, t.Tuple, and t.Type with their built-in equivalents:
list, dict, set, tuple, and type. Ensures that make test still passes
under Python 3.7, 3.8 and 3.9.
2023-01-17 18:57:23 +00:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2022-02-07 17:11:43 +00:00
|
|
|
# The Tutor plugin system is licensed under the terms of the Apache 2.0 license.
|
|
|
|
__license__ = "Apache 2.0"
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import typing as t
|
2023-04-28 15:11:14 +00:00
|
|
|
from weakref import WeakSet
|
2022-02-07 17:11:43 +00:00
|
|
|
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
from typing_extensions import ParamSpec
|
|
|
|
|
2023-04-28 15:11:14 +00:00
|
|
|
|
2022-11-08 15:09:16 +00:00
|
|
|
from . import priorities
|
2022-02-07 17:11:43 +00:00
|
|
|
from .contexts import Contextualized
|
|
|
|
|
2023-01-06 18:02:17 +00:00
|
|
|
#: Action generic signature.
|
|
|
|
T = ParamSpec("T")
|
|
|
|
|
2023-02-06 21:10:33 +00:00
|
|
|
ActionCallbackFunc = t.Callable[T, None]
|
2022-02-07 17:11:43 +00:00
|
|
|
|
|
|
|
|
2023-01-06 18:02:17 +00:00
|
|
|
class ActionCallback(Contextualized, t.Generic[T]):
|
2022-02-07 17:11:43 +00:00
|
|
|
def __init__(
|
|
|
|
self,
|
2023-02-06 21:10:33 +00:00
|
|
|
func: ActionCallbackFunc[T],
|
2022-02-07 17:11:43 +00:00
|
|
|
priority: t.Optional[int] = None,
|
|
|
|
):
|
|
|
|
super().__init__()
|
|
|
|
self.func = func
|
2022-11-08 15:09:16 +00:00
|
|
|
self.priority = priority or priorities.DEFAULT
|
2022-02-07 17:11:43 +00:00
|
|
|
|
|
|
|
def do(
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
self,
|
2023-01-06 18:02:17 +00:00
|
|
|
*args: T.args,
|
|
|
|
**kwargs: T.kwargs,
|
2022-02-07 17:11:43 +00:00
|
|
|
) -> None:
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
self.func(*args, **kwargs)
|
2022-02-07 17:11:43 +00:00
|
|
|
|
|
|
|
|
2023-01-06 18:02:17 +00:00
|
|
|
class Action(t.Generic[T]):
|
2022-02-07 17:11:43 +00:00
|
|
|
"""
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
Action hooks have callbacks that are triggered independently from one another.
|
|
|
|
|
|
|
|
Several actions are defined across the codebase. Each action is given a unique name.
|
|
|
|
To each action are associated zero or more callbacks, sorted by priority.
|
|
|
|
|
|
|
|
This is the typical action lifecycle:
|
|
|
|
|
2023-04-28 15:11:14 +00:00
|
|
|
1. Create an action with ``Action()``.
|
|
|
|
2. Add callbacks with :py:meth:`add`.
|
|
|
|
3. Call the action callbacks with :py:meth:`do`.
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
|
2023-04-28 15:11:14 +00:00
|
|
|
The ``T`` type parameter of the Action class corresponds to the expected signature of
|
2023-01-06 18:02:17 +00:00
|
|
|
the action callbacks. For instance, ``Action[[str, int]]`` means that the action
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
callbacks are expected to take two arguments: one string and one integer.
|
|
|
|
|
2023-04-28 15:11:14 +00:00
|
|
|
This strong typing makes it easier for plugin developers to quickly check whether
|
|
|
|
they are adding and calling action callbacks correctly.
|
2022-02-07 17:11:43 +00:00
|
|
|
"""
|
|
|
|
|
2023-04-28 15:11:14 +00:00
|
|
|
# Keep a weak reference to all created filters. This allows us to clear them when
|
|
|
|
# necessary.
|
|
|
|
INSTANCES: WeakSet[Action[t.Any]] = WeakSet()
|
2022-02-07 17:11:43 +00:00
|
|
|
|
2023-04-28 15:11:14 +00:00
|
|
|
def __init__(self) -> None:
|
2023-01-06 18:02:17 +00:00
|
|
|
self.callbacks: list[ActionCallback[T]] = []
|
2023-04-28 15:11:14 +00:00
|
|
|
self.INSTANCES.add(self)
|
2022-02-07 17:11:43 +00:00
|
|
|
|
|
|
|
def add(
|
|
|
|
self, priority: t.Optional[int] = None
|
2023-02-06 21:10:33 +00:00
|
|
|
) -> t.Callable[[ActionCallbackFunc[T]], ActionCallbackFunc[T]]:
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
"""
|
2023-01-06 18:02:17 +00:00
|
|
|
Decorator to add a callback to an action.
|
|
|
|
|
|
|
|
:param priority: optional order in which the action callbacks are performed. Higher
|
|
|
|
values mean that they will be performed later. The default value is
|
|
|
|
``priorities.DEFAULT`` (10). Actions that should be performed last should have a
|
|
|
|
priority of 100.
|
|
|
|
|
|
|
|
Usage::
|
|
|
|
|
|
|
|
@my_action.add("my-action")
|
|
|
|
def do_stuff(my_arg):
|
|
|
|
...
|
|
|
|
|
|
|
|
The ``do_stuff`` callback function will be called on ``my_action.do(some_arg)``.
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
|
2023-01-06 18:02:17 +00:00
|
|
|
The signature of each callback action function must match the signature of the
|
|
|
|
corresponding :py:meth:`do` method. Callback action functions are not supposed
|
|
|
|
to return any value. Returned values will be ignored.
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
"""
|
|
|
|
|
2023-02-06 21:10:33 +00:00
|
|
|
def inner(func: ActionCallbackFunc[T]) -> ActionCallbackFunc[T]:
|
2022-02-07 17:11:43 +00:00
|
|
|
callback = ActionCallback(func, priority=priority)
|
2022-11-08 15:09:16 +00:00
|
|
|
priorities.insert_callback(callback, self.callbacks)
|
2022-02-07 17:11:43 +00:00
|
|
|
return func
|
|
|
|
|
|
|
|
return inner
|
|
|
|
|
|
|
|
def do(
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
self,
|
2023-01-06 18:02:17 +00:00
|
|
|
*args: T.args,
|
|
|
|
**kwargs: T.kwargs,
|
2022-02-07 17:11:43 +00:00
|
|
|
) -> None:
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
"""
|
2023-01-06 18:02:17 +00:00
|
|
|
Run the action callbacks in sequence.
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
|
2023-01-06 18:02:17 +00:00
|
|
|
:param name: name of the action for which callbacks will be run.
|
|
|
|
|
|
|
|
Extra ``*args`` and ``*kwargs`` arguments will be passed as-is to
|
|
|
|
callback functions.
|
|
|
|
|
|
|
|
Callbacks are executed in order of priority, then FIFO. There is no error
|
|
|
|
management here: a single exception will cause all following callbacks
|
|
|
|
not to be run and the exception will be bubbled up.
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
"""
|
|
|
|
self.do_from_context(None, *args, **kwargs)
|
|
|
|
|
|
|
|
def do_from_context(
|
|
|
|
self,
|
|
|
|
context: t.Optional[str],
|
2023-01-06 18:02:17 +00:00
|
|
|
*args: T.args,
|
|
|
|
**kwargs: T.kwargs,
|
2022-02-07 17:11:43 +00:00
|
|
|
) -> None:
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
"""
|
2023-01-06 18:02:17 +00:00
|
|
|
Same as :py:meth:`do` but only run the callbacks from a given context.
|
|
|
|
|
|
|
|
:param name: name of the action for which callbacks will be run.
|
|
|
|
:param context: limit the set of callback actions to those that
|
|
|
|
were declared within a certain context (see
|
|
|
|
:py:func:`tutor.core.hooks.contexts.enter`).
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
"""
|
2022-02-07 17:11:43 +00:00
|
|
|
for callback in self.callbacks:
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
if callback.is_in_context(context):
|
|
|
|
try:
|
|
|
|
callback.do(
|
|
|
|
*args,
|
|
|
|
**kwargs,
|
|
|
|
)
|
|
|
|
except:
|
|
|
|
sys.stderr.write(
|
2023-04-28 15:11:14 +00:00
|
|
|
f"Error applying action: func={callback.func} contexts={callback.contexts}'\n"
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
)
|
|
|
|
raise
|
2022-02-07 17:11:43 +00:00
|
|
|
|
|
|
|
def clear(self, context: t.Optional[str] = None) -> None:
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
"""
|
|
|
|
Clear all or part of the callbacks associated to an action
|
|
|
|
|
2023-01-06 18:02:17 +00:00
|
|
|
:param name: name of the action callbacks to remove.
|
|
|
|
:param context: when defined, will clear only the actions that were
|
|
|
|
created within that context.
|
|
|
|
|
|
|
|
Actions will be removed from the list of callbacks and will no longer be
|
|
|
|
run in :py:meth:`do` calls.
|
|
|
|
|
|
|
|
This function should almost certainly never be called by plugins. It is
|
|
|
|
mostly useful to disable some plugins at runtime or in unit tests.
|
feat: strongly typed hooks
Now that the mypy bugs have been resolved, we are able to define more precisely
and cleanly the types of Actions and Filters.
Moreover, can now strongly type named actions and hooks (in consts.py). With
such a strong typing, we get early alerts of hooks called with incorrect
arguments, which is nothing short of awesome :)
This change breaks the hooks API by removing the `context=...` argument. The
reason for that is that we cannot insert arbitrary arguments between `P.args,
P.kwargs`: https://peps.python.org/pep-0612/#the-components-of-a-paramspec
> A function declared as def inner(a: A, b: B, *args: P.args, **kwargs:
> P.kwargs) -> R has type Callable[Concatenate[A, B, P], R]. Placing
> keyword-only parameters between the *args and **kwargs is forbidden.
Getting the documentation to build in nitpicky mode is quite difficult... We
need to add `nitpick_ignore` to the docs conf.py, otherwise sphinx complains
about many missing class references. This, despite upgrading almost all doc
requirements (except docutils).
2022-10-06 10:05:01 +00:00
|
|
|
"""
|
2022-02-07 17:11:43 +00:00
|
|
|
self.callbacks = [
|
|
|
|
callback
|
|
|
|
for callback in self.callbacks
|
|
|
|
if not callback.is_in_context(context)
|
|
|
|
]
|
|
|
|
|
2023-04-28 15:11:14 +00:00
|
|
|
@classmethod
|
|
|
|
def clear_all(cls, context: t.Optional[str] = None) -> None:
|
|
|
|
"""
|
|
|
|
Clear any previously defined action with the given context.
|
|
|
|
"""
|
|
|
|
for action in cls.INSTANCES:
|
|
|
|
action.clear(context)
|