Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't arbitrarily deserialize a Spec #131

Closed
callumforrester opened this issue Aug 8, 2024 · 2 comments
Closed

Can't arbitrarily deserialize a Spec #131

callumforrester opened this issue Aug 8, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@callumforrester
Copy link
Contributor

Spec provides a deserialize() method which uses an internal pydantic type adapter to deserialize a dict into any Spec.

As a developer I would like to deserailize a dict into an arbitrary type that I do not know at compile time so that I can include scanspecs in blueapi plans.

In the last version of scanspec I could do this with:

def deserialize(thing: T, type_of_thing: type[T]) -> T:
    return pydantic.parse_obj_as(type_of_thing, thing)

my_spec = deserialize(Spec, {"type": "Line", "start": 0.0, "stop": 1.0, "num": 10})
my_other_thing = deserialize(Foo, {"bar": 1})

This is now deprecated and has been replaced with TypeAdapter, so the equivalent would be:

def deserialize(thing: T, type_of_thing: type[T]) -> T:
    adapter = pydantic.TypeAdapter(type_of_thing)
    return adapter.validate_python(type_of_thing, thing)

my_spec = deserialize(Spec, {"type": "Line", "start": 0.0, "stop": 1.0, "num": 10})
my_other_thing = deserialize(Foo, {"bar": 1})

Using both of the above I get the same error:

Traceback (most recent call last):
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/type_adapter.py", line 277, in _init_core_attrs
    self._core_schema = _getattr_no_parents(self._type, '__pydantic_core_schema__')
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/type_adapter.py", line 119, in _getattr_no_parents
    raise AttributeError(attribute)
AttributeError: __pydantic_core_schema__

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/type_adapter.py", line 264, in __init__
    self._init_core_attrs(rebuild_mocks=False)
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/type_adapter.py", line 142, in wrapped
    return func(self, *args, **kwargs)
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/type_adapter.py", line 284, in _init_core_attrs
    self._core_schema = _get_schema(self._type, config_wrapper, parent_depth=self._parent_depth)
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/type_adapter.py", line 102, in _get_schema
    schema = gen.generate_schema(type_)
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 507, in generate_schema
    from_property = self._generate_schema_from_property(obj, obj)
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 679, in _generate_schema_from_property
    schema = get_schema(
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/scanspec/core.py", line 234, in __get_pydantic_core_schema__
    return handler(source_type)
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/_internal/_schema_generation_shared.py", line 83, in __call__
    schema = self._handler(source_type)
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 789, in _generate_schema_inner
    return self.match_type(obj)
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 875, in match_type
    return self._unknown_type_schema(obj)
  File "/home/vid18871/projects/bluesky/blueapi/venv/lib64/python3.10/site-packages/pydantic/_internal/_generate_schema.py", line 415, in _unknown_type_schema
    raise PydanticSchemaGenerationError(
pydantic.errors.PydanticSchemaGenerationError: Unable to generate pydantic-core schema for <class 'scanspec.specs.Spec'>. Set `arbitrary_types_allowed=True` in the model_config to ignore this error or implement `__get_pydantic_core_schema__` on your type to fully support it.

If you got this error by calling handler(<some type>) within `__get_pydantic_core_schema__` then you likely need to call `handler.generate_schema(<some type>)` since we do not call `__get_pydantic_core_schema__` on `<some type>` otherwise to avoid infinite recursion.

For further information visit https://errors.pydantic.dev/2.8/u/schema-for-unknown-type
@callumforrester callumforrester added the bug Something isn't working label Aug 8, 2024
@callumforrester
Copy link
Contributor Author

I suspect, but have not confirmed, that this is the same bug as #130

@callumforrester
Copy link
Contributor Author

Fixed by #132

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant