Thank you for pydantic_yaml. The recent release of version 1.3.0 has altered the behaviour when loading from yaml. Specifically, parse_yaml_raw_as no longer works when a typing.Union is passed as the model_type (i.e. when allowing pydantic to determine which of the Union member classes to construct). It fails because a typing.Union instance is not a typical python class and raises an exception if passed to issubclass, as is done here. I believe the previous version did not include this subclass check and clause.
Is this intended behaviour? Is passing a Union[.] somehow not a sensible thing to do? Or is this a bug?
I've included a minimal example script to reproduce the behaviour below, as well as a python environment.
If this is a bug, what is the solution? The instance can be successfully loaded if I intervene to step over the issubclass(.) clause and instead load the object with the subsequent clause, which I believe is the same or similar to the pathway taken in ver 1.2.1, that is:
ta = TypeAdapter(model_type) # type: ignore
return ta.validate_python(objects)
so I suppose an additional conditional check could be prepended to the `issubclass` clause to step over when needed.
**Example script:**
from pydantic_yaml import parse_yaml_raw_as
from pydantic import BaseModel
from typing import Union, List
Exception has occurred: TypeError (note: full exception trace is shown but execution is paused at: _run_module_as_main)
issubclass() arg 1 must be a class
File "/home/adam/projects/scratch/env/lib/python3.10/abc.py", line 123, in subclasscheck
return _abc_subclasscheck(cls, subclass)
File "/home/adam/projects/scratch/env/lib/python3.10/site-packages/pydantic_yaml/_internals/v2.py", line 238, in parse_yaml_raw_as
if issubclass(model_type, BaseModelV1):
File "/home/adam/projects/scratch/test.py", line 17, in
my_loaded_instance = parse_yaml_raw_as(Union[MyStrModel,MyListModel],"my_prop: my_yaml_string")
File "/home/adam/projects/scratch/env/lib/python3.10/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/home/adam/projects/scratch/env/lib/python3.10/runpy.py", line 196, in _run_module_as_main (Current frame)
return _run_code(code, main_globals, None,
TypeError: issubclass() arg 1 must be a class
Hi,
Thank you for
pydantic_yaml
. The recent release of version 1.3.0 has altered the behaviour when loading from yaml. Specifically,parse_yaml_raw_as
no longer works when atyping.Union
is passed as themodel_type
(i.e. when allowing pydantic to determine which of the Union member classes to construct). It fails because atyping.Union
instance is not a typical python class and raises an exception if passed toissubclass
, as is done here. I believe the previous version did not include this subclass check and clause.Is this intended behaviour? Is passing a
Union[.]
somehow not a sensible thing to do? Or is this a bug?I've included a minimal example script to reproduce the behaviour below, as well as a python environment.
If this is a bug, what is the solution? The instance can be successfully loaded if I intervene to step over the
issubclass(.)
clause and instead load the object with the subsequent clause, which I believe is the same or similar to the pathway taken in ver 1.2.1, that is:from pydantic_yaml import parse_yaml_raw_as from pydantic import BaseModel from typing import Union, List
class MyStrModel(BaseModel): my_prop: str
class MyListModel(BaseModel): my_prop: List[str]
my_prop_as_str = MyStrModel(my_prop="my_string") print(my_prop_as_str)
my_prop_as_list = MyListModel(my_prop=["my_string_1", "my_string_2"]) print(my_prop_as_list)
my_loaded_instance = parse_yaml_raw_as(Union[MyStrModel,MyListModel],"my_prop: my_yaml_string") print(my_loaded_instance)
my_prop='my_string' my_prop=['my_string_1', 'my_string_2'] my_prop='my_yaml_string'
my_prop='my_string' my_prop=['my_string_1', 'my_string_2']
Exception has occurred: TypeError (note: full exception trace is shown but execution is paused at: _run_module_as_main) issubclass() arg 1 must be a class File "/home/adam/projects/scratch/env/lib/python3.10/abc.py", line 123, in subclasscheck return _abc_subclasscheck(cls, subclass) File "/home/adam/projects/scratch/env/lib/python3.10/site-packages/pydantic_yaml/_internals/v2.py", line 238, in parse_yaml_raw_as if issubclass(model_type, BaseModelV1): File "/home/adam/projects/scratch/test.py", line 17, in
my_loaded_instance = parse_yaml_raw_as(Union[MyStrModel,MyListModel],"my_prop: my_yaml_string")
File "/home/adam/projects/scratch/env/lib/python3.10/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/home/adam/projects/scratch/env/lib/python3.10/runpy.py", line 196, in _run_module_as_main (Current frame)
return _run_code(code, main_globals, None,
TypeError: issubclass() arg 1 must be a class
Name Version Build Channel
_libgcc_mutex 0.1 main
_openmp_mutex 5.1 1_gnu
annotated-types 0.7.0 pypi_0 pypi bzip2 1.0.8 h5eee18b_6
ca-certificates 2024.3.11 h06a4308_0
importlib-metadata 7.2.0 pypi_0 pypi ld_impl_linux-64 2.38 h1181459_1
libffi 3.4.4 h6a678d5_1
libgcc-ng 11.2.0 h1234567_1
libgomp 11.2.0 h1234567_1
libstdcxx-ng 11.2.0 h1234567_1
libuuid 1.41.5 h5eee18b_0
ncurses 6.4 h6a678d5_0
openssl 3.0.14 h5eee18b_0
pip 24.0 py310h06a4308_0
pydantic 2.7.4 pypi_0 pypi pydantic-core 2.18.4 pypi_0 pypi pydantic-yaml 1.3.0 pypi_0 pypi python 3.10.14 h955ad1f_1
readline 8.2 h5eee18b_0
ruamel-yaml 0.18.6 pypi_0 pypi ruamel-yaml-clib 0.2.8 pypi_0 pypi setuptools 69.5.1 py310h06a4308_0
sqlite 3.45.3 h5eee18b_0
tk 8.6.14 h39e8969_0
typing-extensions 4.12.2 pypi_0 pypi tzdata 2024a h04d1e81_0
wheel 0.43.0 py310h06a4308_0
xz 5.4.6 h5eee18b_1
zipp 3.19.2 pypi_0 pypi zlib 1.2.13 h5eee18b_1