diff --git a/graphene/types/argument.py b/graphene/types/argument.py index 8a621b42..9ac10167 100644 --- a/graphene/types/argument.py +++ b/graphene/types/argument.py @@ -8,8 +8,9 @@ from .dynamic import Dynamic class Argument(OrderedType): - def __init__(self, type, default_value=None, description=None, name=None, required=False, _creation_counter=None): - super(Argument, self).__init__(_creation_counter=_creation_counter) + def __init__(self, type, default_value=None, description=None, name=None, required=False, + _creation_counter=None, _metadata=None): + super(Argument, self).__init__(_creation_counter=_creation_counter, _metadata=_metadata) if required: type = NonNull(type) diff --git a/graphene/types/field.py b/graphene/types/field.py index 3b9347c0..dab6c229 100644 --- a/graphene/types/field.py +++ b/graphene/types/field.py @@ -23,8 +23,8 @@ class Field(OrderedType): def __init__(self, type, args=None, resolver=None, source=None, deprecation_reason=None, name=None, description=None, required=False, _creation_counter=None, default_value=None, - **extra_args): - super(Field, self).__init__(_creation_counter=_creation_counter) + _metadata=None, **extra_args): + super(Field, self).__init__(_creation_counter=_creation_counter, _metadata=_metadata) assert not args or isinstance(args, Mapping), ( 'Arguments in a field have to be a mapping, received "{}".' ).format(args) diff --git a/graphene/types/inputfield.py b/graphene/types/inputfield.py index 09ccf5a8..e8f38f76 100644 --- a/graphene/types/inputfield.py +++ b/graphene/types/inputfield.py @@ -6,8 +6,8 @@ class InputField(OrderedType): def __init__(self, type, name=None, default_value=None, deprecation_reason=None, description=None, - required=False, _creation_counter=None, **extra_args): - super(InputField, self).__init__(_creation_counter=_creation_counter) + required=False, _creation_counter=None, _metadata=None, **extra_args): + super(InputField, self).__init__(_creation_counter=_creation_counter, _metadata=_metadata) self.name = name if required: type = NonNull(type) diff --git a/graphene/types/tests/test_structures.py b/graphene/types/tests/test_structures.py index e45f09e2..844e9422 100644 --- a/graphene/types/tests/test_structures.py +++ b/graphene/types/tests/test_structures.py @@ -13,7 +13,7 @@ def test_list(): def test_list_with_unmounted_type(): with pytest.raises(Exception) as exc_info: List(String()) - + assert str(exc_info.value) == 'List could not have a mounted String() as inner type. Try with List(String).' @@ -44,14 +44,14 @@ def test_nonnull_inherited_works_list(): def test_nonnull_inherited_dont_work_nonnull(): with pytest.raises(Exception) as exc_info: NonNull(NonNull(String)) - + assert str(exc_info.value) == 'Can only create NonNull of a Nullable GraphQLType but got: String!.' def test_nonnull_with_unmounted_type(): with pytest.raises(Exception) as exc_info: NonNull(String()) - + assert str(exc_info.value) == 'NonNull could not have a mounted String() as inner type. Try with NonNull(String).' diff --git a/graphene/types/tests/test_unmounted_type.py b/graphene/types/tests/test_unmounted_type.py new file mode 100644 index 00000000..ae8c4a7a --- /dev/null +++ b/graphene/types/tests/test_unmounted_type.py @@ -0,0 +1,44 @@ +from ..unmountedtype import UnmountedType + + +class MyUnmountedType(UnmountedType): + @classmethod + def get_type(cls): + ''' + This function is called when the unmounted type (Scalar instance) + is mounted (as a Field, InputField or Argument) + ''' + return cls + + +def test_unmountedtype_allows_setting_of_metadata(): + one = UnmountedType(_metadata='Test') + + assert one.metadata == 'Test' + + +def test_unmountedtype_metadata_defaults_to_none(): + one = UnmountedType() + + assert one.metadata is None + + +def test_unmountedtype_passes_on_metadata_to_field(): + one = MyUnmountedType(_metadata='Other Test') + one_field = one.Field() + + assert one_field.metadata == 'Other Test' + + +def test_unmountedtype_passes_on_metadata_to_input_field(): + one = MyUnmountedType(_metadata='Other Test') + one_input_field = one.InputField() + + assert one_input_field.metadata == 'Other Test' + + +def test_unmountedtype_passes_on_metadata_to_argument(): + one = MyUnmountedType(_metadata='Other Test') + one_argument = one.Argument() + + assert one_argument.metadata == 'Other Test' diff --git a/graphene/types/unmountedtype.py b/graphene/types/unmountedtype.py index e910421b..a9d934e9 100644 --- a/graphene/types/unmountedtype.py +++ b/graphene/types/unmountedtype.py @@ -15,10 +15,11 @@ class UnmountedType(OrderedType): >>> my_field = String(description='Description here') ''' - def __init__(self, *args, **kwargs): + def __init__(self, _metadata=None, *args, **kwargs): super(UnmountedType, self).__init__() self.args = args self.kwargs = kwargs + self.metadata = _metadata def get_type(self): ''' @@ -36,6 +37,7 @@ class UnmountedType(OrderedType): self.get_type(), *self.args, _creation_counter=self.creation_counter, + _metadata=self.metadata, **self.kwargs ) @@ -48,6 +50,7 @@ class UnmountedType(OrderedType): self.get_type(), *self.args, _creation_counter=self.creation_counter, + _metadata=self.metadata, **self.kwargs ) @@ -60,6 +63,7 @@ class UnmountedType(OrderedType): self.get_type(), *self.args, _creation_counter=self.creation_counter, + _metadata=self.metadata, **self.kwargs ) diff --git a/graphene/utils/orderedtype.py b/graphene/utils/orderedtype.py index a58f4d08..f6d92dcc 100644 --- a/graphene/utils/orderedtype.py +++ b/graphene/utils/orderedtype.py @@ -5,8 +5,9 @@ from functools import total_ordering class OrderedType(object): creation_counter = 1 - def __init__(self, _creation_counter=None): + def __init__(self, _creation_counter=None, _metadata=None): self.creation_counter = _creation_counter or self.gen_counter() + self.metadata = _metadata @staticmethod def gen_counter(): diff --git a/graphene/utils/tests/test_orderedtype.py b/graphene/utils/tests/test_orderedtype.py index ea6c7cc0..40df32d8 100644 --- a/graphene/utils/tests/test_orderedtype.py +++ b/graphene/utils/tests/test_orderedtype.py @@ -39,3 +39,15 @@ def test_orderedtype_non_orderabletypes(): assert one.__lt__(1) == NotImplemented assert one.__gt__(1) == NotImplemented assert not one == 1 + + +def test_orderedtype_has_metadata(): + one = OrderedType(_metadata='Test') + + assert one.metadata == 'Test' + + +def test_orderedtype_metadata_defaults_to_none(): + one = OrderedType() + + assert one.metadata == None