graphql-core 3.2.11__tar.gz → 3.2.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {graphql_core-3.2.11 → graphql_core-3.2.12}/.bumpversion.cfg +3 -3
- {graphql_core-3.2.11 → graphql_core-3.2.12}/PKG-INFO +2 -2
- {graphql_core-3.2.11 → graphql_core-3.2.12}/README.md +1 -1
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/conf.py +1 -1
- {graphql_core-3.2.11 → graphql_core-3.2.12}/pyproject.toml +2 -2
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/parser.py +26 -11
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/overlapping_fields_can_be_merged.py +59 -10
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/version.py +2 -2
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/PKG-INFO +2 -2
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_abstract.py +3 -1
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_parser.py +29 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_overlapping_fields_can_be_merged.py +91 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tox.ini +4 -4
- {graphql_core-3.2.11 → graphql_core-3.2.12}/.coveragerc +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/.editorconfig +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/.flake8 +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/.mypy.ini +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/.readthedocs.yaml +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/CODEOWNERS +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/LICENSE +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/MANIFEST.in +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/SECURITY.md +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/Makefile +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/diffs.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/index.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/intro.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/make.bat +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/error.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/execution.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/graphql.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/language.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/pyutils.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/type.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/utilities.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/validation.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/requirements.txt +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/extension.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/index.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/introspection.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/methods.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/other.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/parser.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/queries.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/resolvers.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/schema.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/sdl.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/validator.rst +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/poetry.lock +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/setup.cfg +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/setup.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/error/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/error/graphql_error.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/error/located_error.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/error/syntax_error.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/collect_fields.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/execute.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/map_async_iterator.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/middleware.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/subscribe.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/values.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/graphql.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/ast.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/block_string.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/character_classes.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/directive_locations.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/lexer.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/location.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/predicates.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/print_location.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/print_string.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/printer.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/schema_coordinate_lexer.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/source.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/token_kind.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/visitor.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/py.typed +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/awaitable_or_value.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/cached_property.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/convert_case.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/description.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/did_you_mean.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/frozen_dict.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/frozen_error.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/frozen_list.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/group_by.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/identity_func.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/inspect.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/is_awaitable.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/is_iterable.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/merge_kwargs.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/natural_compare.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/path.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/print_path_list.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/simple_pub_sub.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/suggestion_list.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/undefined.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/subscription/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/assert_name.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/definition.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/directives.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/introspection.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/scalars.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/validate.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/assert_valid_name.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/ast_from_value.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/ast_to_dict.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/build_ast_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/build_client_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/coerce_input_value.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/concat_ast.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/extend_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/find_breaking_changes.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/get_introspection_query.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/get_operation_ast.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/get_operation_root_type.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/introspection_from_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/lexicographic_sort_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/print_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/resolve_schema_coordinate.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/separate_operations.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/sort_value_node.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/strip_ignored_characters.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/type_comparators.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/type_from_ast.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/type_info.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/value_from_ast.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/value_from_ast_untyped.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/custom/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/custom/no_deprecated.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/custom/no_schema_introspection.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/executable_definitions.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/fields_on_correct_type.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/fragments_on_composite_types.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/known_argument_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/known_directives.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/known_fragment_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/known_type_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/lone_anonymous_operation.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/lone_schema_definition.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/max_introspection_depth_rule.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/no_fragment_cycles.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/no_undefined_variables.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/no_unused_fragments.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/no_unused_variables.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/possible_fragment_spreads.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/possible_type_extensions.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/provided_required_arguments.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/scalar_leafs.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/single_field_subscriptions.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_argument_definition_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_argument_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_directive_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_directives_per_location.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_enum_value_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_field_definition_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_fragment_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_input_field_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_operation_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_operation_types.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_type_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_variable_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/values_of_correct_type.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/variables_are_input_types.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/variables_in_allowed_position.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/specified_rules.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/validate.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/validation_context.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/SOURCES.txt +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/dependency_links.txt +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/not-zip-safe +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/requires.txt +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/top_level.txt +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_build_ast_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_build_client_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_execution_async.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_execution_sync.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_introspection_from_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_parser.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_print.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_repeated_fields.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_validate_gql.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_validate_invalid_gql.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_validate_sdl.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_visit.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/conftest.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/error/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/error/test_graphql_error.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/error/test_located_error.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/error/test_print_location.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_customize.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_directives.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_execution_result.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_executor.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_lists.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_map_async_iterator.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_middleware.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_mutations.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_nonnull.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_one_of.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_parallel.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_resolve.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_subscribe.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_sync.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_union_interface.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_variables.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/fixtures/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/fixtures/github_schema.graphql +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/fixtures/github_schema.json +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/fixtures/kitchen_sink.graphql +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/fixtures/schema_kitchen_sink.graphql +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_ast.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_block_string.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_block_string_fuzz.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_character_classes.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_lexer.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_location.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_predicates.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_print_string.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_printer.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_schema_coordinate_lexer.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_schema_parser.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_schema_printer.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_source.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_visitor.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_cached_property.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_convert_case.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_description.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_did_you_mean.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_frozen_dict.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_frozen_error.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_frozen_list.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_group_by.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_identity_func.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_inspect.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_is_awaitable.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_is_iterable.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_merge_kwargs.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_natural_compare.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_path.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_print_path_list.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_simple_pub_sub.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_suggestion_list.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_undefined.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/star_wars_data.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/star_wars_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_docs.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_star_wars_introspection.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_star_wars_query.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_star_wars_validation.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_user_registry.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_version.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_assert_name.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_custom_scalars.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_definition.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_directives.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_enum.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_extensions.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_introspection.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_predicate.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_scalars.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_validation.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_ast_from_value.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_ast_to_dict.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_build_ast_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_build_client_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_coerce_input_value.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_concat_ast.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_extend_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_find_breaking_changes.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_get_introspection_query.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_get_operation_ast.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_get_operation_root_type.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_introspection_from_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_lexicographic_sort_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_print_schema.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_resolve_schema_coordinate.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_separate_operations.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_sort_value_node.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_strip_ignored_characters.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_strip_ignored_characters_fuzz.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_type_comparators.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_type_from_ast.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_type_info.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_value_from_ast.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_value_from_ast_untyped.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utils/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utils/dedent.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utils/gen_fuzz_strings.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utils/test_dedent.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utils/test_gen_fuzz_strings.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/__init__.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/harness.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_executable_definitions.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_fields_on_correct_type.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_fragments_on_composite_types.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_known_argument_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_known_directives.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_known_fragment_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_known_type_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_lone_anonymous_operation.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_lone_schema_definition.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_max_introspection_depth_rule.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_deprecated.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_fragment_cycles.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_schema_introspection.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_undefined_variables.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_unused_fragments.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_unused_variables.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_possible_fragment_spreads.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_possible_type_extensions.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_provided_required_arguments.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_scalar_leafs.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_single_field_subscriptions.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_argument_definition_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_argument_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_directive_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_directives_per_location.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_enum_value_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_field_definition_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_fragment_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_input_field_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_operation_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_operation_types.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_type_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_variable_names.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_validation.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_values_of_correct_type.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_variables_are_input_types.py +0 -0
- {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_variables_in_allowed_position.py +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[bumpversion]
|
|
2
|
-
current_version = 3.2.
|
|
2
|
+
current_version = 3.2.12
|
|
3
3
|
commit = False
|
|
4
4
|
tag = False
|
|
5
5
|
|
|
@@ -8,8 +8,8 @@ search = version = "{current_version}"
|
|
|
8
8
|
replace = version = "{new_version}"
|
|
9
9
|
|
|
10
10
|
[bumpversion:file:docs/conf.py]
|
|
11
|
-
search = version = release =
|
|
12
|
-
replace = version = release =
|
|
11
|
+
search = version = release = "{current_version}"
|
|
12
|
+
replace = version = release = "{new_version}"
|
|
13
13
|
|
|
14
14
|
[bumpversion:file:README.md]
|
|
15
15
|
search = The current version {current_version}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphql-core
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.12
|
|
4
4
|
Summary: GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL.
|
|
5
5
|
Home-page: https://github.com/graphql-python/graphql-core
|
|
6
6
|
Author: Christoph Zwerschke
|
|
@@ -50,7 +50,7 @@ a query language for APIs created by Facebook.
|
|
|
50
50
|

|
|
51
51
|
[](https://github.com/ambv/black)
|
|
52
52
|
|
|
53
|
-
The current version 3.2.
|
|
53
|
+
The current version 3.2.12 of GraphQL-core is up-to-date with GraphQL.js version 16.14.2.
|
|
54
54
|
|
|
55
55
|
An extensive test suite with over 2500 unit tests and 100% coverage comprises a
|
|
56
56
|
replication of the complete test suite of GraphQL.js, making sure this port is
|
|
@@ -10,7 +10,7 @@ a query language for APIs created by Facebook.
|
|
|
10
10
|

|
|
11
11
|
[](https://github.com/ambv/black)
|
|
12
12
|
|
|
13
|
-
The current version 3.2.
|
|
13
|
+
The current version 3.2.12 of GraphQL-core is up-to-date with GraphQL.js version 16.14.2.
|
|
14
14
|
|
|
15
15
|
An extensive test suite with over 2500 unit tests and 100% coverage comprises a
|
|
16
16
|
replication of the complete test suite of GraphQL.js, making sure this port is
|
|
@@ -61,7 +61,7 @@ author = "Christoph Zwerschke"
|
|
|
61
61
|
# The short X.Y version.
|
|
62
62
|
# version = '3.2'
|
|
63
63
|
# The full version, including alpha/beta/rc tags.
|
|
64
|
-
version = release = "3.2.
|
|
64
|
+
version = release = "3.2.12"
|
|
65
65
|
|
|
66
66
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
|
67
67
|
# for a list of supported languages.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "graphql-core"
|
|
3
|
-
version = "3.2.
|
|
3
|
+
version = "3.2.12"
|
|
4
4
|
description = """
|
|
5
5
|
GraphQL-core is a Python port of GraphQL.js,\
|
|
6
6
|
the JavaScript reference implementation for GraphQL."""
|
|
@@ -87,5 +87,5 @@ disable = [
|
|
|
87
87
|
]
|
|
88
88
|
|
|
89
89
|
[build-system]
|
|
90
|
-
requires = ["poetry_core>=1,<3", "setuptools>=59,<
|
|
90
|
+
requires = ["poetry_core>=1,<3", "setuptools>=59,<85"]
|
|
91
91
|
build-backend = "poetry.core.masonry.api"
|
|
@@ -1355,18 +1355,33 @@ class Parser:
|
|
|
1355
1355
|
return nodes
|
|
1356
1356
|
|
|
1357
1357
|
def advance_lexer(self) -> None:
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1358
|
+
"""Advance the lexer.
|
|
1359
|
+
|
|
1360
|
+
Counts every token that is consumed toward ``max_tokens``, including the
|
|
1361
|
+
comment tokens that the lexer skips over between the previously focused token
|
|
1362
|
+
and the new one. Comments are read and allocated as ``Token`` objects (and
|
|
1363
|
+
chained into the token list) but are not returned by the lexer, so counting
|
|
1364
|
+
only the returned tokens would let a comment-padded document bypass
|
|
1365
|
+
``max_tokens`` while still allocating one token per comment.
|
|
1366
|
+
"""
|
|
1367
|
+
lexer = self._lexer
|
|
1368
|
+
token = lexer.advance()
|
|
1369
|
+
# Count the comment tokens that were skipped since the previously focused
|
|
1370
|
+
# token. They are the nodes strictly between ``last_token`` and ``token`` in
|
|
1371
|
+
# the token linked-list (the lexer only ever skips comments).
|
|
1372
|
+
skipped = lexer.last_token.next
|
|
1373
|
+
while skipped is not None and skipped is not token:
|
|
1361
1374
|
self._token_counter += 1
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1375
|
+
skipped = skipped.next
|
|
1376
|
+
if token.kind is not TokenKind.EOF:
|
|
1377
|
+
self._token_counter += 1
|
|
1378
|
+
max_tokens = self._max_tokens
|
|
1379
|
+
if max_tokens is not None and self._token_counter > max_tokens:
|
|
1380
|
+
raise GraphQLSyntaxError(
|
|
1381
|
+
lexer.source,
|
|
1382
|
+
token.start,
|
|
1383
|
+
f"Document contains more than {max_tokens} tokens. Parsing aborted.",
|
|
1384
|
+
)
|
|
1370
1385
|
|
|
1371
1386
|
|
|
1372
1387
|
def get_token_desc(token: Token) -> str:
|
|
@@ -32,7 +32,27 @@ from . import ValidationContext, ValidationRule
|
|
|
32
32
|
|
|
33
33
|
MYPY = False
|
|
34
34
|
|
|
35
|
-
__all__ = ["OverlappingFieldsCanBeMergedRule"]
|
|
35
|
+
__all__ = ["MAX_FIELD_COMPARISONS", "OverlappingFieldsCanBeMergedRule"]
|
|
36
|
+
|
|
37
|
+
# The maximum number of pairwise field comparisons performed while validating a
|
|
38
|
+
# single document with the OverlappingFieldsCanBeMerged rule. The rule compares
|
|
39
|
+
# every pair of fields that share a response name and recurses into their
|
|
40
|
+
# sub-selections, which is O(n^2) in the number of such fields (and worse when
|
|
41
|
+
# inline fragments repeat the same response name at multiple nesting levels). A
|
|
42
|
+
# crafted query can therefore drive validation into minutes of CPU on a single
|
|
43
|
+
# request. Once this many comparisons have been made, validation is aborted with a
|
|
44
|
+
# GraphQLError instead of running to completion. The default is high enough that any
|
|
45
|
+
# realistic query stays far below it; it can be raised or lowered by assigning to
|
|
46
|
+
# ``graphql.validation.rules.overlapping_fields_can_be_merged.MAX_FIELD_COMPARISONS``.
|
|
47
|
+
MAX_FIELD_COMPARISONS = 250_000
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ComparisonBudgetExceededError(Exception):
|
|
51
|
+
"""Internal signal that the field-comparison budget has been exhausted.
|
|
52
|
+
|
|
53
|
+
Raised deep inside the recursive conflict search and caught by the rule to abort
|
|
54
|
+
validation. Never surfaces to callers of ``validate``.
|
|
55
|
+
"""
|
|
36
56
|
|
|
37
57
|
|
|
38
58
|
def reason_message(reason: "ConflictReasonMessage") -> str:
|
|
@@ -67,15 +87,33 @@ class OverlappingFieldsCanBeMergedRule(ValidationRule):
|
|
|
67
87
|
# times, so this improves the performance of this validator.
|
|
68
88
|
self.cached_fields_and_fragment_names: Dict = {}
|
|
69
89
|
|
|
90
|
+
# Set once the comparison budget is exhausted. Further selection sets are then
|
|
91
|
+
# skipped, since validation has already been aborted with an error.
|
|
92
|
+
self._budget_exceeded = False
|
|
93
|
+
|
|
70
94
|
def enter_selection_set(self, selection_set: SelectionSetNode, *_args: Any) -> None:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
95
|
+
if self._budget_exceeded:
|
|
96
|
+
return
|
|
97
|
+
try:
|
|
98
|
+
conflicts = find_conflicts_within_selection_set(
|
|
99
|
+
self.context,
|
|
100
|
+
self.cached_fields_and_fragment_names,
|
|
101
|
+
self.compared_fields_and_fragment_pairs,
|
|
102
|
+
self.compared_fragment_pairs,
|
|
103
|
+
self.context.get_parent_type(),
|
|
104
|
+
selection_set,
|
|
105
|
+
)
|
|
106
|
+
except ComparisonBudgetExceededError:
|
|
107
|
+
self._budget_exceeded = True
|
|
108
|
+
self.report_error(
|
|
109
|
+
GraphQLError(
|
|
110
|
+
"Query is too complex to validate for overlapping fields:"
|
|
111
|
+
f" exceeded {MAX_FIELD_COMPARISONS} field comparisons."
|
|
112
|
+
" Validation was aborted.",
|
|
113
|
+
selection_set,
|
|
114
|
+
)
|
|
115
|
+
)
|
|
116
|
+
return
|
|
79
117
|
for (reason_name, reason), fields1, fields2 in conflicts:
|
|
80
118
|
reason_msg = reason_message(reason)
|
|
81
119
|
self.report_error(
|
|
@@ -544,6 +582,12 @@ def find_conflict(
|
|
|
544
582
|
Determines if there is a conflict between two particular fields, including comparing
|
|
545
583
|
their sub-fields.
|
|
546
584
|
"""
|
|
585
|
+
# Charge this comparison against the document-wide budget and abort validation once
|
|
586
|
+
# it is exhausted, guarding against quadratic-blowup denial of service.
|
|
587
|
+
compared_fields_and_fragment_pairs.comparisons += 1
|
|
588
|
+
if compared_fields_and_fragment_pairs.comparisons > MAX_FIELD_COMPARISONS:
|
|
589
|
+
raise ComparisonBudgetExceededError
|
|
590
|
+
|
|
547
591
|
parent_type1, node1, def1 = field1
|
|
548
592
|
parent_type2, node2, def2 = field2
|
|
549
593
|
|
|
@@ -780,14 +824,19 @@ class OrderedPairSet:
|
|
|
780
824
|
|
|
781
825
|
The first element is matched by object identity (its ``id``), since field maps
|
|
782
826
|
are unhashable mappings that are kept alive for the duration of the validation.
|
|
827
|
+
|
|
828
|
+
Also carries a running count of the pairwise field comparisons performed with
|
|
829
|
+
this set, used to enforce the OverlappingFieldsCanBeMerged comparison budget.
|
|
783
830
|
"""
|
|
784
831
|
|
|
785
|
-
__slots__ = ("_data",)
|
|
832
|
+
__slots__ = ("_data", "comparisons")
|
|
786
833
|
|
|
787
834
|
_data: Dict[int, Dict[str, bool]]
|
|
835
|
+
comparisons: int
|
|
788
836
|
|
|
789
837
|
def __init__(self) -> None:
|
|
790
838
|
self._data = {}
|
|
839
|
+
self.comparisons = 0
|
|
791
840
|
|
|
792
841
|
def has(self, a: NodeAndDefCollection, b: str, weakly_present: bool) -> bool:
|
|
793
842
|
map_ = self._data.get(id(a))
|
|
@@ -4,9 +4,9 @@ from typing import NamedTuple
|
|
|
4
4
|
__all__ = ["version", "version_info", "version_js", "version_info_js"]
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
version = "3.2.
|
|
7
|
+
version = "3.2.12"
|
|
8
8
|
|
|
9
|
-
version_js = "16.14.
|
|
9
|
+
version_js = "16.14.2"
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
_re_version = re.compile(r"(\d+)\.(\d+)\.(\d+)(\D*)(\d*)")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphql-core
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.12
|
|
4
4
|
Summary: GraphQL implementation for Python, a port of GraphQL.js, the JavaScript reference implementation for GraphQL.
|
|
5
5
|
Home-page: https://github.com/graphql-python/graphql-core
|
|
6
6
|
Author: Christoph Zwerschke
|
|
@@ -50,7 +50,7 @@ a query language for APIs created by Facebook.
|
|
|
50
50
|

|
|
51
51
|
[](https://github.com/ambv/black)
|
|
52
52
|
|
|
53
|
-
The current version 3.2.
|
|
53
|
+
The current version 3.2.12 of GraphQL-core is up-to-date with GraphQL.js version 16.14.2.
|
|
54
54
|
|
|
55
55
|
An extensive test suite with over 2500 unit tests and 100% coverage comprises a
|
|
56
56
|
replication of the complete test suite of GraphQL.js, making sure this port is
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from inspect import isawaitable
|
|
2
|
-
from typing import Any, NamedTuple, Optional
|
|
2
|
+
from typing import Any, Callable, NamedTuple, Optional
|
|
3
3
|
|
|
4
4
|
from pytest import mark
|
|
5
5
|
|
|
@@ -49,6 +49,7 @@ async def execute_query(
|
|
|
49
49
|
|
|
50
50
|
def get_is_type_of(type_, sync=True):
|
|
51
51
|
"""Get a sync or async is_type_of function for the given type."""
|
|
52
|
+
is_type_of: Callable[[Any, Any], Any]
|
|
52
53
|
if sync:
|
|
53
54
|
|
|
54
55
|
def is_type_of(obj, _info):
|
|
@@ -65,6 +66,7 @@ def get_is_type_of(type_, sync=True):
|
|
|
65
66
|
def get_type_error(sync=True):
|
|
66
67
|
"""Get a sync or async is_type_of or type resolver function that raises an error."""
|
|
67
68
|
error = RuntimeError("We are testing this error")
|
|
69
|
+
type_error: Callable[..., Any]
|
|
68
70
|
if sync:
|
|
69
71
|
|
|
70
72
|
def type_error(*_args):
|
|
@@ -116,6 +116,35 @@ def describe_parser():
|
|
|
116
116
|
):
|
|
117
117
|
assert parse('{ foo(bar: "baz") }', max_tokens=7)
|
|
118
118
|
|
|
119
|
+
def counts_comment_tokens_towards_the_maximum():
|
|
120
|
+
# Comment tokens are read and allocated by the lexer but skipped over; they
|
|
121
|
+
# must still count towards max_tokens, otherwise a comment-padded document
|
|
122
|
+
# bypasses the limit (memory-exhaustion DoS) while allocating one token per
|
|
123
|
+
# comment. token_count reflects the comments too.
|
|
124
|
+
assert parse("{ # comment\n foo }").token_count == 4
|
|
125
|
+
assert parse("# leading\n{ foo }\n# trailing").token_count == 5
|
|
126
|
+
|
|
127
|
+
# An interspersed comment pushes the document over the limit.
|
|
128
|
+
parse("{ # c\n foo }", max_tokens=4)
|
|
129
|
+
with raises(
|
|
130
|
+
GraphQLSyntaxError,
|
|
131
|
+
match="Syntax Error:"
|
|
132
|
+
r" Document contains more than 3 tokens\. Parsing aborted\.",
|
|
133
|
+
):
|
|
134
|
+
parse("{ # c\n foo }", max_tokens=3)
|
|
135
|
+
|
|
136
|
+
# Neither leading nor trailing comment padding can bypass the limit.
|
|
137
|
+
with raises(
|
|
138
|
+
GraphQLSyntaxError,
|
|
139
|
+
match=r"Document contains more than 5 tokens\. Parsing aborted\.",
|
|
140
|
+
):
|
|
141
|
+
parse("# c\n" * 1000 + "{ a }", max_tokens=5)
|
|
142
|
+
with raises(
|
|
143
|
+
GraphQLSyntaxError,
|
|
144
|
+
match=r"Document contains more than 5 tokens\. Parsing aborted\.",
|
|
145
|
+
):
|
|
146
|
+
parse("{ a }" + "\n# c" * 1000, max_tokens=5)
|
|
147
|
+
|
|
119
148
|
def parses_variable_inline_values():
|
|
120
149
|
parse("{ field(complex: { a: { b: [ $var ] } }) }")
|
|
121
150
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
from contextlib import contextmanager
|
|
1
2
|
from functools import partial
|
|
2
3
|
|
|
3
4
|
from graphql.utilities import build_schema
|
|
4
5
|
from graphql.validation import OverlappingFieldsCanBeMergedRule
|
|
6
|
+
from graphql.validation.rules import (
|
|
7
|
+
overlapping_fields_can_be_merged as overlapping_module,
|
|
8
|
+
)
|
|
5
9
|
|
|
6
10
|
from .harness import assert_validation_errors
|
|
7
11
|
|
|
@@ -9,6 +13,30 @@ assert_errors = partial(assert_validation_errors, OverlappingFieldsCanBeMergedRu
|
|
|
9
13
|
|
|
10
14
|
assert_valid = partial(assert_errors, errors=[])
|
|
11
15
|
|
|
16
|
+
budget_schema = build_schema("""
|
|
17
|
+
type Query {
|
|
18
|
+
field: Node
|
|
19
|
+
other: Node
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type Node {
|
|
23
|
+
f: Node
|
|
24
|
+
x: String
|
|
25
|
+
}
|
|
26
|
+
""")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@contextmanager
|
|
30
|
+
def budget_of(limit):
|
|
31
|
+
# Temporarily lower the module-level comparison budget so the budget tests can
|
|
32
|
+
# trigger the guard with small, fast queries.
|
|
33
|
+
saved = overlapping_module.MAX_FIELD_COMPARISONS
|
|
34
|
+
overlapping_module.MAX_FIELD_COMPARISONS = limit
|
|
35
|
+
try:
|
|
36
|
+
yield
|
|
37
|
+
finally:
|
|
38
|
+
overlapping_module.MAX_FIELD_COMPARISONS = saved
|
|
39
|
+
|
|
12
40
|
|
|
13
41
|
def describe_validate_overlapping_fields_can_be_merged():
|
|
14
42
|
def unique_fields():
|
|
@@ -1193,3 +1221,66 @@ def describe_validate_overlapping_fields_can_be_merged():
|
|
|
1193
1221
|
}
|
|
1194
1222
|
}
|
|
1195
1223
|
""")
|
|
1224
|
+
|
|
1225
|
+
def describe_comparison_budget():
|
|
1226
|
+
def aborts_validation_when_the_comparison_budget_is_exceeded():
|
|
1227
|
+
# Repeated inline fragments select the same response name, forcing O(n^2)
|
|
1228
|
+
# pairwise comparisons. Once the budget is exhausted the rule aborts with
|
|
1229
|
+
# a single error instead of running the comparison to completion. The
|
|
1230
|
+
# trailing `other` selection set is visited after the abort and must be
|
|
1231
|
+
# skipped, so exactly one error is reported for the whole document.
|
|
1232
|
+
query = (
|
|
1233
|
+
"{ field { " + " ".join(["... on Node { x }"] * 10) + " } other { x } }"
|
|
1234
|
+
)
|
|
1235
|
+
with budget_of(5):
|
|
1236
|
+
assert_errors(
|
|
1237
|
+
query,
|
|
1238
|
+
[
|
|
1239
|
+
{
|
|
1240
|
+
"message": "Query is too complex to validate for"
|
|
1241
|
+
" overlapping fields: exceeded 5 field comparisons."
|
|
1242
|
+
" Validation was aborted."
|
|
1243
|
+
}
|
|
1244
|
+
],
|
|
1245
|
+
schema=budget_schema,
|
|
1246
|
+
)
|
|
1247
|
+
|
|
1248
|
+
def deduplication_alone_would_not_bound_this_query():
|
|
1249
|
+
# Each `f` selection shares the response name `f` but wraps a distinct
|
|
1250
|
+
# sub-selection (`a0: x`, `a1: x`, ...), so every field has a distinct
|
|
1251
|
+
# structural fingerprint and none conflicts with another (differing
|
|
1252
|
+
# aliases merge cleanly). A fix based purely on deduplicating structurally
|
|
1253
|
+
# identical fields cannot remove any of these, so it would still perform
|
|
1254
|
+
# O(n^2) comparisons; the comparison budget bounds the work regardless.
|
|
1255
|
+
query = (
|
|
1256
|
+
"{ field { "
|
|
1257
|
+
+ " ".join(f"... on Node {{ f {{ a{i}: x }} }}" for i in range(20))
|
|
1258
|
+
+ " } }"
|
|
1259
|
+
)
|
|
1260
|
+
# With a generous budget the query is valid, proving the fields do not
|
|
1261
|
+
# conflict and that no deduplication pass could collapse them.
|
|
1262
|
+
with budget_of(1_000_000):
|
|
1263
|
+
assert_valid(query, schema=budget_schema)
|
|
1264
|
+
# With a small budget the same query is aborted rather than validated in
|
|
1265
|
+
# quadratic time.
|
|
1266
|
+
with budget_of(10):
|
|
1267
|
+
assert_errors(
|
|
1268
|
+
query,
|
|
1269
|
+
[
|
|
1270
|
+
{
|
|
1271
|
+
"message": "Query is too complex to validate for"
|
|
1272
|
+
" overlapping fields: exceeded 10 field comparisons."
|
|
1273
|
+
" Validation was aborted."
|
|
1274
|
+
}
|
|
1275
|
+
],
|
|
1276
|
+
schema=budget_schema,
|
|
1277
|
+
)
|
|
1278
|
+
|
|
1279
|
+
def does_not_abort_queries_that_stay_within_the_budget():
|
|
1280
|
+
# A valid overlapping query well under the budget validates normally, with
|
|
1281
|
+
# no spurious abort error.
|
|
1282
|
+
with budget_of(50):
|
|
1283
|
+
assert_valid(
|
|
1284
|
+
"{ field { ... on Node { x } ... on Node { x } } }",
|
|
1285
|
+
schema=budget_schema,
|
|
1286
|
+
)
|
|
@@ -33,8 +33,8 @@ commands =
|
|
|
33
33
|
[testenv:mypy]
|
|
34
34
|
basepython = python3.14
|
|
35
35
|
deps =
|
|
36
|
-
mypy>=2.
|
|
37
|
-
pytest>=8.4,<
|
|
36
|
+
mypy>=2.3,<3
|
|
37
|
+
pytest>=8.4,<10
|
|
38
38
|
commands =
|
|
39
39
|
mypy src tests
|
|
40
40
|
|
|
@@ -54,8 +54,8 @@ commands =
|
|
|
54
54
|
|
|
55
55
|
[testenv]
|
|
56
56
|
deps =
|
|
57
|
-
pytest>=7.4,<
|
|
58
|
-
pytest-asyncio>=0.21,<
|
|
57
|
+
pytest>=7.4,<10
|
|
58
|
+
pytest-asyncio>=0.21,<2
|
|
59
59
|
pytest-benchmark>=4.0,<6
|
|
60
60
|
pytest-cov>=4.1,<8
|
|
61
61
|
pytest-describe>=2,<4
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|