Skip to content

Commit 5f33a89

Browse files
author
Rami Chowdhury
committed
Make more compatible with recent Pydantic
1 parent 7ea4f42 commit 5f33a89

File tree

3 files changed

+48
-17
lines changed

3 files changed

+48
-17
lines changed

graphene_pydantic/converters.py

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,36 @@
77
import decimal
88
import enum
99

10-
from pydantic import BaseModel, fields
10+
from pydantic import BaseModel
11+
from pydantic.fields import Field as PydanticField
12+
13+
try:
14+
# Pydantic pre-1.0
15+
from pydantic.fields import Shape
16+
17+
SHAPE_SINGLETON = (Shape.SINGLETON,)
18+
SHAPE_SEQUENTIAL = (
19+
Shape.LIST,
20+
Shape.TUPLE,
21+
Shape.TUPLE_ELLIPS,
22+
Shape.SEQUENCE,
23+
Shape.SET,
24+
)
25+
SHAPE_MAPPING = (Shape.MAPPING,)
26+
except ImportError:
27+
# Pydantic 1.0+
28+
from pydantic import fields
29+
30+
SHAPE_SINGLETON = (fields.SHAPE_SINGLETON,)
31+
SHAPE_SEQUENTIAL = (
32+
fields.SHAPE_LIST,
33+
fields.SHAPE_TUPLE,
34+
fields.SHAPE_TUPLE_ELLIPSIS,
35+
fields.SHAPE_SEQUENCE,
36+
fields.SHAPE_SET,
37+
)
38+
SHAPE_MAPPING = (fields.SHAPE_MAPPING,)
39+
1140

1241
from graphene import Field, Boolean, Enum, Float, Int, List, String, UUID, Union
1342
from graphene.types.base import BaseType
@@ -45,7 +74,7 @@ def _get_field(root, _info):
4574

4675

4776
def convert_pydantic_field(
48-
field: fields.Field,
77+
field: PydanticField,
4978
registry: Registry,
5079
parent_type: T.Type = None,
5180
model: T.Type[BaseModel] = None,
@@ -75,7 +104,7 @@ def convert_pydantic_field(
75104

76105
def convert_pydantic_type(
77106
type_: T.Type,
78-
field: fields.Field,
107+
field: PydanticField,
79108
registry: Registry = None,
80109
parent_type: T.Type = None,
81110
model: T.Type[BaseModel] = None,
@@ -88,24 +117,18 @@ def convert_pydantic_type(
88117
graphene_type = find_graphene_type(
89118
type_, field, registry, parent_type=parent_type, model=model
90119
)
91-
if field.shape == fields.Shape.SINGLETON:
120+
if field.shape in SHAPE_SINGLETON:
92121
return graphene_type
93-
elif field.shape in (
94-
fields.Shape.LIST,
95-
fields.Shape.TUPLE,
96-
fields.Shape.TUPLE_ELLIPS,
97-
fields.Shape.SEQUENCE,
98-
fields.Shape.SET,
99-
):
122+
elif field.shape in SHAPE_SEQUENTIAL:
100123
# TODO: _should_ Sets remain here?
101124
return List(graphene_type)
102-
elif field.shape == fields.Shape.MAPPING:
125+
elif field.shape in SHAPE_MAPPING:
103126
raise ConversionError(f"Don't know how to handle mappings in Graphene.")
104127

105128

106129
def find_graphene_type(
107130
type_: T.Type,
108-
field: fields.Field,
131+
field: PydanticField,
109132
registry: Registry = None,
110133
parent_type: T.Type = None,
111134
model: T.Type[BaseModel] = None,
@@ -178,7 +201,7 @@ def find_graphene_type(
178201

179202
def convert_generic_python_type(
180203
type_: T.Type,
181-
field: fields.Field,
204+
field: PydanticField,
182205
registry: Registry = None,
183206
parent_type: T.Type = None,
184207
model: T.Type[BaseModel] = None,
@@ -231,7 +254,7 @@ def convert_generic_python_type(
231254

232255
def convert_union_type(
233256
type_: T.Type,
234-
field: fields.Field,
257+
field: PydanticField,
235258
registry: Registry = None,
236259
parent_type: T.Type = None,
237260
model: T.Type[BaseModel] = None,

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ keywords = ["api", "graphql", "protocol", "rest", "relay", "graphene", "pydantic
2222
python = "^3.6"
2323
# To keep things simple, we only support newer versions of Graphene & Pydantic
2424
graphene = ">=2.1.3,<3"
25-
pydantic = ">=0.25,<0.30"
25+
pydantic = ">=0.26,<=1.1"
2626

2727
[tool.poetry.dev-dependencies]
2828
pytest = "~4.6.4"

tests/test_converters.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import pytest
88
import graphene
99
import graphene.types
10+
import pydantic
1011
from pydantic import create_model, BaseModel
1112

1213
from graphene_pydantic.converters import convert_pydantic_field, ConversionError
@@ -142,4 +143,11 @@ def test_unknown():
142143
with pytest.raises(ConversionError) as exc:
143144
_convert_field_from_spec("attr", (create_model("Model", size=int), None))
144145
assert "Don't know how to convert" in exc.value.args[0]
145-
assert "Field(attr type=Model default=None)" in exc.value.args[0]
146+
if pydantic.version.VERSION < pydantic.version.StrictVersion("1.0"):
147+
assert "Field(attr type=Model default=None)" in exc.value.args[0]
148+
else:
149+
# this worked at least as of 1.1
150+
assert (
151+
"ModelField(name='attr', type=Optional[Model], required=False, default=None)"
152+
in exc.value.args[0]
153+
)

0 commit comments

Comments
 (0)