1- from typing import Any , Dict
1+ from operator import attrgetter
2+ from typing import Any , Collection
23
34from ...error import GraphQLError
4- from ...language import ArgumentNode , NameNode , VisitorAction , SKIP
5- from . import ASTValidationContext , ASTValidationRule
5+ from ...language import ArgumentNode , DirectiveNode , FieldNode
6+ from ...pyutils import group_by
7+ from . import ASTValidationRule
68
79__all__ = ["UniqueArgumentNamesRule" ]
810
@@ -16,26 +18,20 @@ class UniqueArgumentNamesRule(ASTValidationRule):
1618 See https://spec.graphql.org/draft/#sec-Argument-Names
1719 """
1820
19- def __init__ (self , context : ASTValidationContext ):
20- super ().__init__ (context )
21- self .known_arg_names : Dict [str , NameNode ] = {}
21+ def enter_field (self , node : FieldNode , * _args : Any ) -> None :
22+ self .check_arg_uniqueness (node .arguments )
2223
23- def enter_field (self , * _args : Any ) -> None :
24- self .known_arg_names . clear ( )
24+ def enter_directive (self , node : DirectiveNode , * args : Any ) -> None :
25+ self .check_arg_uniqueness ( node . arguments )
2526
26- def enter_directive (self , * _args : Any ) -> None :
27- self . known_arg_names . clear ( )
27+ def check_arg_uniqueness (self , argument_nodes : Collection [ ArgumentNode ] ) -> None :
28+ seen_args = group_by ( argument_nodes , attrgetter ( "name.value" ) )
2829
29- def enter_argument (self , node : ArgumentNode , * _args : Any ) -> VisitorAction :
30- known_arg_names = self .known_arg_names
31- arg_name = node .name .value
32- if arg_name in known_arg_names :
33- self .report_error (
34- GraphQLError (
35- f"There can be only one argument named '{ arg_name } '." ,
36- [known_arg_names [arg_name ], node .name ],
30+ for arg_name , arg_nodes in seen_args .items ():
31+ if len (arg_nodes ) > 1 :
32+ self .report_error (
33+ GraphQLError (
34+ f"There can be only one argument named '{ arg_name } '." ,
35+ [node .name for node in arg_nodes ],
36+ )
3737 )
38- )
39- else :
40- known_arg_names [arg_name ] = node .name
41- return SKIP
0 commit comments