Skip to content

Commit f502608

Browse files
committed
pydantic 2.13 - fix UnsupportedFieldAttributeWarning
Union[Annotated[str, Field(default=None)], Annotated[int, Field(default=None)],] -> Annotated[Union[str, int], Field(default=None)] c.f. pydantic/pydantic#12530
1 parent cb906ce commit f502608

File tree

3 files changed

+22
-25
lines changed

3 files changed

+22
-25
lines changed

pyproject.toml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@ authors = [
66
]
77
dependencies = [
88
"PyYaml",
9-
"pydantic",
9+
"pydantic @ git+https://github.com/pydantic/pydantic.git",
1010
"email-validator",
1111
"yarl",
1212
"httpx",
1313
"more-itertools",
14-
'typing_extensions; python_version<"3.10"',
1514
"jmespath",
1615
]
1716
requires-python = ">=3.10"
@@ -50,9 +49,6 @@ Repository = "https://github.com/commonism/aiopenapi3"
5049
auth = [
5150
"httpx-auth>=0.21.0",
5251
]
53-
socks = [
54-
"httpx-socks",
55-
]
5652
types =[
5753
"pydantic-extra-types>=2.10.1",
5854
]
@@ -89,7 +85,9 @@ filterwarnings = [
8985
"ignore:unclosed <socket.socket fd=:ResourceWarning",
9086
"ignore:Ignoring Schema with additionalProperties and named properties:UserWarning",
9187
"ignore:'flask.Markup' is deprecated and will be removed in Flask 2.4. Import 'markupsafe.Markup' instead.:DeprecationWarning",
92-
"ignore:unclosed resource <TCPTransport:ResourceWarning"
88+
"ignore:unclosed resource <TCPTransport:ResourceWarning",
89+
"ignore:co_lnotab is deprecated, use co_lines instead:DeprecationWarning",
90+
# "ignore::pydantic.warnings.UnsupportedFieldAttributeWarning",
9391
]
9492
asyncio_mode = "strict"
9593
asyncio_default_fixture_loop_scope = "session"

src/aiopenapi3/model.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class _PropertyInfo:
113113
type_: str
114114

115115
root: Any = None
116+
anno: pydantic.Field = None
116117
config: dict[str, Any] = dataclasses.field(default_factory=dict)
117118
properties: dict[str, _PropertyInfo] = dataclasses.field(
118119
default_factory=lambda: collections.defaultdict(lambda: _ClassInfo._PropertyInfo())
@@ -257,10 +258,13 @@ def collapse(cls, type_name, items: list["_ClassInfo"]) -> type[BaseModel]:
257258
r = [i.model() for i in items]
258259

259260
if len(r) > 1:
260-
ru: object = Union[tuple(r)]
261+
# FIXME - merge annotations
262+
ru: object = Annotated[Union[tuple(r)], items[0].anno]
261263
m: type[RootModel] = create_model(type_name, __base__=(ConfiguredRootModel[ru],), __module__=me.__name__)
262264
elif len(r) == 1:
263265
m: type[BaseModel] = cast(type[BaseModel], r[0])
266+
if items[0].anno:
267+
m = Annotated[m, items[0].anno]
264268
if not is_basemodel(m):
265269
m = create_model(type_name, __base__=(ConfiguredRootModel[m],), __module__=me.__name__)
266270
else: # == 0
@@ -326,9 +330,8 @@ def createClassInfo(
326330
for primitive types the anyOf/oneOf is taken care of in Model.createAnnotation
327331
"""
328332
if typing.get_origin(_t := Model.createAnnotation(schema, _type=_type)) != Literal:
329-
classinfo.root = Annotated[_t, Model.createField(schema, _type=_type, args=None)]
330-
else:
331-
classinfo.root = _t
333+
classinfo.anno = Model.createField(schema, _type=_type, args=None)
334+
classinfo.root = _t
332335
elif _type == "array":
333336
"""anyOf/oneOf is taken care in in createAnnotation"""
334337
classinfo.root = Model.createAnnotation(schema, _type="array")
@@ -355,9 +358,8 @@ def createClassInfo(
355358
if _type in Model.types(i)
356359
)
357360
if schema.discriminator and schema.discriminator.mapping:
358-
classinfo.root = Annotated[
359-
Union[t], Field(discriminator=Model.nameof(schema.discriminator.propertyName))
360-
]
361+
classinfo.root = Union[t]
362+
classinfo.anno = Field(discriminator=Model.nameof(schema.discriminator.propertyName))
361363
else:
362364
if len(t):
363365
classinfo.root = Union[t]
@@ -373,9 +375,8 @@ def createClassInfo(
373375
if _type in Model.types(i)
374376
)
375377
if schema.discriminator and schema.discriminator.mapping:
376-
classinfo.root = Annotated[
377-
Union[t], Field(discriminator=Model.nameof(schema.discriminator.propertyName))
378-
]
378+
classinfo.root = Union[t]
379+
classinfo.anno = Field(discriminator=Model.nameof(schema.discriminator.propertyName))
379380
else:
380381
if len(t):
381382
classinfo.root = Union[t]
@@ -451,8 +452,8 @@ def validate_patternProperties(self_):
451452
"""
452453
assert isinstance(schema, v20.Schema)
453454
schema_ = v20.Schema(type="string", format="binary")
454-
_t = Model.createAnnotation(schema_, _type="string")
455-
classinfo.root = Annotated[_t, Model.createField(schema_, _type="string", args=None)]
455+
classinfo.root = Model.createAnnotation(schema_, _type="string")
456+
classinfo.anno = Model.createField(schema_, _type="string", args=None)
456457
else:
457458
raise ValueError(_type)
458459

@@ -716,7 +717,7 @@ def booleanFalse(schema: Optional["SchemaType"]) -> bool:
716717
raise ValueError(schema)
717718

718719
@staticmethod
719-
def createField(schema: "SchemaType", _type=None, args=None):
720+
def createField(schema: "SchemaType", _type=None, args=None) -> Field:
720721
if args is None:
721722
args = dict(default=getattr(schema, "default", None))
722723

tests/schema_test.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,10 @@ def test_schema_regex_engine(with_schema_regex_engine):
121121
import pydantic_core._pydantic_core
122122

123123
with pytest.raises(pydantic_core._pydantic_core.SchemaError, match="error: unclosed character class$"):
124-
annotations = typing.get_args(Root.model_fields["root"].annotation)
125-
assert len(annotations) == 2 and annotations[0] == str and isinstance(annotations[1], FieldInfo), annotations
126-
metadata = annotations[1].metadata
127-
assert len(metadata) == 1, metadata
128-
pattern = metadata[0].pattern
129-
assert isinstance(pattern, str), pattern
124+
t = Root.model_fields["root"]
125+
assert t.annotation == str
126+
assert isinstance(t.metadata[0].pattern, str)
127+
pattern = t.metadata[0].pattern
130128
from typing import Annotated
131129

132130
C = Annotated[str, pydantic.Field(pattern=pattern)]

0 commit comments

Comments
 (0)