Skip to content

Commit e905b6a

Browse files
committed
Validation: Remove internal functions for error messages
Replicates graphql/graphql-js@5d28d35 and graphql/graphql-js@58e2f5f
1 parent 5eddf8f commit e905b6a

File tree

69 files changed

+2163
-1413
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+2163
-1413
lines changed

docs/usage/validator.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ In this case, we will get::
3131
" Did you mean 'homePlanet'?",
3232
locations=[SourceLocation(line=5, column=9)]),
3333
GraphQLError(
34-
"Field 'friends' of type '[Character]' must have a sub selection of subfields."
34+
"Field 'friends' of type '[Character]' must have a selection of subfields."
3535
" Did you mean 'friends { ... }'?",
3636
locations=[SourceLocation(line=6, column=9)])]
3737

src/graphql/validation/rules/executable_definitions.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@
1111
)
1212
from . import ASTValidationRule
1313

14-
__all__ = ["ExecutableDefinitionsRule", "non_executable_definitions_message"]
15-
16-
17-
def non_executable_definitions_message(def_name: str) -> str:
18-
return f"The {def_name} definition is not executable."
14+
__all__ = ["ExecutableDefinitionsRule"]
1915

2016

2117
class ExecutableDefinitionsRule(ASTValidationRule):
@@ -28,19 +24,18 @@ class ExecutableDefinitionsRule(ASTValidationRule):
2824
def enter_document(self, node: DocumentNode, *_args):
2925
for definition in node.definitions:
3026
if not isinstance(definition, ExecutableDefinitionNode):
27+
def_name = (
28+
"schema"
29+
if isinstance(
30+
definition, (SchemaDefinitionNode, SchemaExtensionNode)
31+
)
32+
else cast(
33+
Union[DirectiveDefinitionNode, TypeDefinitionNode], definition,
34+
).name.value
35+
)
3136
self.report_error(
3237
GraphQLError(
33-
non_executable_definitions_message(
34-
"schema"
35-
if isinstance(
36-
definition, (SchemaDefinitionNode, SchemaExtensionNode)
37-
)
38-
else cast(
39-
Union[DirectiveDefinitionNode, TypeDefinitionNode],
40-
definition,
41-
).name.value
42-
),
43-
definition,
38+
f"The {def_name} definition is not executable.", definition,
4439
)
4540
)
4641
return self.SKIP

src/graphql/validation/rules/fields_on_correct_type.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,7 @@
1414
from ...pyutils import did_you_mean, suggestion_list
1515
from . import ValidationRule
1616

17-
__all__ = ["FieldsOnCorrectTypeRule", "undefined_field_message"]
18-
19-
20-
def undefined_field_message(
21-
field_name: str,
22-
type_: str,
23-
suggested_type_names: List[str],
24-
suggested_field_names: List[str],
25-
) -> str:
26-
hint = did_you_mean(
27-
[f"'{s}'" for s in suggested_type_names], "to use an inline fragment on"
28-
) or did_you_mean([f"'{s}'" for s in suggested_field_names])
29-
return f"Cannot query field '{field_name}' on type '{type_}'.{hint}"
17+
__all__ = ["FieldsOnCorrectTypeRule"]
3018

3119

3220
class FieldsOnCorrectTypeRule(ValidationRule):
@@ -54,10 +42,14 @@ def enter_field(self, node: FieldNode, *_args):
5442
)
5543

5644
# Report an error, including helpful suggestions.
45+
quoted_type_names = [f"'{s}'" for s in suggested_type_names]
46+
quoted_field_names = [f"'{s}'" for s in suggested_field_names]
5747
self.report_error(
5848
GraphQLError(
59-
undefined_field_message(
60-
field_name, type_.name, suggested_type_names, suggested_field_names
49+
f"Cannot query field '{field_name}' on type '{type_}'."
50+
+ (
51+
did_you_mean(quoted_type_names, "to use an inline fragment on")
52+
or did_you_mean(quoted_field_names)
6153
),
6254
node,
6355
)

src/graphql/validation/rules/fragments_on_composite_types.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,7 @@
44
from ...utilities import type_from_ast
55
from . import ValidationRule
66

7-
__all__ = [
8-
"FragmentsOnCompositeTypesRule",
9-
"inline_fragment_on_non_composite_error_message",
10-
"fragment_on_non_composite_error_message",
11-
]
12-
13-
14-
def inline_fragment_on_non_composite_error_message(type_: str) -> str:
15-
return f"Fragment cannot condition on non composite type '{type_}'."
16-
17-
18-
def fragment_on_non_composite_error_message(frag_name: str, type_: str) -> str:
19-
return f"Fragment '{frag_name}' cannot condition on non composite type '{type_}'."
7+
__all__ = ["FragmentsOnCompositeTypesRule"]
208

219

2210
class FragmentsOnCompositeTypesRule(ValidationRule):
@@ -32,11 +20,11 @@ def enter_inline_fragment(self, node: InlineFragmentNode, *_args):
3220
if type_condition:
3321
type_ = type_from_ast(self.context.schema, type_condition)
3422
if type_ and not is_composite_type(type_):
23+
type_str = print_ast(type_condition)
3524
self.report_error(
3625
GraphQLError(
37-
inline_fragment_on_non_composite_error_message(
38-
print_ast(type_condition)
39-
),
26+
"Fragment cannot condition"
27+
f" on non composite type '{type_str}'.",
4028
type_condition,
4129
)
4230
)
@@ -45,11 +33,11 @@ def enter_fragment_definition(self, node: FragmentDefinitionNode, *_args):
4533
type_condition = node.type_condition
4634
type_ = type_from_ast(self.context.schema, type_condition)
4735
if type_ and not is_composite_type(type_):
36+
type_str = print_ast(type_condition)
4837
self.report_error(
4938
GraphQLError(
50-
fragment_on_non_composite_error_message(
51-
node.name.value, print_ast(type_condition)
52-
),
39+
f"Fragment '{node.name.value}' cannot condition"
40+
f" on non composite type '{type_str}'.",
5341
type_condition,
5442
)
5543
)

src/graphql/validation/rules/known_argument_names.py

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,7 @@
66
from ...type import specified_directives
77
from . import ASTValidationRule, SDLValidationContext, ValidationContext
88

9-
__all__ = [
10-
"KnownArgumentNamesRule",
11-
"KnownArgumentNamesOnDirectivesRule",
12-
"unknown_arg_message",
13-
"unknown_directive_arg_message",
14-
]
15-
16-
17-
def unknown_arg_message(
18-
arg_name: str, field_name: str, type_name: str, suggested_args: List[str]
19-
) -> str:
20-
hint = did_you_mean([f"'{s}'" for s in suggested_args])
21-
return (
22-
f"Unknown argument '{arg_name}' on field '{field_name}'"
23-
f" of type '{type_name}'.{hint}"
24-
)
25-
26-
27-
def unknown_directive_arg_message(
28-
arg_name: str, directive_name: str, suggested_args: List[str]
29-
) -> str:
30-
hint = did_you_mean([f"'{s}'" for s in suggested_args])
31-
return f"Unknown argument '{arg_name}' on directive '@{directive_name}'. {hint}"
9+
__all__ = ["KnownArgumentNamesRule", "KnownArgumentNamesOnDirectivesRule"]
3210

3311

3412
class KnownArgumentNamesOnDirectivesRule(ASTValidationRule):
@@ -67,9 +45,9 @@ def enter_directive(self, directive_node: DirectiveNode, *_args):
6745
suggestions = suggestion_list(arg_name, known_args)
6846
self.report_error(
6947
GraphQLError(
70-
unknown_directive_arg_message(
71-
arg_name, directive_name, suggestions
72-
),
48+
f"Unknown argument '{arg_name}'"
49+
f" on directive '@{directive_name}'."
50+
+ did_you_mean([f"'{s}'" for s in suggestions]),
7351
arg_node,
7452
)
7553
)
@@ -96,14 +74,12 @@ def enter_argument(self, arg_node: ArgumentNode, *args):
9674
arg_name = arg_node.name.value
9775
field_name = args[3][-1].name.value
9876
known_args_names = list(field_def.args)
77+
suggestions = suggestion_list(arg_name, known_args_names)
9978
context.report_error(
10079
GraphQLError(
101-
unknown_arg_message(
102-
arg_name,
103-
field_name,
104-
parent_type.name,
105-
suggestion_list(arg_name, known_args_names),
106-
),
80+
f"Unknown argument '{arg_name}' on field '{field_name}'"
81+
f" of type '{parent_type.name}'."
82+
+ did_you_mean([f"'{s}'" for s in suggestions]),
10783
arg_node,
10884
)
10985
)

src/graphql/validation/rules/known_directives.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,7 @@
1111
from ...type import specified_directives
1212
from . import ASTValidationRule, SDLValidationContext, ValidationContext
1313

14-
__all__ = [
15-
"KnownDirectivesRule",
16-
"unknown_directive_message",
17-
"misplaced_directive_message",
18-
]
19-
20-
21-
def unknown_directive_message(directive_name: str) -> str:
22-
return f"Unknown directive '{directive_name}'."
23-
24-
25-
def misplaced_directive_message(directive_name: str, location: str) -> str:
26-
return f"Directive '{directive_name}' may not be used on {location}."
14+
__all__ = ["KnownDirectivesRule"]
2715

2816

2917
class KnownDirectivesRule(ASTValidationRule):
@@ -61,16 +49,13 @@ def enter_directive(self, node: DirectiveNode, _key, _parent, _path, ancestors):
6149
if candidate_location and candidate_location not in locations:
6250
self.report_error(
6351
GraphQLError(
64-
misplaced_directive_message(
65-
node.name.value, candidate_location.value
66-
),
52+
f"Directive '{name}'"
53+
f" may not be used on {candidate_location.value}.",
6754
node,
6855
)
6956
)
7057
else:
71-
self.report_error(
72-
GraphQLError(unknown_directive_message(node.name.value), node)
73-
)
58+
self.report_error(GraphQLError(f"Unknown directive '{name}'.", node))
7459

7560

7661
_operation_location = {

src/graphql/validation/rules/known_fragment_names.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22
from ...language import FragmentSpreadNode
33
from . import ValidationRule
44

5-
__all__ = ["KnownFragmentNamesRule", "unknown_fragment_message"]
6-
7-
8-
def unknown_fragment_message(fragment_name: str) -> str:
9-
return f"Unknown fragment '{fragment_name}'."
5+
__all__ = ["KnownFragmentNamesRule"]
106

117

128
class KnownFragmentNamesRule(ValidationRule):
@@ -21,5 +17,5 @@ def enter_fragment_spread(self, node: FragmentSpreadNode, *_args):
2117
fragment = self.context.get_fragment(fragment_name)
2218
if not fragment:
2319
self.report_error(
24-
GraphQLError(unknown_fragment_message(fragment_name), node.name)
20+
GraphQLError(f"Unknown fragment '{fragment_name}'.", node.name)
2521
)

src/graphql/validation/rules/known_type_names.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,7 @@
1313
from ...pyutils import did_you_mean, suggestion_list
1414
from . import ASTValidationRule, ValidationContext, SDLValidationContext
1515

16-
__all__ = ["KnownTypeNamesRule", "unknown_type_message"]
17-
18-
19-
def unknown_type_message(type_name: str, suggested_types: List[str]) -> str:
20-
hint = did_you_mean([f"'{s}'" for s in suggested_types])
21-
return f"Unknown type '{type_name}'.{hint}"
16+
__all__ = ["KnownTypeNamesRule"]
2217

2318

2419
class KnownTypeNamesRule(ASTValidationRule):
@@ -65,7 +60,11 @@ def enter_named_type(
6560
else self.type_names,
6661
)
6762
self.report_error(
68-
GraphQLError(unknown_type_message(type_name, suggested_types), node)
63+
GraphQLError(
64+
f"Unknown type '{type_name}'."
65+
+ did_you_mean([f"'{s}'" for s in suggested_types]),
66+
node,
67+
)
6968
)
7069

7170

src/graphql/validation/rules/lone_anonymous_operation.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22
from ...language import DocumentNode, OperationDefinitionNode
33
from . import ASTValidationContext, ASTValidationRule
44

5-
__all__ = ["LoneAnonymousOperationRule", "anonymous_operation_not_alone_message"]
6-
7-
8-
def anonymous_operation_not_alone_message() -> str:
9-
return "This anonymous operation must be the only defined operation."
5+
__all__ = ["LoneAnonymousOperationRule"]
106

117

128
class LoneAnonymousOperationRule(ASTValidationRule):
@@ -30,5 +26,7 @@ def enter_document(self, node: DocumentNode, *_args):
3026
def enter_operation_definition(self, node: OperationDefinitionNode, *_args):
3127
if not node.name and self.operation_count > 1:
3228
self.report_error(
33-
GraphQLError(anonymous_operation_not_alone_message(), node)
29+
GraphQLError(
30+
"This anonymous operation must be the only defined operation.", node
31+
)
3432
)

src/graphql/validation/rules/lone_schema_definition.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,7 @@
22
from ...language import SchemaDefinitionNode
33
from . import SDLValidationRule, SDLValidationContext
44

5-
__all__ = [
6-
"LoneSchemaDefinitionRule",
7-
"schema_definition_not_alone_message",
8-
"cannot_define_schema_within_extension_message",
9-
]
10-
11-
12-
def schema_definition_not_alone_message():
13-
return "Must provide only one schema definition."
14-
15-
16-
def cannot_define_schema_within_extension_message():
17-
return "Cannot define a new schema within a schema extension."
5+
__all__ = ["LoneSchemaDefinitionRule"]
186

197

208
class LoneSchemaDefinitionRule(SDLValidationRule):
@@ -37,11 +25,13 @@ def __init__(self, context: SDLValidationContext) -> None:
3725
def enter_schema_definition(self, node: SchemaDefinitionNode, *_args):
3826
if self.already_defined:
3927
self.report_error(
40-
GraphQLError(cannot_define_schema_within_extension_message(), node)
28+
GraphQLError(
29+
"Cannot define a new schema within a schema extension.", node
30+
)
4131
)
4232
else:
4333
if self.schema_definitions_count:
4434
self.report_error(
45-
GraphQLError(schema_definition_not_alone_message(), node)
35+
GraphQLError("Must provide only one schema definition.", node)
4636
)
4737
self.schema_definitions_count += 1

src/graphql/validation/rules/no_fragment_cycles.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@
44
from ...language import FragmentDefinitionNode, FragmentSpreadNode
55
from . import ASTValidationContext, ASTValidationRule
66

7-
__all__ = ["NoFragmentCyclesRule", "cycle_error_message"]
8-
9-
10-
def cycle_error_message(frag_name: str, spread_names: List[str]) -> str:
11-
via = f" via {', '.join(spread_names)}" if spread_names else ""
12-
return f"Cannot spread fragment '{frag_name}' within itself{via}."
7+
__all__ = ["NoFragmentCyclesRule"]
138

149

1510
class NoFragmentCyclesRule(ASTValidationRule):
@@ -63,10 +58,12 @@ def detect_cycle_recursive(self, fragment: FragmentDefinitionNode):
6358
self.detect_cycle_recursive(spread_fragment)
6459
else:
6560
cycle_path = spread_path[cycle_index:]
66-
fragment_names = [s.name.value for s in cycle_path[:-1]]
61+
via_names = [s.name.value for s in cycle_path[:-1]]
6762
self.report_error(
6863
GraphQLError(
69-
cycle_error_message(spread_name, fragment_names), cycle_path
64+
f"Cannot spread fragment '{spread_name}' within itself"
65+
+ (f" via {', '.join(via_names)}." if via_names else "."),
66+
cycle_path,
7067
)
7168
)
7269
spread_path.pop()

0 commit comments

Comments
 (0)