When I create a pydantic model dynamically via create_model()
then in some situations update_forward_refs()
can't find the relevant definition.
This works:
from typing import List, Union
from pydantic import BaseModel
class Foo(BaseModel):
foo: List["Bar"]
Bar = Union[Foo, int]
Foo.update_forward_refs()
But the following, which I believe should be equivalent, fails with a NameError:
from typing import List, Union
from pydantic import create_model, BaseModel
Foo = create_model("Foo", foo=(List["Bar"], ...))
Bar = Union[Foo, int]
Foo.update_forward_refs()
resulting in:
Traceback (most recent call last):
File "test_forward_ref.py", line 11, in <module>
Foo.update_forward_refs()
File "pydantic\main.py", line 832, in pydantic.main.BaseModel.update_forward_refs
File "pydantic\typing.py", line 382, in pydantic.typing.update_field_forward_refs
or class checks.
File "pydantic\typing.py", line 62, in pydantic.typing.evaluate_forwardref
'MutableSet',
File "C:\Users\Ian\.conda\envs\tso\lib\typing.py", line 518, in _evaluate
eval(self.__forward_code__, globalns, localns),
File "<string>", line 1, in <module>
NameError: name 'Bar' is not defined
It is significant that "Bar" is refered to within a List in the annotation for field foo
. If the annotation of field foo
is directly "Bar" then there is no problem.
Can someone please me towards fixing this please? What else do I need to do?
Python 3.8 and pydantic 1.8.2
CodePudding user response:
update_forward_refs()
admits a **localns: Any
parameter. It seems that in this case you can pass Bar=Bar
to update_forward_refs()
and it will work:
from typing import List, Union
from pydantic import create_model
Foo = create_model("Foo", foo=(List["Bar"], ...))
Bar = Union[Foo, int]
Foo.update_forward_refs(Bar=Bar)
print(Foo(foo=[1, Foo(foo=[2])]))
Output:
foo=[1, Foo(foo=[2])]