dapper91 / pydantic-xml

python xml for humans
https://pydantic-xml.readthedocs.io
The Unlicense
155 stars 16 forks source link

`mypy`: Metaclass conflict in v2 #89

Closed ja-albert closed 1 year ago

ja-albert commented 1 year ago

Hi :) Again, thank you for your work and your quick fix in my previous issue!

I found a new problem in v2.0.0b1, which I could not reproduce in v1.0.0. MWE:

from pydantic_xml import BaseXmlModel

class A(BaseXmlModel): pass

Running mypy on it results in:

$ mypy test.py
test.py:3: error: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases  [misc]

I'm unsure if this is a mypy bug or not, but in my normal code, this results in this mypy error for each subclass of BaseXmlModel I have.

I also found this mypy issue which suggests that adding a # type: ignore[misc] to the class BaseXmlModel line could be a workaround: https://github.com/python/mypy/issues/14033#issuecomment-1307044115 But to be honest, I do not know enough about Python metaclasses to give you a better problem analysis and solution proposal. On the other hand, you may already have seen a similar issue, as you apparently added the same type ignore a few lines above the BaseXmlModel definition for version 2: https://github.com/dapper91/pydantic-xml/blob/v2.0.0b1/pydantic_xml/model.py#L202

dapper91 commented 1 year ago

Hi @ja-albert.

Thanks for your report.

Yes, the problem is here. mypy can't figure out that type(BaseModel) returns ModelMetaclass and thinks that BaseModel and BaseXmlModel have different metaclass roots which is prohibited in python.

The other problem is that ModelMetaclass located in an internal pydantic module which means it is not a public api and can be changed in the future.

Found the issue addressing that problem. They advice to import ModelMetaclass directly from pydantic._internal._model_construction.

I will fix it in the next release.

ja-albert commented 1 year ago

Thank you, the problem is fixed in the new release :+1: