From 5a537872e4c88f58b1cba09bce2712d190a2f1ab Mon Sep 17 00:00:00 2001 From: getglad Date: Wed, 27 Mar 2019 22:26:37 -0400 Subject: [PATCH] Allow initialization of ObjectType with dynamic private state --- graphene/tests/issues/test_870.py | 80 +++++++++++++++++++++++++ graphene/types/objecttype.py | 2 +- graphene/types/tests/test_objecttype.py | 4 +- 3 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 graphene/tests/issues/test_870.py diff --git a/graphene/tests/issues/test_870.py b/graphene/tests/issues/test_870.py new file mode 100644 index 00000000..2b9850e1 --- /dev/null +++ b/graphene/tests/issues/test_870.py @@ -0,0 +1,80 @@ +import graphene + + +class SecondChild(graphene.ObjectType): + hello = graphene.String() + + +def resolve_second_child(self, info): + return SecondChild(hello=self.second_child._test) + + +second_child_f = graphene.Field(SecondChild, resolver=resolve_second_child) + + +class FirstChild(graphene.ObjectType): + hello = graphene.String() + second_child = second_child_f + + +def resolve_first_child(self, info): + message = self.first_child._test + " stranger" + + test_case = {"_test": message} + + return FirstChild( + hello=self.first_child._test, second_child=SecondChild(**test_case) + ) + + +first_child_f = graphene.Field(FirstChild, resolver=resolve_first_child) + + +class ParentQuery(graphene.ObjectType): + hello = graphene.String() + first_child = first_child_f + + +def resolve_parent(self, info, **args): + + message = args.get("greeting") + " there" + + test_case = {"_test": message} + + return ParentQuery(hello=args.get("greeting"), first_child=FirstChild(**test_case)) + + +parent = graphene.Field( + ParentQuery, resolver=resolve_parent, greeting=graphene.Argument(graphene.String) +) + + +class Query(graphene.ObjectType): + final = parent + + +def test_issue(): + query_string = """ + query { + final (greeting: "hi") { + hello + firstChild { + hello + secondChild { + hello + } + } + } + } + """ + + schema = graphene.Schema(query=Query) + result = schema.execute(query_string) + + assert not result.errors + assert result.data["final"]["hello"] == "hi" + assert result.data["final"]["firstChild"]["hello"] == "hi there" + assert ( + result.data["final"]["firstChild"]["secondChild"]["hello"] + == "hi there stranger" + ) diff --git a/graphene/types/objecttype.py b/graphene/types/objecttype.py index be4addb2..4af0db79 100644 --- a/graphene/types/objecttype.py +++ b/graphene/types/objecttype.py @@ -95,7 +95,7 @@ class ObjectType(BaseType): for prop in list(kwargs): try: if isinstance( - getattr(self.__class__, prop), property + getattr(self.__class__, prop, None), property ) or prop.startswith("_"): setattr(self, prop, kwargs.pop(prop)) except AttributeError: diff --git a/graphene/types/tests/test_objecttype.py b/graphene/types/tests/test_objecttype.py index 2acb578f..55b1a5f8 100644 --- a/graphene/types/tests/test_objecttype.py +++ b/graphene/types/tests/test_objecttype.py @@ -91,8 +91,8 @@ def test_generate_objecttype_with_private_attributes(): m = MyObjectType(_private_state="custom") assert m._private_state == "custom" - with pytest.raises(TypeError): - MyObjectType(_other_private_state="Wrong") + m = MyObjectType(_other_private_state="custom") + assert getattr(m, "_other_private_state", None) is "custom" def test_ordered_fields_in_objecttype():