|
1 | 1 | from collections.abc import Iterable
|
2 | 2 | from functools import partial
|
| 3 | +from typing import Any, Callable, Dict |
3 | 4 |
|
4 | 5 | from graphql import (
|
5 | 6 | ArgumentNode,
|
@@ -105,7 +106,7 @@ def args(self, **kwargs):
|
105 | 106 | arg = self.field.args.get(name)
|
106 | 107 | if not arg:
|
107 | 108 | raise KeyError(f"Argument {name} does not exist in {self.field}.")
|
108 |
| - arg_type_serializer = get_arg_serializer(arg.type) |
| 109 | + arg_type_serializer = get_arg_serializer(arg.type, known_serializers=dict()) |
109 | 110 | serialized_value = arg_type_serializer(value)
|
110 | 111 | added_args.append(
|
111 | 112 | ArgumentNode(name=NameNode(value=name), value=serialized_value)
|
@@ -151,21 +152,25 @@ def serialize_list(serializer, list_values):
|
151 | 152 | return ListValueNode(values=FrozenList(serializer(v) for v in list_values))
|
152 | 153 |
|
153 | 154 |
|
154 |
| -def get_arg_serializer(arg_type): |
| 155 | +def get_arg_serializer(arg_type, known_serializers): |
155 | 156 | if isinstance(arg_type, GraphQLNonNull):
|
156 |
| - return get_arg_serializer(arg_type.of_type) |
| 157 | + return get_arg_serializer(arg_type.of_type, known_serializers) |
157 | 158 | if isinstance(arg_type, GraphQLInputField):
|
158 |
| - return get_arg_serializer(arg_type.type) |
| 159 | + return get_arg_serializer(arg_type.type, known_serializers) |
159 | 160 | if isinstance(arg_type, GraphQLInputObjectType):
|
160 |
| - serializers = {k: get_arg_serializer(v) for k, v in arg_type.fields.items()} |
161 |
| - return lambda value: ObjectValueNode( |
| 161 | + if arg_type in known_serializers: |
| 162 | + return known_serializers[arg_type] |
| 163 | + known_serializers[arg_type] = None |
| 164 | + serializers = {k: get_arg_serializer(v, known_serializers) for k, v in arg_type.fields.items()} |
| 165 | + known_serializers[arg_type] = lambda value: ObjectValueNode( |
162 | 166 | fields=FrozenList(
|
163 | 167 | ObjectFieldNode(name=NameNode(value=k), value=serializers[k](v))
|
164 | 168 | for k, v in value.items()
|
165 | 169 | )
|
166 | 170 | )
|
| 171 | + return known_serializers[arg_type] |
167 | 172 | if isinstance(arg_type, GraphQLList):
|
168 |
| - inner_serializer = get_arg_serializer(arg_type.of_type) |
| 173 | + inner_serializer = get_arg_serializer(arg_type.of_type, known_serializers) |
169 | 174 | return partial(serialize_list, inner_serializer)
|
170 | 175 | if isinstance(arg_type, GraphQLEnumType):
|
171 | 176 | return lambda value: EnumValueNode(value=arg_type.serialize(value))
|
|
0 commit comments