pydantic-to-typescript
pydantic-to-typescript copied to clipboard
Error when TypeAlias is used
Hi and thank you for this package!
I would like to report a bug with version 1.0.10 and Python version 3.10.
Assume we have this Python file:
# test.py
from typing import TypeAlias
from pydantic import BaseModel
CustomType: TypeAlias = list[str]
class Test(BaseModel):
x: int
Now if I run pydantic2ts --module test.py --output ./test.ts I get the following error:
Traceback (most recent call last):
File "/Users/user/miniforge3/envs/py310/bin/pydantic2ts", line 8, in <module>
sys.exit(main())
File "/Users/user/miniforge3/envs/py310/lib/python3.10/site-packages/pydantic2ts/cli/script.py", line 274, in main
return generate_typescript_defs(
File "/Users/user/miniforge3/envs/py310/lib/python3.10/site-packages/pydantic2ts/cli/script.py", line 201, in generate_typescript_defs
models = extract_pydantic_models(import_module(module))
File "/Users/user/miniforge3/envs/py310/lib/python3.10/site-packages/pydantic2ts/cli/script.py", line 81, in extract_pydantic_models
for _, model in inspect.getmembers(module, is_concrete_pydantic_model):
File "/Users/user/miniforge3/envs/py310/lib/python3.10/inspect.py", line 482, in getmembers
if not predicate or predicate(value):
File "/Users/user/miniforge3/envs/py310/lib/python3.10/site-packages/pydantic2ts/cli/script.py", line 68, in is_concrete_pydantic_model
elif GenericModel and issubclass(obj, GenericModel):
File "/Users/user/miniforge3/envs/py310/lib/python3.10/abc.py", line 123, in __subclasscheck__
return _abc_subclasscheck(cls, subclass)
TypeError: issubclass() arg 1 must be a class
Note that CustomType is not even used in the PydanticModel. Still, if I comment out the definition of CustomType, the error disappears.
CustomType is (since version 3.9 at least) actually an instance of type GenericAlias. Despite it being the first argument (which is meant to work properly), calling issubclass with anything based on ABCMeta (which BaseModel and GenericModel are) results in a call to _abc_subclasscheck with the subclass last (which must not be a generic).
The pydantic maintainers encountered this early 2021 and fixed it in their pydantic.utils.lenient_issubclass function pydantic/pydantic#2399. Swapping out the two calls to issubclass in is_concrete_pydantic_model to that utility function solves it.
I modified the function to
def is_concrete_pydantic_model(obj) -> bool:
"""
Return true if an object is a concrete subclass of pydantic's BaseModel.
'concrete' meaning that it's not a GenericModel.
"""
return isinstance(obj, ModelMetaclass)
and I can generate typescript.