lxml-stubs
lxml-stubs copied to clipboard
Annotating XPathObject is a lost cause
Have been feeding on my own dogfood for quite a while, the annotation of XPathObject as XPath evaluation result is one of the spots that I feel constantly irritated. Although the annotation itself is correct per se, its presence turns out to be a nuisance for developers. The problem is, it is a long union of so many types that the selection result can never be used directly. For xpath evluation result to be useful, it has to be narrowed down to specific type(s) with approaches like:
- try-except block
isinstance()checkassert
All of them have one thing in common: throw away the type supplied by stub, and perform manual type narrowing afterwards. It is more like a roadblock rather than something that helps. As a supporting example, elementpath package returns Any as evaluation result even when the package is considered fully annotated.
Input argument used by variable inside xpath expression is different though, as that doesn't need extra processing and isn't as complex as output types.
My suggestion is set XPathObject as alias to Any, and cleanup input arguments as another alias, like:
_XPathObject = Any
_XPathVarArg = Union[...]
class XPath:
def __call__(self,
_etree_or_element: _ElementOrTree,
**_variables: _XPathVarArg
) -> _XPathObject: ...
Sounds ok. The return value is pretty much Any, I agree that more detail doesn't really add much.
This was the biggest thing I noticed when trying out the stubs on a project that already used lxml.
The discussion in https://github.com/python/typing/issues/566 and https://github.com/python/typing/issues/1096 might be of interest. One of the suggestions in that issue is to return Union[A, B, C] | Any. From my reading of those issues ,the idea is that IDEs can suggest completions, but type checkers won't force you to manually narrow the type.
its presence turns out to be a nuisance for developers.
agree
and in my project, I try to use try-except block, but mypy keeps reporting errors
i have to use isinstance()
This is so irritating!