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])]
