1
- from typing import Callable , Dict , List , Optional , Union , cast
1
+ from typing import Callable , Dict , List , Optional , Union , TypeVar , cast
2
2
from functools import partial
3
3
4
4
from .ast import (
30
30
Location ,
31
31
NameNode ,
32
32
NamedTypeNode ,
33
- Node ,
34
33
NonNullTypeNode ,
35
34
NullValueNode ,
36
35
ObjectFieldNode ,
66
65
67
66
__all__ = ["parse" , "parse_type" , "parse_value" ]
68
67
68
+ T = TypeVar ("T" )
69
+
69
70
SourceType = Union [Source , str ]
70
71
71
72
@@ -267,15 +268,8 @@ def parse_operation_type(self) -> OperationType:
267
268
268
269
def parse_variable_definitions (self ) -> List [VariableDefinitionNode ]:
269
270
"""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
279
273
)
280
274
281
275
def parse_variable_definition (self ) -> VariableDefinitionNode :
@@ -337,14 +331,7 @@ def parse_field(self) -> FieldNode:
337
331
def parse_arguments (self , is_const : bool ) -> List [ArgumentNode ]:
338
332
"""Arguments[Const]: (Argument[?Const]+)"""
339
333
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 )
348
335
349
336
def parse_argument (self ) -> ArgumentNode :
350
337
"""Argument: Name : Value"""
@@ -671,15 +658,8 @@ def parse_implements_interfaces(self) -> List[NamedTypeNode]:
671
658
672
659
def parse_fields_definition (self ) -> List [FieldDefinitionNode ]:
673
660
"""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
683
663
)
684
664
685
665
def parse_field_definition (self ) -> FieldDefinitionNode :
@@ -702,15 +682,8 @@ def parse_field_definition(self) -> FieldDefinitionNode:
702
682
703
683
def parse_argument_defs (self ) -> List [InputValueDefinitionNode ]:
704
684
"""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
714
687
)
715
688
716
689
def parse_input_value_def (self ) -> InputValueDefinitionNode :
@@ -798,17 +771,8 @@ def parse_enum_type_definition(self) -> EnumTypeDefinitionNode:
798
771
799
772
def parse_enum_values_definition (self ) -> List [EnumValueDefinitionNode ]:
800
773
"""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
812
776
)
813
777
814
778
def parse_enum_value_definition (self ) -> EnumValueDefinitionNode :
@@ -842,15 +806,8 @@ def parse_input_object_type_definition(self) -> InputObjectTypeDefinitionNode:
842
806
843
807
def parse_input_fields_definition (self ) -> List [InputValueDefinitionNode ]:
844
808
"""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
854
811
)
855
812
856
813
def parse_schema_extension (self ) -> SchemaExtensionNode :
@@ -859,14 +816,8 @@ def parse_schema_extension(self) -> SchemaExtensionNode:
859
816
self .expect_keyword ("extend" )
860
817
self .expect_keyword ("schema" )
861
818
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
870
821
)
871
822
if not directives and not operation_types :
872
823
raise self .unexpected ()
@@ -1088,24 +1039,42 @@ def unexpected(self, at_token: Token = None) -> GraphQLError:
1088
1039
)
1089
1040
1090
1041
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 ]:
1093
1044
"""Fetch any matching nodes, possibly none.
1094
1045
1095
1046
Returns a possibly empty list of parse nodes, determined by the `parse_fn`.
1096
1047
This list begins with a lex token of `open_kind` and ends with a lex token of
1097
1048
`close_kind`. Advances the parser to the next lex token after the closing token.
1098
1049
"""
1099
1050
self .expect_token (open_kind )
1100
- nodes : List [Node ] = []
1051
+ nodes : List [T ] = []
1101
1052
append = nodes .append
1102
1053
while not self .expect_optional_token (close_kind ):
1103
1054
append (parse_fn ())
1104
1055
return nodes
1105
1056
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
+
1106
1075
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 ]:
1109
1078
"""Fetch matching nodes, at least one.
1110
1079
1111
1080
Returns a non-empty list of parse nodes, determined by the `parse_fn`.
0 commit comments