@@ -64,15 +64,19 @@ def extend_schema(schema: GraphQLSchema, document_ast: DocumentNode,
64
64
# have the same name. For example, a type named "skip".
65
65
directive_definitions : List [DirectiveDefinitionNode ] = []
66
66
67
+ schema_def : Optional [SchemaDefinitionNode ] = None
67
68
# Schema extensions are collected which may add additional operation types.
68
69
schema_extensions : List [SchemaExtensionNode ] = []
69
70
70
71
for def_ in document_ast .definitions :
71
72
if isinstance (def_ , SchemaDefinitionNode ):
72
- # Sanity check that a schema extension is not defining a new schema
73
- raise GraphQLError (
74
- 'Cannot define a new schema within a schema extension.' ,
75
- [def_ ])
73
+ # Sanity check that a schema extension is not overriding the schema
74
+ if (schema .ast_node or schema .query_type or
75
+ schema .mutation_type or schema .subscription_type ):
76
+ raise GraphQLError (
77
+ 'Cannot define a new schema within a schema extension.' ,
78
+ [def_ ])
79
+ schema_def = def_
76
80
elif isinstance (def_ , SchemaExtensionNode ):
77
81
schema_extensions .append (def_ )
78
82
elif isinstance (def_ , (
@@ -121,7 +125,8 @@ def extend_schema(schema: GraphQLSchema, document_ast: DocumentNode,
121
125
# If this document contains no new types, extensions, or directives then
122
126
# return the same unmodified GraphQLSchema instance.
123
127
if (not type_extensions_map and not type_definition_map
124
- and not directive_definitions and not schema_extensions ):
128
+ and not directive_definitions and not schema_extensions
129
+ and not schema_def ):
125
130
return schema
126
131
127
132
# Below are functions used for producing this schema that have closed over
@@ -431,20 +436,33 @@ def resolve_type(type_ref: NamedTypeNode) -> GraphQLNamedType:
431
436
OperationType .SUBSCRIPTION :
432
437
extend_maybe_named_type (schema .subscription_type )}
433
438
434
- # Then, incorporate all schema extensions.
439
+ if schema_def :
440
+ for operation_type in schema_def .operation_types :
441
+ operation = operation_type .operation
442
+ if operation_types [operation ]:
443
+ raise TypeError (
444
+ f'Must provide only one { operation .value } type in schema.' )
445
+ # Note: While this could make early assertions to get the
446
+ # correctly typed values, that would throw immediately while
447
+ # type system validation with validate_schema() will produce
448
+ # more actionable results.
449
+ type_ = operation_type .type
450
+ operation_types [operation ] = ast_builder .build_type (type_ )
451
+
452
+ # Then, incorporate schema definition and all schema extensions.
435
453
for schema_extension in schema_extensions :
436
454
if schema_extension .operation_types :
437
455
for operation_type in schema_extension .operation_types :
438
456
operation = operation_type .operation
439
457
if operation_types [operation ]:
440
458
raise TypeError (f'Must provide only one { operation .value } '
441
459
' type in schema.' )
442
- type_ref = operation_type .type
443
460
# Note: While this could make early assertions to get the
444
461
# correctly typed values, that would throw immediately while
445
462
# type system validation with validate_schema() will produce
446
- # more actionable results
447
- operation_types [operation ] = ast_builder .build_type (type_ref )
463
+ # more actionable results.
464
+ type_ = operation_type .type
465
+ operation_types [operation ] = ast_builder .build_type (type_ )
448
466
449
467
schema_extension_ast_nodes = (
450
468
schema .extension_ast_nodes or cast (Tuple [SchemaExtensionNode ], ())
0 commit comments