mirror of
https://github.com/kennethreitz/pydantic.git
synced 2026-06-05 23:00:18 +00:00
fix: forward ref with nested models and optional fields (#1752)
* fix: forward ref with nested models and optional fields PR #1712 introduced a regression for forward refs in `ModelField.prepare` as it would not return early for forward refs anymore. Optional fields would hence have `required` set to `True`. closes #1736 * test: skip python 3.6 as __future__.annotations is not defined
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Fix behaviour with forward refs and optional fields in nested models
|
||||
+5
-5
@@ -334,6 +334,11 @@ class ModelField(Representation):
|
||||
"""
|
||||
|
||||
self._set_default_and_type()
|
||||
if self.type_.__class__ == ForwardRef:
|
||||
# self.type_ is currently a ForwardRef and there's nothing we can do now,
|
||||
# user will need to call model.update_forward_refs()
|
||||
return
|
||||
|
||||
self._type_analysis()
|
||||
if self.required is Undefined:
|
||||
self.required = True
|
||||
@@ -366,11 +371,6 @@ class ModelField(Representation):
|
||||
if self.type_ is None:
|
||||
raise errors_.ConfigError(f'unable to infer type for attribute "{self.name}"')
|
||||
|
||||
if self.type_.__class__ == ForwardRef:
|
||||
# self.type_ is currently a ForwardRef and there's nothing we can do now,
|
||||
# user will need to call model.update_forward_refs()
|
||||
return
|
||||
|
||||
if self.required is False and default_value is None:
|
||||
self.allow_none = True
|
||||
|
||||
|
||||
@@ -439,3 +439,36 @@ else:
|
||||
raise AssertionError('error not raised')
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@skip_pre_37
|
||||
def test_forward_ref_optional(create_module):
|
||||
module = create_module(
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import List, Optional
|
||||
|
||||
|
||||
class Spec(BaseModel):
|
||||
spec_fields: List[str] = Field(..., alias="fields")
|
||||
filter: Optional[str]
|
||||
sort: Optional[str]
|
||||
|
||||
|
||||
class PSpec(Spec):
|
||||
g: Optional[GSpec]
|
||||
|
||||
|
||||
class GSpec(Spec):
|
||||
p: Optional[PSpec]
|
||||
|
||||
PSpec.update_forward_refs()
|
||||
|
||||
class Filter(BaseModel):
|
||||
g: Optional[GSpec]
|
||||
p: Optional[PSpec]
|
||||
"""
|
||||
)
|
||||
Filter = module.Filter
|
||||
assert isinstance(Filter(p={'sort': 'some_field:asc', 'fields': []}), Filter)
|
||||
|
||||
Reference in New Issue
Block a user