Skip to content

Commit 4dbb9d4

Browse files
committed
Simplify deep copy of schemas
1 parent 8c053a3 commit 4dbb9d4

File tree

2 files changed

+37
-47
lines changed

2 files changed

+37
-47
lines changed

src/graphql/type/schema.py

Lines changed: 34 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -291,23 +291,21 @@ def to_kwargs(self) -> Dict[str, Any]:
291291
def __copy__(self) -> "GraphQLSchema": # pragma: no cover
292292
return self.__class__(**self.to_kwargs())
293293

294-
def __deepcopy__(self, memo: Dict) -> "GraphQLSchema":
294+
def __deepcopy__(self, memo_: Dict) -> "GraphQLSchema":
295295
from ..type import (
296296
is_introspection_type,
297297
is_specified_scalar_type,
298298
is_specified_directive,
299299
)
300300

301-
type_map = {
301+
type_map: TypeMap = {
302302
name: copy(type_)
303303
for name, type_ in self.type_map.items()
304304
if not is_introspection_type(type_) and not is_specified_scalar_type(type_)
305305
}
306-
remapped: Set[str] = set()
307-
types = [
308-
cast(GraphQLNamedType, remap_type(type_, type_map, remapped))
309-
for type_ in type_map.values()
310-
]
306+
types = type_map.values()
307+
for type_ in types:
308+
remap_named_type(type_, type_map)
311309
directives = [
312310
directive if is_specified_directive(directive) else copy(directive)
313311
for directive in self.directives
@@ -321,9 +319,9 @@ def __deepcopy__(self, memo: Dict) -> "GraphQLSchema":
321319
types,
322320
directives,
323321
self.description,
324-
extensions=deepcopy(self.extensions, memo),
325-
ast_node=deepcopy(self.ast_node, memo),
326-
extension_ast_nodes=deepcopy(self.extension_ast_nodes, memo),
322+
extensions=deepcopy(self.extensions),
323+
ast_node=deepcopy(self.ast_node),
324+
extension_ast_nodes=deepcopy(self.extension_ast_nodes),
327325
assume_valid=True,
328326
)
329327

@@ -442,50 +440,42 @@ def assert_schema(schema: Any) -> GraphQLSchema:
442440
return cast(GraphQLSchema, schema)
443441

444442

445-
def remap_type(
446-
type_: GraphQLType, type_map: TypeMap, remapped: Set[str]
447-
) -> GraphQLType:
448-
"""Change all references in the given type for a new type map."""
443+
def remapped_type(type_: GraphQLType, type_map: TypeMap) -> GraphQLType:
444+
"""Get a copy of the given type that uses this type map."""
449445
if is_wrapping_type(type_):
450-
wrapping_type = cast(GraphQLWrappingType, type_)
451-
return wrapping_type.__class__(
452-
remap_type(wrapping_type.of_type, type_map, remapped)
453-
)
454-
named_type = cast(GraphQLNamedType, type_)
455-
name = named_type.name
456-
remapped_type = type_map.get(name)
457-
if not remapped_type:
458-
return named_type
459-
if name in remapped:
460-
return remapped_type
461-
remapped.add(name)
462-
if is_union_type(remapped_type):
463-
named_type = cast(GraphQLUnionType, named_type)
464-
named_type.types = [
465-
remap_type(member_type, type_map, remapped)
466-
for member_type in named_type.types
446+
type_ = cast(GraphQLWrappingType, type_)
447+
return type_.__class__(remapped_type(type_.of_type, type_map))
448+
type_ = cast(GraphQLNamedType, type_)
449+
return type_map.get(type_.name, type_)
450+
451+
452+
def remap_named_type(type_: GraphQLNamedType, type_map: TypeMap) -> None:
453+
"""Change all references in the given named type to use this type map."""
454+
if is_union_type(type_):
455+
type_ = cast(GraphQLUnionType, type_)
456+
type_.types = [
457+
type_map.get(member_type.name, member_type) for member_type in type_.types
467458
]
468-
elif is_object_type(remapped_type) or is_interface_type(remapped_type):
469-
named_type = cast(Union[GraphQLObjectType, GraphQLInterfaceType], named_type)
470-
named_type.interfaces = [
471-
remap_type(interface_type, type_map, remapped)
472-
for interface_type in named_type.interfaces
459+
elif is_object_type(type_) or is_interface_type(type_):
460+
type_ = cast(Union[GraphQLObjectType, GraphQLInterfaceType], type_)
461+
type_.interfaces = [
462+
type_map.get(interface_type.name, interface_type)
463+
for interface_type in type_.interfaces
473464
]
474-
fields = named_type.fields
465+
fields = type_.fields
475466
for field_name, field in fields.items():
476467
field = copy(field)
477-
field.type = remap_type(field.type, type_map, remapped)
468+
field.type = remapped_type(field.type, type_map)
478469
args = field.args
479470
for arg_name, arg in args.items():
480471
arg = copy(arg)
481-
arg.type = remap_type(arg.type, type_map, remapped)
472+
arg.type = remapped_type(arg.type, type_map)
482473
args[arg_name] = arg
483474
fields[field_name] = field
484-
elif is_input_object_type(remapped_type):
485-
named_type = cast(GraphQLInputObjectType, named_type)
486-
fields = named_type.fields
475+
elif is_input_object_type(type_):
476+
type_ = cast(GraphQLInputObjectType, type_)
477+
fields = type_.fields
487478
for field_name, field in fields.items():
488479
field = copy(field)
489-
field.type = remap_type(field.type, type_map, remapped)
480+
field.type = remapped_type(field.type, type_map)
490481
fields[field_name] = field
491-
return named_type

tests/type/test_schema.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,13 +450,13 @@ def can_deep_copy_a_schema():
450450
}
451451
452452
type Cow {
453-
id: ID
453+
id: ID!
454454
name: String
455455
moos: Boolean
456456
}
457457
458458
type Pig {
459-
id: ID
459+
id: ID!
460460
name: String
461461
oink: Boolean
462462
}
@@ -474,7 +474,7 @@ def can_deep_copy_a_schema():
474474
}
475475
476476
type Farm {
477-
animals: [Animal]
477+
animals: [Animal!]!
478478
}
479479
480480
type Work {

0 commit comments

Comments
 (0)