@@ -36,6 +36,11 @@ def __init__(self, query, mutation=None):
36
36
self ._type_map = self ._build_type_map ()
37
37
self ._directives = None
38
38
39
+ for type in self ._type_map .values ():
40
+ if isinstance (type , GraphQLObjectType ):
41
+ for interface in type .get_interfaces ():
42
+ assert_object_implements_interface (type , interface )
43
+
39
44
def get_query_type (self ):
40
45
return self ._query
41
46
@@ -82,8 +87,8 @@ def type_map_reducer(map, type):
82
87
if type .name in map :
83
88
assert map [type .name ] == type , (
84
89
'Schema must contain unique named types but contains multiple types named "{}".'
85
- .format (type .name )
86
- )
90
+ ) .format (type .name )
91
+
87
92
return map
88
93
89
94
map [type .name ] = type
@@ -110,3 +115,50 @@ def type_map_reducer(map, type):
110
115
reduced_map = type_map_reducer (reduced_map , getattr (field , 'type' , None ))
111
116
112
117
return reduced_map
118
+
119
+
120
+ def assert_object_implements_interface (object , interface ):
121
+ object_field_map = object .get_fields ()
122
+ interface_field_map = interface .get_fields ()
123
+
124
+ for field_name , interface_field in interface_field_map .items ():
125
+ object_field = object_field_map .get (field_name )
126
+
127
+ assert object_field , '"{}" expects field "{}" but "{}" does not provide it.' .format (
128
+ interface , field_name , object
129
+ )
130
+
131
+ assert is_equal_type (interface_field .type , object_field .type ), (
132
+ '{}.{} expects type "{}" but {}.{} provides type "{}".'
133
+ ).format (interface , field_name , interface_field .type , object , field_name , object_field .type )
134
+
135
+ object_arg_map = {arg .name : arg for arg in object_field .args }
136
+ for interface_arg in interface_field .args :
137
+ arg_name = interface_arg .name
138
+ object_arg = object_arg_map .get (arg_name )
139
+
140
+ assert object_arg , (
141
+ '{}.{} expects argument "{}" but {}.{} does not provide it.'
142
+ ).format (interface , field_name , arg_name , object , field_name )
143
+
144
+ assert is_equal_type (interface_arg .type , object_arg .type ), (
145
+ '{}.{}({}:) expects type "{}" but {}.{}({}:) provides type "{}".'
146
+ ).format (interface , field_name , arg_name , interface_arg .type , object , field_name , arg_name , object_arg .type )
147
+
148
+ interface_arg_map = {arg .name : arg for arg in interface_field .args }
149
+ for object_arg in object_field .args :
150
+ arg_name = object_arg .name
151
+ interface_arg = interface_arg_map .get (arg_name )
152
+ assert interface_arg , (
153
+ '{}.{} does not define argument "{}" but {}.{} provides it.'
154
+ ).format (interface , field_name , arg_name , object , field_name )
155
+
156
+
157
+ def is_equal_type (type_a , type_b ):
158
+ if isinstance (type_a , GraphQLNonNull ) and isinstance (type_b , GraphQLNonNull ):
159
+ return is_equal_type (type_a .of_type , type_b .of_type )
160
+
161
+ if isinstance (type_a , GraphQLList ) and isinstance (type_b , GraphQLList ):
162
+ return is_equal_type (type_a .of_type , type_b .of_type )
163
+
164
+ return type_a is type_b
0 commit comments