-
I'm wondering if there's a way to let the type-checker know that all classes produced by a certain metaclass have a specified base-class. I use a metaclass to create
The problem is that I'm suspecting that I need to annotate the _T = TypeVar("_T")
class MetaOxmlElement(type):
"""Metaclass for BaseOxmlElement."""
def __new__(
cls: Type[_T], clsname: str, bases: Tuple[type, ...], namespace: Dict[str, Any]
) -> _T:
bases = (*bases, etree.ElementBase)
return super().__new__(cls, clsname, bases, namespace) More ContextI'm the author of The metaclass that creates these element-classes is |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
I don't think there's a way in the current type system to handle such dynamic code. Why do you dynamically inject the class BaseOxmlElement(ElementBase, metaclass=MetaOxmlElement):
... I think that achieves the same thing without needing to resort to dynamic "magic" that confuses a static type checker. |
Beta Was this translation helpful? Give feedback.
-
Thanks very much Eric for replying :) Making that change gives me: I've seen that before while trying one thing and another to see if I could happen on a magic combination. I can't say I actually know what it means though. The MRO for >>> from lxml import etree
>>> etree.ElementBase.__mro__
(<class 'lxml.etree.ElementBase'>, <class 'lxml.etree._Element'>, <class 'object'>)
>>> etree._Element.__mro__
(<class 'lxml.etree._Element'>, <class 'object'>) I get that same typing error with both Neither
|
Beta Was this translation helpful? Give feedback.
Thanks, I'm able to repro the issue now. The problem is that the
lxml
stubs indicate thatlxml.etree._Element
subclasses fromSized
, which uses anABCMeta
metaclass. At runtime,lxml.etree._Element
does not derive fromSized
, so this appears to be a bug in thelxml
type stubs, which are not accurately reflecting the implementation. You can work around the issue in your code by adding a# type: ignore
or# pyright: ignore
.It occurs to me that pyright's error message in this case could be improved. I've updated the code accordingly, and future releases of pyright will now report the specific metaclasses that are causing the conflict.