Improved lazy types support in Graphene

This commit also adds support for string types in Field, InputField, List and NonNull, where the string will be import. Usage like: Field("graphene.String")
This commit is contained in:
Syrus Akbary 2017-04-06 22:13:06 -07:00
parent bd0d418986
commit 4b71465922
9 changed files with 106 additions and 7 deletions

View File

@ -6,6 +6,7 @@ from .argument import Argument, to_arguments
from .mountedtype import MountedType
from .structures import NonNull
from .unmountedtype import UnmountedType
from .utils import get_type
base_type = type
@ -60,9 +61,7 @@ class Field(MountedType):
@property
def type(self):
if inspect.isfunction(self._type) or type(self._type) is partial:
return self._type()
return self._type
return get_type(self._type)
def get_resolver(self, parent_resolver):
return self.resolver or parent_resolver

View File

@ -1,5 +1,6 @@
from .mountedtype import MountedType
from .structures import NonNull
from .utils import get_type
class InputField(MountedType):
@ -11,7 +12,11 @@ class InputField(MountedType):
self.name = name
if required:
type = NonNull(type)
self.type = type
self._type = type
self.deprecation_reason = deprecation_reason
self.default_value = default_value
self.description = description
@property
def type(self):
return get_type(self._type)

View File

@ -1,4 +1,5 @@
from .unmountedtype import UnmountedType
from .utils import get_type
class Structure(UnmountedType):
@ -18,7 +19,11 @@ class Structure(UnmountedType):
cls_name,
of_type_name,
))
self.of_type = of_type
self._of_type = of_type
@property
def of_type(self):
return get_type(self._of_type)
def get_type(self):
'''

View File

@ -1,9 +1,11 @@
import pytest
from functools import partial
from ..argument import Argument
from ..field import Field
from ..structures import NonNull
from ..scalars import String
from .utils import MyLazyType
class MyInstance(object):
@ -66,6 +68,17 @@ def test_field_with_lazy_type():
assert field.type == MyType
def test_field_with_lazy_partial_type():
MyType = object()
field = Field(partial(lambda: MyType))
assert field.type == MyType
def test_field_with_string_type():
field = Field("graphene.types.tests.utils.MyLazyType")
assert field.type == MyLazyType
def test_field_not_source_and_resolver():
MyType = object()
with pytest.raises(Exception) as exc_info:

View File

@ -0,0 +1,30 @@
import pytest
from functools import partial
from ..inputfield import InputField
from ..structures import NonNull
from .utils import MyLazyType
def test_inputfield_required():
MyType = object()
field = InputField(MyType, required=True)
assert isinstance(field.type, NonNull)
assert field.type.of_type == MyType
def test_inputfield_with_lazy_type():
MyType = object()
field = InputField(lambda: MyType)
assert field.type == MyType
def test_inputfield_with_lazy_partial_type():
MyType = object()
field = InputField(partial(lambda: MyType))
assert field.type == MyType
def test_inputfield_with_string_type():
field = InputField("graphene.types.tests.utils.MyLazyType")
assert field.type == MyLazyType

View File

@ -1,7 +1,9 @@
import pytest
from functools import partial
from ..structures import List, NonNull
from ..scalars import String
from .utils import MyLazyType
def test_list():
@ -17,6 +19,23 @@ def test_list_with_unmounted_type():
assert str(exc_info.value) == 'List could not have a mounted String() as inner type. Try with List(String).'
def test_list_with_lazy_type():
MyType = object()
field = List(lambda: MyType)
assert field.of_type == MyType
def test_list_with_lazy_partial_type():
MyType = object()
field = List(partial(lambda: MyType))
assert field.of_type == MyType
def test_list_with_string_type():
field = List("graphene.types.tests.utils.MyLazyType")
assert field.of_type == MyLazyType
def test_list_inherited_works_list():
_list = List(List(String))
assert isinstance(_list.of_type, List)
@ -35,6 +54,23 @@ def test_nonnull():
assert str(nonnull) == 'String!'
def test_nonnull_with_lazy_type():
MyType = object()
field = NonNull(lambda: MyType)
assert field.of_type == MyType
def test_nonnull_with_lazy_partial_type():
MyType = object()
field = NonNull(partial(lambda: MyType))
assert field.of_type == MyType
def test_nonnull_with_string_type():
field = NonNull("graphene.types.tests.utils.MyLazyType")
assert field.of_type == MyLazyType
def test_nonnull_inherited_works_list():
_list = NonNull(List(String))
assert isinstance(_list.of_type, List)

View File

@ -0,0 +1 @@
MyLazyType = object()

View File

@ -283,6 +283,4 @@ class TypeMap(GraphQLTypeMap):
return GraphQLList(self.get_field_type(map, type.of_type))
if isinstance(type, NonNull):
return GraphQLNonNull(self.get_field_type(map, type.of_type))
if inspect.isfunction(type):
type = type()
return map.get(type._meta.name)

View File

@ -1,5 +1,9 @@
import inspect
from collections import OrderedDict
from functools import partial
from six import string_types
from ..utils.module_loading import import_string
from .mountedtype import MountedType
from .unmountedtype import UnmountedType
@ -62,3 +66,11 @@ def yank_fields_from_attrs(attrs, _as=None, delete=True, sort=True):
if sort:
fields_with_names = sorted(fields_with_names, key=lambda f: f[1])
return OrderedDict(fields_with_names)
def get_type(_type):
if isinstance(_type, string_types):
return import_string(_type)
if inspect.isfunction(_type) or type(_type) is partial:
return _type()
return _type