From a147ed6c00059ea2ea4e373c7211bf7e3bc1f1e9 Mon Sep 17 00:00:00 2001 From: Paul van der Linden Date: Tue, 3 May 2022 17:15:48 +0200 Subject: [PATCH 1/7] test: parse mapping --- CONTRIBUTING.md | 2 +- tests/test_parse_mapping.py | 101 ++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 tests/test_parse_mapping.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 70750f8e..e3512f2e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ virtualenv gql-dev Activate the virtualenv and install dependencies by running: ```console -python -m pip install -e.[dev] +python -m pip install -e.[test] ``` If you are using Linux or MacOS, you can make use of Makefile command diff --git a/tests/test_parse_mapping.py b/tests/test_parse_mapping.py new file mode 100644 index 00000000..9d51be23 --- /dev/null +++ b/tests/test_parse_mapping.py @@ -0,0 +1,101 @@ +from graphql.type import ( + GraphQLArgument, + GraphQLField, + GraphQLInt, + GraphQLList, + GraphQLObjectType, + GraphQLSchema, + GraphQLNonNull, + GraphQLString, +) + +from gql import Client, gql + + +def static_result(root, _info, count): + return { + "edges": [ + { + "node": { + "from": {"address": "0x45b9ad45995577fe"}, + "to": {"address": "0x6394e988297f5ed2"}, + } + }, + {"node": {"from": None, "to": {"address": "0x6394e988297f5ed2"}}}, + ] + } + + +Account = GraphQLObjectType( + name="Account", + fields={"address": GraphQLField(GraphQLNonNull(GraphQLString))}, +) + + +queryType = GraphQLObjectType( + name="RootQueryType", + fields={ + "test": GraphQLField( + GraphQLObjectType( + name="test", + fields={ + "edges": GraphQLField( + GraphQLList( + GraphQLObjectType( + "example", + fields={ + "node": GraphQLField( + GraphQLObjectType( + name="node", + fields={ + "from": GraphQLField(Account), + "to": GraphQLField(Account), + }, + ) + ) + }, + ) + ) + ) + }, + ), + args={"count": GraphQLArgument(GraphQLInt)}, + resolve=static_result, + ), + }, +) + +schema = GraphQLSchema(query=queryType) + + +def test_null_mapping(): + + client = Client(schema=schema, parse_results=True) + query = gql( + """query testQ($count: Int) {test(count: $count){ + edges { + node { + from { + address + } + to { + address + } + } + } + } }""" + ) + + assert client.execute(query, variable_values={"count": 2}) == { + "test": { + "edges": [ + { + "node": { + "from": {"address": "0x45b9ad45995577fe"}, + "to": {"address": "0x6394e988297f5ed2"}, + } + }, + {"node": {"from": None, "to": {"address": "0x6394e988297f5ed2"}}}, + ] + } + } From 7403e0cf2c7ee3f0a46f62b3f16f24d53acec2d4 Mon Sep 17 00:00:00 2001 From: Hanusz Leszek Date: Tue, 3 May 2022 18:53:44 +0200 Subject: [PATCH 2/7] possible fix --- gql/utilities/parse_result.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gql/utilities/parse_result.py b/gql/utilities/parse_result.py index 5f9dd2a4..e4da866d 100644 --- a/gql/utilities/parse_result.py +++ b/gql/utilities/parse_result.py @@ -294,7 +294,7 @@ def leave_field( if self.current_result is None: log.debug(f"Leave field {name}: returning None") - return {name: None} + return_value = {name: None} elif node.selection_set is None: From baff2f25240e5d7808218d99fc2198d569cd6413 Mon Sep 17 00:00:00 2001 From: Hanusz Leszek Date: Tue, 3 May 2022 18:56:17 +0200 Subject: [PATCH 3/7] fix style --- gql/utilities/parse_result.py | 2 +- tests/test_parse_mapping.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gql/utilities/parse_result.py b/gql/utilities/parse_result.py index e4da866d..a1b77456 100644 --- a/gql/utilities/parse_result.py +++ b/gql/utilities/parse_result.py @@ -294,7 +294,7 @@ def leave_field( if self.current_result is None: log.debug(f"Leave field {name}: returning None") - return_value = {name: None} + return_value: Dict[str, Any] = {name: None} elif node.selection_set is None: diff --git a/tests/test_parse_mapping.py b/tests/test_parse_mapping.py index 9d51be23..07c155f8 100644 --- a/tests/test_parse_mapping.py +++ b/tests/test_parse_mapping.py @@ -3,9 +3,9 @@ GraphQLField, GraphQLInt, GraphQLList, + GraphQLNonNull, GraphQLObjectType, GraphQLSchema, - GraphQLNonNull, GraphQLString, ) From 33a01889d16b2da424c2cb7680c55b830e7f9aad Mon Sep 17 00:00:00 2001 From: Hanusz Leszek Date: Tue, 3 May 2022 22:11:38 +0200 Subject: [PATCH 4/7] small change in debug logs --- gql/utilities/parse_result.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/gql/utilities/parse_result.py b/gql/utilities/parse_result.py index a1b77456..ede627ae 100644 --- a/gql/utilities/parse_result.py +++ b/gql/utilities/parse_result.py @@ -293,8 +293,7 @@ def leave_field( if self.current_result is None: - log.debug(f"Leave field {name}: returning None") - return_value: Dict[str, Any] = {name: None} + return_value = None elif node.selection_set is None: @@ -308,23 +307,19 @@ def leave_field( assert is_leaf_type(result_type) # Finally parsing a single scalar using the parse_value method - parsed_value = result_type.parse_value(self.current_result) - - return_value = {name: parsed_value} + return_value = result_type.parse_value(self.current_result) else: partial_results = cast(List[Dict[str, Any]], node.selection_set) - return_value = { - name: {k: v for pr in partial_results for k, v in pr.items()} - } + return_value = {k: v for pr in partial_results for k, v in pr.items()} # Go up a level in the result stack self.result_stack.pop() log.debug(f"Leave field {name}: returning {return_value}") - return return_value + return {name: return_value} # Fragments From e7431894cd607d65392d44690c173081dc12c834 Mon Sep 17 00:00:00 2001 From: Hanusz Leszek Date: Tue, 3 May 2022 22:13:43 +0200 Subject: [PATCH 5/7] Restore CONTRIBUTING.md file --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e3512f2e..70750f8e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ virtualenv gql-dev Activate the virtualenv and install dependencies by running: ```console -python -m pip install -e.[test] +python -m pip install -e.[dev] ``` If you are using Linux or MacOS, you can make use of Makefile command From d2ff81f0f404652a5174c40ad0754931bb224e6f Mon Sep 17 00:00:00 2001 From: Hanusz Leszek Date: Tue, 3 May 2022 22:22:34 +0200 Subject: [PATCH 6/7] Move test in custom_scalars folder --- .../test_parse_results.py} | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) rename tests/{test_parse_mapping.py => custom_scalars/test_parse_results.py} (92%) diff --git a/tests/test_parse_mapping.py b/tests/custom_scalars/test_parse_results.py similarity index 92% rename from tests/test_parse_mapping.py rename to tests/custom_scalars/test_parse_results.py index 07c155f8..086474ff 100644 --- a/tests/test_parse_mapping.py +++ b/tests/custom_scalars/test_parse_results.py @@ -68,7 +68,12 @@ def static_result(root, _info, count): schema = GraphQLSchema(query=queryType) -def test_null_mapping(): +def test_parse_results_null_mapping(): + """This is a regression test for the issue: + https://github.com/graphql-python/gql/issues/325 + + Most of the parse_results tests are in tests/starwars/test_parse_results.py + """ client = Client(schema=schema, parse_results=True) query = gql( From ccc1c83a0b1dda9078102d9e1fec47aefe9b59b8 Mon Sep 17 00:00:00 2001 From: Hanusz Leszek Date: Tue, 3 May 2022 22:39:05 +0200 Subject: [PATCH 7/7] modify test to allow to modify static_result easily for some manual tests --- tests/custom_scalars/test_parse_results.py | 40 +++++++++------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/tests/custom_scalars/test_parse_results.py b/tests/custom_scalars/test_parse_results.py index 086474ff..e3c6d6f6 100644 --- a/tests/custom_scalars/test_parse_results.py +++ b/tests/custom_scalars/test_parse_results.py @@ -11,19 +11,21 @@ from gql import Client, gql +static_result = { + "edges": [ + { + "node": { + "from": {"address": "0x45b9ad45995577fe"}, + "to": {"address": "0x6394e988297f5ed2"}, + } + }, + {"node": {"from": None, "to": {"address": "0x6394e988297f5ed2"}}}, + ] +} -def static_result(root, _info, count): - return { - "edges": [ - { - "node": { - "from": {"address": "0x45b9ad45995577fe"}, - "to": {"address": "0x6394e988297f5ed2"}, - } - }, - {"node": {"from": None, "to": {"address": "0x6394e988297f5ed2"}}}, - ] - } + +def resolve_test(root, _info, count): + return static_result Account = GraphQLObjectType( @@ -60,7 +62,7 @@ def static_result(root, _info, count): }, ), args={"count": GraphQLArgument(GraphQLInt)}, - resolve=static_result, + resolve=resolve_test, ), }, ) @@ -92,15 +94,5 @@ def test_parse_results_null_mapping(): ) assert client.execute(query, variable_values={"count": 2}) == { - "test": { - "edges": [ - { - "node": { - "from": {"address": "0x45b9ad45995577fe"}, - "to": {"address": "0x6394e988297f5ed2"}, - } - }, - {"node": {"from": None, "to": {"address": "0x6394e988297f5ed2"}}}, - ] - } + "test": static_result }