graphql-python / graphql-python/graphql-core
Can default values form cycles?
- Linguagem predominante
- Python
- Estrelas
- 531
- Forks
- 146
- Métricas de merge de PRs
- Nenhum PR com merge em 30d
Descrição
Hi, I’ve been working with input fields' default values, and I encountered this question - can default values form cycles? I looked into the [spec](https://spec.graphql.org/October2021/) but I haven’t found answer. I tried to create a schema with such values:
```py
from graphql import build_schema
schema_str = """
schema { query: Query }
type Query { _skip: String! }
input InputA {
id: ID!
fieldB: InputB = {id: "1"}
}
input InputB {
id: ID!
fieldA: InputA = {id: "1"}
}
"""
build_schema(schema_str)
```
I used `graphql-core==3.2.3` and `python-3.11.1`, as a result, I got this exception:
```bash
Traceback (most recent call last):
File ".../lib/python3.11/site-packages/graphql/type/definition.py", line 1456, in fields
fields = resolve_thunk(self._fields)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/type/definition.py", line 300, in resolve_thunk
return thunk() if callable(thunk) else thunk
^^^^^^^
File ".../lib/python3.11/site-packages/graphql/utilities/extend_schema.py", line 605, in
fields=lambda: build_input_field_map(all_nodes),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RecursionError: maximum recursion depth exceeded
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".../lib/python3.11/site-packages/graphql/type/definition.py", line 1456, in fields
fields = resolve_thunk(self._fields)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/type/definition.py", line 300, in resolve_thunk
return thunk() if callable(thunk) else thunk
^^^^^^^
File ".../lib/python3.11/site-packages/graphql/utilities/extend_schema.py", line 605, in
fields=lambda: build_input_field_map(all_nodes),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/utilities/extend_schema.py", line 471, in build_input_field_map
default_value=value_from_ast(field.default_value, type_),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/utilities/value_from_ast.py", line 107, in value_from_ast
fields = type_.fields
^^^^^^^^^^^^
File "".../lib/python3.11/functools.py", line 1001, in __get__
val = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/type/definition.py", line 1459, in fields
raise cls(f"{self.name} fields cannot be resolved. {error}") from error
TypeError: InputB fields cannot be resolved. maximum recursion depth exceeded
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".../lib/python3.11/site-packages/graphql/type/definition.py", line 1456, in fields
fields = resolve_thunk(self._fields)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/type/definition.py", line 300, in resolve_thunk
return thunk() if callable(thunk) else thunk
^^^^^^^
File ".../lib/python3.11/site-packages/graphql/utilities/extend_schema.py", line 605, in
fields=lambda: build_input_field_map(all_nodes),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/utilities/extend_schema.py", line 471, in build_input_field_map
default_value=value_from_ast(field.default_value, type_),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/utilities/value_from_ast.py", line 107, in value_from_ast
fields = type_.fields
^^^^^^^^^^^^
File "".../lib/python3.11/functools.py", line 1001, in __get__
val = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/type/definition.py", line 1459, in fields
raise cls(f"{self.name} fields cannot be resolved. {error}") from error
TypeError: InputA fields cannot be resolved. InputB fields cannot be resolved. maximum recursion depth exceeded
The above exception was the direct cause of the following exception:
...
# 4k lines of the same error, each with extra `InputB fields cannot be resolved.`
...
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "scheam_test.py", line 17, in
build_schema(schema_str)
File ".../lib/python3.11/site-packages/graphql/utilities/build_ast_schema.py", line 95, in build_schema
return build_ast_schema(
^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/utilities/build_ast_schema.py", line 84, in build_ast_schema
return GraphQLSchema(**schema_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/type/schema.py", line 218, in __init__
collect_referenced_types(type_)
File ".../lib/python3.11/site-packages/graphql/type/schema.py", line 438, in collect_referenced_types
for field in named_type.fields.values():
^^^^^^^^^^^^^^^^^
File "".../lib/python3.11/functools.py", line 1001, in __get__
val = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File ".../lib/python3.11/site-packages/graphql/type/definition.py", line 1459, in fields
raise cls(f"{self.name} fields cannot be resolved. {error}") from error
TypeError: InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. InputA fields cannot be resolved. InputB fields cannot be resolved. maximum recursion depth exceeded
```
I wonder if this is not allowed but not mentioned in the specification or is it a bug in `graphql-core`?
Guia de contribuição
Nenhum guia de contribuição indexado para este repositório
Direção de pesquisa
Start with graphql/utilities/build_ast_schema.py and the traceback path through graphql/utilities/value_from_ast.py, graphql/type/definition.py, and graphql/type/schema.py. Reproduce the recursive InputA/InputB schema with the reported Python and graphql-core versions, then compare the behavior with the GraphQL specification. Done means the issue is classified according to the specification and recursive defaults receive a deliberate, tested outcome rather than an unbounded RecursionError.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- graphql, python
- Domínio
- api
- Tipo de issue
- Bug
- Dificuldade
- 3/5
- Tempo estimado
- 1-2 dias
- Status de atividade
- Pouca atividade
- Clareza
- Razoavelmente clara
- Facilidade para iniciantes
- 48/100