Skip to content

Commit 602d774

Browse files
author
rawls238
committed
initial impl
1 parent c2bffcf commit 602d774

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

graphql/core/validation/rules.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from ..utils import type_from_ast, is_valid_literal_value
22
from ..error import GraphQLError
3-
from ..type.definition import is_composite_type, is_input_type, is_leaf_type, GraphQLNonNull
3+
from ..type.definition import is_composite_type, is_input_type, is_leaf_type, GraphQLNonNull, GraphQLObjectType,
4+
GraphQLInterfaceType, GraphQLUnionType
45
from ..language import ast
56
from ..language.visitor import Visitor, visit
67
from ..language.printer import print_ast
@@ -234,7 +235,38 @@ def unused_fragment_message(fragment_name):
234235

235236

236237
class PossibleFragmentSpreads(ValidationRule):
237-
pass
238+
def enter_InlineFragment(self, node, *args):
239+
frag_type = self.context.get_type()
240+
parent_type = self.context.get_parent_type()
241+
if frag_type and parent_type and not self.do_types_overlap(frag_type, parent_type):
242+
return GraphQLError(
243+
self.type_incompatible_anon_spread_message(parent_type, frag_type),
244+
[node]
245+
)
246+
247+
def enter_FragmentSpread(self, node, *args):
248+
frag_name = node.name.value
249+
frag_type = self.get_fragment_type(context, frag_name)
250+
parent_type = self.context.get_parent_type()
251+
if frag_type and parent_type and not self.do_types_overlap(frag_type, parent_type):
252+
return GraphQLError(
253+
self.type_incompatible_spread_message(frag_name, parent_type, frag_type),
254+
[node]
255+
)
256+
257+
@staticmethod
258+
def get_fragment_type(context, name):
259+
frag = context.get_fragment(name)
260+
return frag and type_from_ast(context.get_schema(), frag.type_condition)
261+
262+
263+
@staticmethod
264+
def type_incompatible_spread_message(frag_name, parent_type, frag_type):
265+
return 'Fragment {} cannot be spread here as objects of type {} can never be of type {}'.format(frag_name, parent_type, frag_type)
266+
267+
@staticmethod
268+
def type_incompatible_anon_spread_message(parent_type, frag_type):
269+
return 'Fragment cannot be spread here as objects of type {} can never be of type {}'.format(parent_type, frag_type)
238270

239271

240272
class NoFragmentCycles(ValidationRule):

0 commit comments

Comments
 (0)