mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-10-31 07:57:26 +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