1- from typing import Callable , Dict , List , Optional , Union , cast
1+ from typing import Callable , Dict , List , Optional , Union , TypeVar , cast
22from functools import partial
33
44from .ast import (
3030 Location ,
3131 NameNode ,
3232 NamedTypeNode ,
33- Node ,
3433 NonNullTypeNode ,
3534 NullValueNode ,
3635 ObjectFieldNode ,
6665
6766__all__ = ["parse" , "parse_type" , "parse_value" ]
6867
68+ T = TypeVar ("T" )
69+
6970SourceType = Union [Source , str ]
7071
7172
@@ -267,15 +268,8 @@ def parse_operation_type(self) -> OperationType:
267268
268269 def parse_variable_definitions (self ) -> List [VariableDefinitionNode ]:
269270 """VariableDefinitions: (VariableDefinition+)"""
270- return (
271- cast (
272- List [VariableDefinitionNode ],
273- self .many (
274- TokenKind .PAREN_L , self .parse_variable_definition , TokenKind .PAREN_R
275- ),
276- )
277- if self .peek (TokenKind .PAREN_L )
278- else []
271+ return self .optional_many (
272+ TokenKind .PAREN_L , self .parse_variable_definition , TokenKind .PAREN_R
279273 )
280274
281275 def parse_variable_definition (self ) -> VariableDefinitionNode :
@@ -337,14 +331,7 @@ def parse_field(self) -> FieldNode:
337331 def parse_arguments (self , is_const : bool ) -> List [ArgumentNode ]:
338332 """Arguments[Const]: (Argument[?Const]+)"""
339333 item = self .parse_const_argument if is_const else self .parse_argument
340- return (
341- cast (
342- List [ArgumentNode ],
343- self .many (TokenKind .PAREN_L , item , TokenKind .PAREN_R ),
344- )
345- if self .peek (TokenKind .PAREN_L )
346- else []
347- )
334+ return self .optional_many (TokenKind .PAREN_L , item , TokenKind .PAREN_R )
348335
349336 def parse_argument (self ) -> ArgumentNode :
350337 """Argument: Name : Value"""
@@ -671,15 +658,8 @@ def parse_implements_interfaces(self) -> List[NamedTypeNode]:
671658
672659 def parse_fields_definition (self ) -> List [FieldDefinitionNode ]:
673660 """FieldsDefinition: {FieldDefinition+}"""
674- return (
675- cast (
676- List [FieldDefinitionNode ],
677- self .many (
678- TokenKind .BRACE_L , self .parse_field_definition , TokenKind .BRACE_R
679- ),
680- )
681- if self .peek (TokenKind .BRACE_L )
682- else []
661+ return self .optional_many (
662+ TokenKind .BRACE_L , self .parse_field_definition , TokenKind .BRACE_R
683663 )
684664
685665 def parse_field_definition (self ) -> FieldDefinitionNode :
@@ -702,15 +682,8 @@ def parse_field_definition(self) -> FieldDefinitionNode:
702682
703683 def parse_argument_defs (self ) -> List [InputValueDefinitionNode ]:
704684 """ArgumentsDefinition: (InputValueDefinition+)"""
705- return (
706- cast (
707- List [InputValueDefinitionNode ],
708- self .many (
709- TokenKind .PAREN_L , self .parse_input_value_def , TokenKind .PAREN_R
710- ),
711- )
712- if self .peek (TokenKind .PAREN_L )
713- else []
685+ return self .optional_many (
686+ TokenKind .PAREN_L , self .parse_input_value_def , TokenKind .PAREN_R
714687 )
715688
716689 def parse_input_value_def (self ) -> InputValueDefinitionNode :
@@ -798,17 +771,8 @@ def parse_enum_type_definition(self) -> EnumTypeDefinitionNode:
798771
799772 def parse_enum_values_definition (self ) -> List [EnumValueDefinitionNode ]:
800773 """EnumValuesDefinition: {EnumValueDefinition+}"""
801- return (
802- cast (
803- List [EnumValueDefinitionNode ],
804- self .many (
805- TokenKind .BRACE_L ,
806- self .parse_enum_value_definition ,
807- TokenKind .BRACE_R ,
808- ),
809- )
810- if self .peek (TokenKind .BRACE_L )
811- else []
774+ return self .optional_many (
775+ TokenKind .BRACE_L , self .parse_enum_value_definition , TokenKind .BRACE_R
812776 )
813777
814778 def parse_enum_value_definition (self ) -> EnumValueDefinitionNode :
@@ -842,15 +806,8 @@ def parse_input_object_type_definition(self) -> InputObjectTypeDefinitionNode:
842806
843807 def parse_input_fields_definition (self ) -> List [InputValueDefinitionNode ]:
844808 """InputFieldsDefinition: {InputValueDefinition+}"""
845- return (
846- cast (
847- List [InputValueDefinitionNode ],
848- self .many (
849- TokenKind .BRACE_L , self .parse_input_value_def , TokenKind .BRACE_R
850- ),
851- )
852- if self .peek (TokenKind .BRACE_L )
853- else []
809+ return self .optional_many (
810+ TokenKind .BRACE_L , self .parse_input_value_def , TokenKind .BRACE_R
854811 )
855812
856813 def parse_schema_extension (self ) -> SchemaExtensionNode :
@@ -859,14 +816,8 @@ def parse_schema_extension(self) -> SchemaExtensionNode:
859816 self .expect_keyword ("extend" )
860817 self .expect_keyword ("schema" )
861818 directives = self .parse_directives (True )
862- operation_types = (
863- self .many (
864- TokenKind .BRACE_L ,
865- self .parse_operation_type_definition ,
866- TokenKind .BRACE_R ,
867- )
868- if self .peek (TokenKind .BRACE_L )
869- else []
819+ operation_types = self .optional_many (
820+ TokenKind .BRACE_L , self .parse_operation_type_definition , TokenKind .BRACE_R
870821 )
871822 if not directives and not operation_types :
872823 raise self .unexpected ()
@@ -1088,24 +1039,42 @@ def unexpected(self, at_token: Token = None) -> GraphQLError:
10881039 )
10891040
10901041 def any (
1091- self , open_kind : TokenKind , parse_fn : Callable [[], Node ], close_kind : TokenKind
1092- ) -> List [Node ]:
1042+ self , open_kind : TokenKind , parse_fn : Callable [[], T ], close_kind : TokenKind
1043+ ) -> List [T ]:
10931044 """Fetch any matching nodes, possibly none.
10941045
10951046 Returns a possibly empty list of parse nodes, determined by the `parse_fn`.
10961047 This list begins with a lex token of `open_kind` and ends with a lex token of
10971048 `close_kind`. Advances the parser to the next lex token after the closing token.
10981049 """
10991050 self .expect_token (open_kind )
1100- nodes : List [Node ] = []
1051+ nodes : List [T ] = []
11011052 append = nodes .append
11021053 while not self .expect_optional_token (close_kind ):
11031054 append (parse_fn ())
11041055 return nodes
11051056
1057+ def optional_many (
1058+ self , open_kind : TokenKind , parse_fn : Callable [[], T ], close_kind : TokenKind
1059+ ) -> List [T ]:
1060+ """Fetch matching nodes, maybe none.
1061+
1062+ Returns a list of parse nodes, determined by the `parse_fn`. It can be empty
1063+ only if the open token is missing, otherwise it will always return a non-empty
1064+ list that begins with a lex token of `open_kind` and ends with a lex token of
1065+ `close_kind`. Advances the parser to the next lex token after the closing token.
1066+ """
1067+ if self .expect_optional_token (open_kind ):
1068+ nodes = [parse_fn ()]
1069+ append = nodes .append
1070+ while not self .expect_optional_token (close_kind ):
1071+ append (parse_fn ())
1072+ return nodes
1073+ return []
1074+
11061075 def many (
1107- self , open_kind : TokenKind , parse_fn : Callable [[], Node ], close_kind : TokenKind
1108- ) -> List [Node ]:
1076+ self , open_kind : TokenKind , parse_fn : Callable [[], T ], close_kind : TokenKind
1077+ ) -> List [T ]:
11091078 """Fetch matching nodes, at least one.
11101079
11111080 Returns a non-empty list of parse nodes, determined by the `parse_fn`.
0 commit comments