mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-08 23:50:38 +03:00
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:
parent
bd0d418986
commit
4b71465922
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
'''
|
||||
|
|
|
@ -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:
|
||||
|
|
30
graphene/types/tests/test_inputfield.py
Normal file
30
graphene/types/tests/test_inputfield.py
Normal 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
|
|
@ -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)
|
||||
|
|
1
graphene/types/tests/utils.py
Normal file
1
graphene/types/tests/utils.py
Normal file
|
@ -0,0 +1 @@
|
|||
MyLazyType = object()
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user