Skip to content

Commit

Permalink
Improves annotations of PluginManager and contributed XPath functions
Browse files Browse the repository at this point in the history
  • Loading branch information
funkyfuture committed Sep 23, 2024
1 parent e2f106c commit 98f06e7
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 17 deletions.
34 changes: 24 additions & 10 deletions _delb/plugins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
from __future__ import annotations

import sys
from collections.abc import Callable, Iterable
from typing import TYPE_CHECKING, Any
from collections.abc import Iterable
from typing import TYPE_CHECKING, overload, Any

if sys.version_info < (3, 10): # DROPWITH Python3.9
from importlib_metadata import entry_points
Expand All @@ -27,8 +27,14 @@

if TYPE_CHECKING:
from types import SimpleNamespace

from _delb.typing import Loader, LoaderConstraint
from delb import Document
from _delb.typing import (
GenericDecorated,
Loader,
LoaderConstraint,
SecondOrderDecorator,
XPathFunction,
)


class DocumentMixinBase:
Expand Down Expand Up @@ -93,10 +99,10 @@ def _init_config(cls, config: SimpleNamespace, kwargs: dict[str, Any]):

class PluginManager:
def __init__(self):
self.document_mixins: list[type] = []
self.document_subclasses: list[type] = []
self.document_mixins: list[type[DocumentMixinBase]] = []
self.document_subclasses: list[type[Document]] = []
self.loaders: list[Loader] = []
self.xpath_functions: dict[str, Callable] = {}
self.xpath_functions: dict[str, XPathFunction] = {}

@staticmethod
def load_plugins():
Expand All @@ -108,7 +114,7 @@ def load_plugins():

def register_loader(
self, before: LoaderConstraint = None, after: LoaderConstraint = None
) -> Callable:
) -> SecondOrderDecorator:
"""
Registers a document loader.
Expand Down Expand Up @@ -200,7 +206,15 @@ def registrar(loader: Loader) -> Loader:

return registrar

def register_xpath_function(self, arg: Callable | str) -> Callable:
@overload
def register_xpath_function(self, arg: str) -> SecondOrderDecorator: ...

@overload
def register_xpath_function(self, arg: GenericDecorated) -> GenericDecorated: ...

def register_xpath_function(
self, arg: str | GenericDecorated
) -> SecondOrderDecorator | GenericDecorated:
"""
Custom XPath functions can be defined as shown in the following example. The
first argument to a function is always an instance of
Expand Down Expand Up @@ -231,7 +245,7 @@ def lowercase(_, string: str) -> str:
"""
if isinstance(arg, str):

def wrapper(func):
def wrapper(func: XPathFunction) -> XPathFunction:
self.xpath_functions[arg] = func
return func

Expand Down
10 changes: 8 additions & 2 deletions _delb/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@

import sys

from typing import TYPE_CHECKING, Any, Mapping, Union # noqa: UNT001
from typing import TYPE_CHECKING, Any, Callable, Mapping, Union, TypeVar # noqa: UNT001


if TYPE_CHECKING:
from collections.abc import Callable, Iterable
from collections.abc import Iterable
from types import SimpleNamespace

if sys.version_info < (3, 10): # DROPWITH Python 3.9
Expand All @@ -33,6 +33,7 @@
from lxml import etree

from _delb.nodes import NodeBase, _TagDefinition
from _delb.xpath.ast import EvaluationContext


if sys.version_info < (3, 11): # DROPWITH Python 3.10
Expand All @@ -41,6 +42,9 @@
from typing import Self


GenericDecorated = TypeVar("GenericDecorated", bound=Callable[..., Any])
SecondOrderDecorator: TypeAlias = "Callable[[GenericDecorated], GenericDecorated]"

Filter: TypeAlias = "Callable[[NodeBase], bool]"
NamespaceDeclarations: TypeAlias = Mapping[str | None, str]
NodeSource: TypeAlias = Union[str, "NodeBase", "_TagDefinition"]
Expand All @@ -49,6 +53,8 @@
Loader: TypeAlias = "Callable[[Any, SimpleNamespace], LoaderResult]"
LoaderConstraint: TypeAlias = Union[Loader, "Iterable[Loader]", None]

XPathFunction: TypeAlias = "Callable[[EvaluationContext, *Any], Any]"


__all__ = (
"Filter",
Expand Down
10 changes: 5 additions & 5 deletions _delb/xpath/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@


@plugin_manager.register_xpath_function
def concat(_, *strings: str) -> str:
def concat(_: EvaluationContext, *strings: str) -> str:
return "".join(strings)


@plugin_manager.register_xpath_function
def contains(_, string: str, substring: str) -> bool:
def contains(_: EvaluationContext, string: str, substring: str) -> bool:
return substring in string


@plugin_manager.register_xpath_function
def boolean(_, value: Any) -> bool:
def boolean(_: EvaluationContext, value: Any) -> bool:
return bool(value)


Expand All @@ -46,7 +46,7 @@ def last(context: EvaluationContext) -> int:


@plugin_manager.register_xpath_function("not")
def _not(_, value: Any) -> bool:
def _not(_: EvaluationContext, value: Any) -> bool:
return not value


Expand All @@ -56,7 +56,7 @@ def position(context: EvaluationContext) -> int:


@plugin_manager.register_xpath_function("starts-with")
def starts_with(_, string: str, prefix: str) -> bool:
def starts_with(_: EvaluationContext, string: str, prefix: str) -> bool:
return string.startswith(prefix)


Expand Down

0 comments on commit 98f06e7

Please sign in to comment.