tefra / xsdata-pydantic

Naive XML & JSON Bindings for python pydantic classes!
https://xsdata-pydantic.readthedocs.io/
MIT License
52 stars 10 forks source link

XmlPeriod don't have validator #16

Closed http403 closed 1 year ago

http403 commented 1 year ago

I generated a model for KML file but I got an no validator found exception.

To reproduce

xsdata generate https://schemas.opengis.net/kml/2.2.0/ogckml22.xsd --output pydantic --package kml

Run

from kml import ogckml22

def main():
    point = ogckml22.Placemark(
        name="Sample", point=ogckml.Point(coordinates="-122.0822035425683,37.42228990140251,0)"
    )

if __name__ == "__main__":
    main()

Output

Exception has occurred: RuntimeError       (note: full exception trace is shown but execution is paused at: _run_module_as_main)
no validator found for <class 'xsdata.models.datatype.XmlPeriod'>, see `arbitrary_types_allowed` in Config
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\validators.py", line 765, in find_validators
    raise RuntimeError(f'no validator found for {type_}, see `arbitrary_types_allowed` in Config')
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\fields.py", line 831, in pydantic.fields.ModelField.populate_validators
    *(get_validators() if get_validators else list(find_validators(self.type_, self.model_config))),
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\fields.py", line 557, in pydantic.fields.ModelField.prepare
    self.populate_validators()
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\fields.py", line 436, in pydantic.fields.ModelField.__init__
    self.prepare()
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\fields.py", line 808, in pydantic.fields.ModelField._create_sub_type
    return self.__class__(
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\fields.py", line 663, in pydantic.fields.ModelField._type_analysis
    self.sub_fields = [self._create_sub_type(t, f'{self.name}_{display_as_type(t)}') for t in types_]
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\fields.py", line 552, in pydantic.fields.ModelField.prepare
    self._type_analysis()
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\fields.py", line 436, in pydantic.fields.ModelField.__init__
    self.prepare()
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\fields.py", line 506, in pydantic.fields.ModelField.infer
Config    return cls(
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\main.py", line 197, in pydantic.main.ModelMetaclass.__new__
    fields[ann_name] = ModelField.infer(
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\main.py", line 1026, in pydantic.main.create_model
    return meta(__model_name, resolved_bases, namespace, **kwds)
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\dataclasses.py", line 400, in pydantic.dataclasses.create_pydantic_model_from_dataclass
    model: Type['BaseModel'] = create_model(
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\dataclasses.py", line 347, in pydantic.dataclasses._add_pydantic_validation_attributes
    setattr(dc_cls, '__pydantic_model__', create_pydantic_model_from_dataclass(dc_cls, config, dc_cls_doc))
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\dataclasses.py", line 224, in pydantic.dataclasses.dataclass.wrap
    _add_pydantic_validation_attributes(cls, the_config, should_validate_on_init, dc_cls_doc)
  File "C:\Users\User\AppData\Local\pypoetry\Cache\virtualenvs\pos2xml-nzgsLrQL-py3.10\Lib\site-packages\pydantic\dataclasses.py", line 231, in pydantic.dataclasses.dataclass
    return wrap(_cls)
  File "C:\Users\User\Documents\Projects\position-extract\kml\ogckml22.py", line 147, in <module>
    class Begin:
  File "C:\Users\User\Documents\Projects\position-extract\kml\__init__.py", line 9, in <module>
    from kml.ogckml22 import (
  File "C:\Users\User\Documents\Projects\position-extract\pos2kml\main.py", line 1, in <module>
    from kml import ogckml22
  File "C:\Users\User\scoop\apps\pyenv\current\pyenv-win\versions\3.10.2\Lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\User\scoop\apps\pyenv\current\pyenv-win\versions\3.10.2\Lib\runpy.py", line 196, in _run_module_as_main (Current frame)
    return _run_code(code, main_globals, None,
RuntimeError: no validator found for <class 'xsdata.models.datatype.XmlPeriod'>, see `arbitrary_types_allowed` in Config

However, I do saw a make_validators() for XmlPeriod was called in xsdata_pydantic/compact.py. I tried set a breakpoint there but it wasn't triggered.

bryan-hunt commented 1 year ago

@http403 I just ran into this issue myself - the pydantic validator bindings need to get loaded first before you can instantiate the model.

There are two side effects here actually - xsdata-pydantic becomes a project dependency in order to run it (likely a minor issue) and you need to make sure you do something to trigger loading of xsdata_pydantic.bindings before the model is instantiated.

I myself have the model saved within a larger package so I just added a dummy import xsdata_pydantic.bindings to the init.py file above it.

http403 commented 1 year ago

@bryan-hunt thanks for finding the solution. I moved to use xsdata-attrs instead. I will close this issue.