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.
Files changed (347) hide show
  1. {graphql_core-3.2.11 → graphql_core-3.2.12}/.bumpversion.cfg +3 -3
  2. {graphql_core-3.2.11 → graphql_core-3.2.12}/PKG-INFO +2 -2
  3. {graphql_core-3.2.11 → graphql_core-3.2.12}/README.md +1 -1
  4. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/conf.py +1 -1
  5. {graphql_core-3.2.11 → graphql_core-3.2.12}/pyproject.toml +2 -2
  6. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/parser.py +26 -11
  7. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/overlapping_fields_can_be_merged.py +59 -10
  8. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/version.py +2 -2
  9. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/PKG-INFO +2 -2
  10. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_abstract.py +3 -1
  11. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_parser.py +29 -0
  12. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_overlapping_fields_can_be_merged.py +91 -0
  13. {graphql_core-3.2.11 → graphql_core-3.2.12}/tox.ini +4 -4
  14. {graphql_core-3.2.11 → graphql_core-3.2.12}/.coveragerc +0 -0
  15. {graphql_core-3.2.11 → graphql_core-3.2.12}/.editorconfig +0 -0
  16. {graphql_core-3.2.11 → graphql_core-3.2.12}/.flake8 +0 -0
  17. {graphql_core-3.2.11 → graphql_core-3.2.12}/.mypy.ini +0 -0
  18. {graphql_core-3.2.11 → graphql_core-3.2.12}/.readthedocs.yaml +0 -0
  19. {graphql_core-3.2.11 → graphql_core-3.2.12}/CODEOWNERS +0 -0
  20. {graphql_core-3.2.11 → graphql_core-3.2.12}/LICENSE +0 -0
  21. {graphql_core-3.2.11 → graphql_core-3.2.12}/MANIFEST.in +0 -0
  22. {graphql_core-3.2.11 → graphql_core-3.2.12}/SECURITY.md +0 -0
  23. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/Makefile +0 -0
  24. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/diffs.rst +0 -0
  25. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/index.rst +0 -0
  26. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/intro.rst +0 -0
  27. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/make.bat +0 -0
  28. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/error.rst +0 -0
  29. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/execution.rst +0 -0
  30. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/graphql.rst +0 -0
  31. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/language.rst +0 -0
  32. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/pyutils.rst +0 -0
  33. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/type.rst +0 -0
  34. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/utilities.rst +0 -0
  35. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/modules/validation.rst +0 -0
  36. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/requirements.txt +0 -0
  37. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/extension.rst +0 -0
  38. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/index.rst +0 -0
  39. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/introspection.rst +0 -0
  40. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/methods.rst +0 -0
  41. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/other.rst +0 -0
  42. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/parser.rst +0 -0
  43. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/queries.rst +0 -0
  44. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/resolvers.rst +0 -0
  45. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/schema.rst +0 -0
  46. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/sdl.rst +0 -0
  47. {graphql_core-3.2.11 → graphql_core-3.2.12}/docs/usage/validator.rst +0 -0
  48. {graphql_core-3.2.11 → graphql_core-3.2.12}/poetry.lock +0 -0
  49. {graphql_core-3.2.11 → graphql_core-3.2.12}/setup.cfg +0 -0
  50. {graphql_core-3.2.11 → graphql_core-3.2.12}/setup.py +0 -0
  51. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/__init__.py +0 -0
  52. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/error/__init__.py +0 -0
  53. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/error/graphql_error.py +0 -0
  54. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/error/located_error.py +0 -0
  55. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/error/syntax_error.py +0 -0
  56. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/__init__.py +0 -0
  57. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/collect_fields.py +0 -0
  58. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/execute.py +0 -0
  59. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/map_async_iterator.py +0 -0
  60. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/middleware.py +0 -0
  61. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/subscribe.py +0 -0
  62. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/execution/values.py +0 -0
  63. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/graphql.py +0 -0
  64. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/__init__.py +0 -0
  65. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/ast.py +0 -0
  66. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/block_string.py +0 -0
  67. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/character_classes.py +0 -0
  68. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/directive_locations.py +0 -0
  69. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/lexer.py +0 -0
  70. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/location.py +0 -0
  71. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/predicates.py +0 -0
  72. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/print_location.py +0 -0
  73. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/print_string.py +0 -0
  74. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/printer.py +0 -0
  75. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/schema_coordinate_lexer.py +0 -0
  76. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/source.py +0 -0
  77. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/token_kind.py +0 -0
  78. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/language/visitor.py +0 -0
  79. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/py.typed +0 -0
  80. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/__init__.py +0 -0
  81. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/awaitable_or_value.py +0 -0
  82. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/cached_property.py +0 -0
  83. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/convert_case.py +0 -0
  84. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/description.py +0 -0
  85. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/did_you_mean.py +0 -0
  86. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/frozen_dict.py +0 -0
  87. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/frozen_error.py +0 -0
  88. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/frozen_list.py +0 -0
  89. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/group_by.py +0 -0
  90. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/identity_func.py +0 -0
  91. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/inspect.py +0 -0
  92. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/is_awaitable.py +0 -0
  93. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/is_iterable.py +0 -0
  94. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/merge_kwargs.py +0 -0
  95. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/natural_compare.py +0 -0
  96. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/path.py +0 -0
  97. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/print_path_list.py +0 -0
  98. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/simple_pub_sub.py +0 -0
  99. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/suggestion_list.py +0 -0
  100. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/pyutils/undefined.py +0 -0
  101. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/subscription/__init__.py +0 -0
  102. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/__init__.py +0 -0
  103. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/assert_name.py +0 -0
  104. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/definition.py +0 -0
  105. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/directives.py +0 -0
  106. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/introspection.py +0 -0
  107. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/scalars.py +0 -0
  108. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/schema.py +0 -0
  109. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/type/validate.py +0 -0
  110. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/__init__.py +0 -0
  111. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/assert_valid_name.py +0 -0
  112. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/ast_from_value.py +0 -0
  113. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/ast_to_dict.py +0 -0
  114. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/build_ast_schema.py +0 -0
  115. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/build_client_schema.py +0 -0
  116. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/coerce_input_value.py +0 -0
  117. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/concat_ast.py +0 -0
  118. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/extend_schema.py +0 -0
  119. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/find_breaking_changes.py +0 -0
  120. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/get_introspection_query.py +0 -0
  121. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/get_operation_ast.py +0 -0
  122. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/get_operation_root_type.py +0 -0
  123. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/introspection_from_schema.py +0 -0
  124. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/lexicographic_sort_schema.py +0 -0
  125. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/print_schema.py +0 -0
  126. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/resolve_schema_coordinate.py +0 -0
  127. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/separate_operations.py +0 -0
  128. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/sort_value_node.py +0 -0
  129. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/strip_ignored_characters.py +0 -0
  130. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/type_comparators.py +0 -0
  131. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/type_from_ast.py +0 -0
  132. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/type_info.py +0 -0
  133. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/value_from_ast.py +0 -0
  134. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/utilities/value_from_ast_untyped.py +0 -0
  135. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/__init__.py +0 -0
  136. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/__init__.py +0 -0
  137. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/custom/__init__.py +0 -0
  138. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/custom/no_deprecated.py +0 -0
  139. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/custom/no_schema_introspection.py +0 -0
  140. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/executable_definitions.py +0 -0
  141. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/fields_on_correct_type.py +0 -0
  142. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/fragments_on_composite_types.py +0 -0
  143. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/known_argument_names.py +0 -0
  144. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/known_directives.py +0 -0
  145. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/known_fragment_names.py +0 -0
  146. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/known_type_names.py +0 -0
  147. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/lone_anonymous_operation.py +0 -0
  148. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/lone_schema_definition.py +0 -0
  149. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/max_introspection_depth_rule.py +0 -0
  150. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/no_fragment_cycles.py +0 -0
  151. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/no_undefined_variables.py +0 -0
  152. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/no_unused_fragments.py +0 -0
  153. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/no_unused_variables.py +0 -0
  154. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/possible_fragment_spreads.py +0 -0
  155. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/possible_type_extensions.py +0 -0
  156. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/provided_required_arguments.py +0 -0
  157. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/scalar_leafs.py +0 -0
  158. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/single_field_subscriptions.py +0 -0
  159. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_argument_definition_names.py +0 -0
  160. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_argument_names.py +0 -0
  161. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_directive_names.py +0 -0
  162. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_directives_per_location.py +0 -0
  163. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_enum_value_names.py +0 -0
  164. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_field_definition_names.py +0 -0
  165. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_fragment_names.py +0 -0
  166. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_input_field_names.py +0 -0
  167. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_operation_names.py +0 -0
  168. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_operation_types.py +0 -0
  169. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_type_names.py +0 -0
  170. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/unique_variable_names.py +0 -0
  171. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/values_of_correct_type.py +0 -0
  172. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/variables_are_input_types.py +0 -0
  173. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/rules/variables_in_allowed_position.py +0 -0
  174. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/specified_rules.py +0 -0
  175. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/validate.py +0 -0
  176. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql/validation/validation_context.py +0 -0
  177. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/SOURCES.txt +0 -0
  178. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/dependency_links.txt +0 -0
  179. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/not-zip-safe +0 -0
  180. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/requires.txt +0 -0
  181. {graphql_core-3.2.11 → graphql_core-3.2.12}/src/graphql_core.egg-info/top_level.txt +0 -0
  182. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/__init__.py +0 -0
  183. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/__init__.py +0 -0
  184. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_build_ast_schema.py +0 -0
  185. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_build_client_schema.py +0 -0
  186. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_execution_async.py +0 -0
  187. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_execution_sync.py +0 -0
  188. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_introspection_from_schema.py +0 -0
  189. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_parser.py +0 -0
  190. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_print.py +0 -0
  191. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_repeated_fields.py +0 -0
  192. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_validate_gql.py +0 -0
  193. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_validate_invalid_gql.py +0 -0
  194. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_validate_sdl.py +0 -0
  195. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/benchmarks/test_visit.py +0 -0
  196. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/conftest.py +0 -0
  197. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/error/__init__.py +0 -0
  198. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/error/test_graphql_error.py +0 -0
  199. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/error/test_located_error.py +0 -0
  200. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/error/test_print_location.py +0 -0
  201. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/__init__.py +0 -0
  202. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_customize.py +0 -0
  203. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_directives.py +0 -0
  204. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_execution_result.py +0 -0
  205. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_executor.py +0 -0
  206. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_lists.py +0 -0
  207. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_map_async_iterator.py +0 -0
  208. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_middleware.py +0 -0
  209. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_mutations.py +0 -0
  210. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_nonnull.py +0 -0
  211. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_one_of.py +0 -0
  212. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_parallel.py +0 -0
  213. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_resolve.py +0 -0
  214. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_schema.py +0 -0
  215. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_subscribe.py +0 -0
  216. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_sync.py +0 -0
  217. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_union_interface.py +0 -0
  218. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/execution/test_variables.py +0 -0
  219. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/fixtures/__init__.py +0 -0
  220. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/fixtures/github_schema.graphql +0 -0
  221. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/fixtures/github_schema.json +0 -0
  222. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/fixtures/kitchen_sink.graphql +0 -0
  223. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/fixtures/schema_kitchen_sink.graphql +0 -0
  224. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/__init__.py +0 -0
  225. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_ast.py +0 -0
  226. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_block_string.py +0 -0
  227. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_block_string_fuzz.py +0 -0
  228. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_character_classes.py +0 -0
  229. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_lexer.py +0 -0
  230. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_location.py +0 -0
  231. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_predicates.py +0 -0
  232. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_print_string.py +0 -0
  233. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_printer.py +0 -0
  234. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_schema_coordinate_lexer.py +0 -0
  235. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_schema_parser.py +0 -0
  236. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_schema_printer.py +0 -0
  237. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_source.py +0 -0
  238. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/language/test_visitor.py +0 -0
  239. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/__init__.py +0 -0
  240. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_cached_property.py +0 -0
  241. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_convert_case.py +0 -0
  242. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_description.py +0 -0
  243. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_did_you_mean.py +0 -0
  244. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_frozen_dict.py +0 -0
  245. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_frozen_error.py +0 -0
  246. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_frozen_list.py +0 -0
  247. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_group_by.py +0 -0
  248. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_identity_func.py +0 -0
  249. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_inspect.py +0 -0
  250. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_is_awaitable.py +0 -0
  251. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_is_iterable.py +0 -0
  252. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_merge_kwargs.py +0 -0
  253. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_natural_compare.py +0 -0
  254. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_path.py +0 -0
  255. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_print_path_list.py +0 -0
  256. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_simple_pub_sub.py +0 -0
  257. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_suggestion_list.py +0 -0
  258. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/pyutils/test_undefined.py +0 -0
  259. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/star_wars_data.py +0 -0
  260. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/star_wars_schema.py +0 -0
  261. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_docs.py +0 -0
  262. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_star_wars_introspection.py +0 -0
  263. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_star_wars_query.py +0 -0
  264. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_star_wars_validation.py +0 -0
  265. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_user_registry.py +0 -0
  266. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/test_version.py +0 -0
  267. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/__init__.py +0 -0
  268. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_assert_name.py +0 -0
  269. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_custom_scalars.py +0 -0
  270. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_definition.py +0 -0
  271. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_directives.py +0 -0
  272. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_enum.py +0 -0
  273. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_extensions.py +0 -0
  274. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_introspection.py +0 -0
  275. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_predicate.py +0 -0
  276. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_scalars.py +0 -0
  277. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_schema.py +0 -0
  278. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/type/test_validation.py +0 -0
  279. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/__init__.py +0 -0
  280. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_ast_from_value.py +0 -0
  281. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_ast_to_dict.py +0 -0
  282. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_build_ast_schema.py +0 -0
  283. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_build_client_schema.py +0 -0
  284. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_coerce_input_value.py +0 -0
  285. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_concat_ast.py +0 -0
  286. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_extend_schema.py +0 -0
  287. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_find_breaking_changes.py +0 -0
  288. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_get_introspection_query.py +0 -0
  289. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_get_operation_ast.py +0 -0
  290. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_get_operation_root_type.py +0 -0
  291. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_introspection_from_schema.py +0 -0
  292. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_lexicographic_sort_schema.py +0 -0
  293. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_print_schema.py +0 -0
  294. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_resolve_schema_coordinate.py +0 -0
  295. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_separate_operations.py +0 -0
  296. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_sort_value_node.py +0 -0
  297. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_strip_ignored_characters.py +0 -0
  298. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_strip_ignored_characters_fuzz.py +0 -0
  299. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_type_comparators.py +0 -0
  300. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_type_from_ast.py +0 -0
  301. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_type_info.py +0 -0
  302. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_value_from_ast.py +0 -0
  303. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utilities/test_value_from_ast_untyped.py +0 -0
  304. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utils/__init__.py +0 -0
  305. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utils/dedent.py +0 -0
  306. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utils/gen_fuzz_strings.py +0 -0
  307. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utils/test_dedent.py +0 -0
  308. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/utils/test_gen_fuzz_strings.py +0 -0
  309. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/__init__.py +0 -0
  310. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/harness.py +0 -0
  311. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_executable_definitions.py +0 -0
  312. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_fields_on_correct_type.py +0 -0
  313. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_fragments_on_composite_types.py +0 -0
  314. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_known_argument_names.py +0 -0
  315. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_known_directives.py +0 -0
  316. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_known_fragment_names.py +0 -0
  317. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_known_type_names.py +0 -0
  318. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_lone_anonymous_operation.py +0 -0
  319. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_lone_schema_definition.py +0 -0
  320. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_max_introspection_depth_rule.py +0 -0
  321. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_deprecated.py +0 -0
  322. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_fragment_cycles.py +0 -0
  323. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_schema_introspection.py +0 -0
  324. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_undefined_variables.py +0 -0
  325. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_unused_fragments.py +0 -0
  326. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_no_unused_variables.py +0 -0
  327. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_possible_fragment_spreads.py +0 -0
  328. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_possible_type_extensions.py +0 -0
  329. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_provided_required_arguments.py +0 -0
  330. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_scalar_leafs.py +0 -0
  331. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_single_field_subscriptions.py +0 -0
  332. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_argument_definition_names.py +0 -0
  333. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_argument_names.py +0 -0
  334. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_directive_names.py +0 -0
  335. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_directives_per_location.py +0 -0
  336. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_enum_value_names.py +0 -0
  337. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_field_definition_names.py +0 -0
  338. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_fragment_names.py +0 -0
  339. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_input_field_names.py +0 -0
  340. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_operation_names.py +0 -0
  341. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_operation_types.py +0 -0
  342. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_type_names.py +0 -0
  343. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_unique_variable_names.py +0 -0
  344. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_validation.py +0 -0
  345. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_values_of_correct_type.py +0 -0
  346. {graphql_core-3.2.11 → graphql_core-3.2.12}/tests/validation/test_variables_are_input_types.py +0 -0
  347. {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.11
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 = '{current_version}'
12
- replace = version = release = '{new_version}'
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.11
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
  ![Lint Status](https://github.com/graphql-python/graphql-core/actions/workflows/lint.yml/badge.svg)
51
51
  [![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
52
52
 
53
- The current version 3.2.11 of GraphQL-core is up-to-date with GraphQL.js version 16.14.1.
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
  ![Lint Status](https://github.com/graphql-python/graphql-core/actions/workflows/lint.yml/badge.svg)
11
11
  [![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
12
12
 
13
- The current version 3.2.11 of GraphQL-core is up-to-date with GraphQL.js version 16.14.1.
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.11"
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.11"
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,<83"]
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
- token = self._lexer.advance()
1359
-
1360
- if token.kind != TokenKind.EOF:
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
- max_tokens = self._max_tokens
1363
- if max_tokens is not None and self._token_counter > max_tokens:
1364
- raise GraphQLSyntaxError(
1365
- self._lexer.source,
1366
- token.start,
1367
- f"Document contains more than {max_tokens} tokens."
1368
- " Parsing aborted.",
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
- conflicts = find_conflicts_within_selection_set(
72
- self.context,
73
- self.cached_fields_and_fragment_names,
74
- self.compared_fields_and_fragment_pairs,
75
- self.compared_fragment_pairs,
76
- self.context.get_parent_type(),
77
- selection_set,
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.11"
7
+ version = "3.2.12"
8
8
 
9
- version_js = "16.14.1"
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.11
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
  ![Lint Status](https://github.com/graphql-python/graphql-core/actions/workflows/lint.yml/badge.svg)
51
51
  [![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
52
52
 
53
- The current version 3.2.11 of GraphQL-core is up-to-date with GraphQL.js version 16.14.1.
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.1,<3
37
- pytest>=8.4,<9
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,<9
58
- pytest-asyncio>=0.21,<1
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