Skip to content

Annotate context argument of FunctionNamespace functions - #130

Open
andersk wants to merge 2 commits into
abelcheung:mainfrom
andersk:xpath-function-context
Open

andersk wants to merge 2 commits into
abelcheung:mainfrom
andersk:xpath-function-context

Conversation

@andersk

@andersk andersk commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

Every XPath extension function receives a context object as its first argument, which provides the context_node and eval_context properties. Add a stub-only _BaseContext class describing it, and require functions registered in _XPathFunctionNamespaceRegistry to accept it as first argument.

At runtime the context is an _XPathContext or an _XSLTContext, since the same function namespace registry serves both XPath and XSLT, so the common base class is used.

@abelcheung

Copy link
Copy Markdown
Owner

Errors in workflow checks are not your problem, I haven't touched the codebase for a long while, and various type checkers have progressed significantly during all this time. I will try to spend some time these days.

@andersk
andersk force-pushed the xpath-function-context branch from dc70b3a to a386551 Compare September 25, 2026 10:02
This was referenced Sep 25, 2026
andersk and others added 2 commits September 25, 2026 16:46
Every XPath extension function receives a context object as its first
argument, which provides the context_node and eval_context properties
(https://lxml.de/extensions.html#the-xpath-context).  Add a stub-only
_BaseContext class describing it, and require functions registered in
_XPathFunctionNamespaceRegistry to accept it as first argument.

At runtime the context is an _XPathContext or an _XSLTContext, since
the same function namespace registry serves both XPath and XSLT, so
the common base class is used.

The decorator form now uses a TypeVar bound to the extension function
type instead of a ParamSpec, so the decorated function's type is
preserved exactly, including the annotation of its first parameter.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Apply the same context-first-argument requirement introduced for
FunctionNamespace to the extensions= argument of _Element.xpath(),
_ElementTree.xpath(), XPath, ETXPath, XPathElementEvaluator,
XPathDocumentEvaluator and XPathEvaluator, and to the return type of
Extension().

Because dict values are invariant, a plain
dict[..., Callable[Concatenate[_BaseContext, ...], Any]] parameter
would make mypy reject correct code such as an inferred
{("ns", "f"): f} dict variable.  The dict forms therefore use a TypeVar
bound to the extension function type, so the value type is solved
instead of compared invariantly.

Compatibility: extension functions that take no arguments, or whose
first parameter is annotated with a type incompatible with
_BaseContext, are now rejected.  Unannotated functions, and dicts
explicitly annotated with Callable[..., Any] values, are accepted as
before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@andersk
andersk force-pushed the xpath-function-context branch from a386551 to 4fe4a3e Compare September 25, 2026 23:46

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants