1
- from . import rules as Rules
2
- from ..error import GraphQLError
3
- from ..language .ast import FragmentDefinition , FragmentSpread
4
- from ..language .visitor import Visitor , visit
1
+ from ..language .visitor import visit
5
2
from ..type import GraphQLSchema
6
3
from ..utils .type_info import TypeInfo
7
-
8
- specified_rules = [
9
- Rules .UniqueOperationNames ,
10
- Rules .LoneAnonymousOperation ,
11
- Rules .KnownTypeNames ,
12
- Rules .FragmentsOnCompositeTypes ,
13
- Rules .VariablesAreInputTypes ,
14
- Rules .ScalarLeafs ,
15
- Rules .FieldsOnCorrectType ,
16
- Rules .UniqueFragmentNames ,
17
- Rules .KnownFragmentNames ,
18
- Rules .NoUnusedFragments ,
19
- Rules .PossibleFragmentSpreads ,
20
- Rules .NoFragmentCycles ,
21
- Rules .NoUndefinedVariables ,
22
- Rules .NoUnusedVariables ,
23
- Rules .KnownDirectives ,
24
- Rules .KnownArgumentNames ,
25
- Rules .UniqueArgumentNames ,
26
- Rules .ArgumentsOfCorrectType ,
27
- Rules .ProvidedNonNullArguments ,
28
- Rules .DefaultValuesOfCorrectType ,
29
- Rules .VariablesInAllowedPosition ,
30
- Rules .OverlappingFieldsCanBeMerged ,
31
- Rules .UniqueInputFieldNames
32
- ]
4
+ from .context import ValidationContext
5
+ from .rules import specified_rules
6
+ from .visitor import ValidationVisitor
33
7
34
8
35
9
def validate (schema , ast , rules = None ):
@@ -48,140 +22,3 @@ def visit_using_rules(schema, ast, rules):
48
22
rules = [rule (context ) for rule in rules ]
49
23
visit (ast , ValidationVisitor (rules , context , type_info , errors ))
50
24
return errors
51
-
52
-
53
- class ValidationVisitor (Visitor ):
54
- def __init__ (self , rules , context , type_info , errors ):
55
- self .context = context
56
- self .rules = rules
57
- self .total_rules = len (rules )
58
- self .type_info = type_info
59
- self .errors = errors
60
- self .ignore_children = {}
61
-
62
- def enter (self , node , key , parent , path , ancestors ):
63
- self .type_info .enter (node )
64
- to_ignore = None
65
- rules_wanting_to_visit_fragment = None
66
-
67
- skipped = 0
68
- for rule in self .rules :
69
- if rule in self .ignore_children :
70
- skipped += 1
71
- continue
72
-
73
- visit_spread_fragments = getattr (rule , 'visit_spread_fragments' , False )
74
-
75
- if isinstance (node , FragmentDefinition ) and key and visit_spread_fragments :
76
- if to_ignore is None :
77
- to_ignore = []
78
-
79
- to_ignore .append (rule )
80
- continue
81
-
82
- result = rule .enter (node , key , parent , path , ancestors )
83
-
84
- if result and is_error (result ):
85
- append (self .errors , result )
86
- result = False
87
-
88
- if result is None and visit_spread_fragments and isinstance (node , FragmentSpread ):
89
- if rules_wanting_to_visit_fragment is None :
90
- rules_wanting_to_visit_fragment = []
91
-
92
- rules_wanting_to_visit_fragment .append (rule )
93
-
94
- if result is False :
95
- if to_ignore is None :
96
- to_ignore = []
97
-
98
- to_ignore .append (rule )
99
-
100
- if rules_wanting_to_visit_fragment :
101
- fragment = self .context .get_fragment (node .name .value )
102
-
103
- if fragment :
104
- sub_visitor = ValidationVisitor (rules_wanting_to_visit_fragment , self .context , self .type_info ,
105
- self .errors )
106
- visit (fragment , sub_visitor )
107
-
108
- should_skip = (len (to_ignore ) if to_ignore else 0 + skipped ) == self .total_rules
109
-
110
- if should_skip :
111
- self .type_info .leave (node )
112
-
113
- elif to_ignore :
114
- for rule in to_ignore :
115
- self .ignore_children [rule ] = node
116
-
117
- if should_skip :
118
- return False
119
-
120
- def leave (self , node , key , parent , path , ancestors ):
121
- for rule in self .rules :
122
- if rule in self .ignore_children :
123
- if self .ignore_children [rule ] is node :
124
- del self .ignore_children [rule ]
125
-
126
- continue
127
-
128
- result = rule .leave (node , key , parent , path , ancestors )
129
-
130
- if result and is_error (result ):
131
- append (self .errors , result )
132
-
133
- self .type_info .leave (node )
134
-
135
-
136
- def is_error (value ):
137
- if isinstance (value , list ):
138
- return all (isinstance (item , GraphQLError ) for item in value )
139
- return isinstance (value , GraphQLError )
140
-
141
-
142
- def append (arr , items ):
143
- if isinstance (items , list ):
144
- arr .extend (items )
145
- else :
146
- arr .append (items )
147
-
148
-
149
- class ValidationContext (object ):
150
- def __init__ (self , schema , ast , type_info ):
151
- self ._schema = schema
152
- self ._ast = ast
153
- self ._type_info = type_info
154
- self ._fragments = None
155
-
156
- def get_schema (self ):
157
- return self ._schema
158
-
159
- def get_ast (self ):
160
- return self ._ast
161
-
162
- def get_fragment (self , name ):
163
- fragments = self ._fragments
164
- if fragments is None :
165
- self ._fragments = fragments = {}
166
- for statement in self .get_ast ().definitions :
167
- if isinstance (statement , FragmentDefinition ):
168
- fragments [statement .name .value ] = statement
169
- return fragments .get (name )
170
-
171
- def get_type (self ):
172
- return self ._type_info .get_type ()
173
-
174
- def get_parent_type (self ):
175
- return self ._type_info .get_parent_type ()
176
-
177
- def get_input_type (self ):
178
- return self ._type_info .get_input_type ()
179
-
180
- def get_field_def (self ):
181
- return self ._type_info .get_field_def ()
182
-
183
- def get_directive (self ):
184
- return self ._type_info .get_directive ()
185
-
186
- def get_argument (self ):
187
- return self ._type_info .get_argument ()
0 commit comments