Skip to content

Commit a7fe66f

Browse files
committed
Remove excessive cache inside lexicographicSortSchema
Replicates graphql/graphql-js@c2bc19b
1 parent a4abff9 commit a7fe66f

File tree

1 file changed

+43
-39
lines changed

1 file changed

+43
-39
lines changed
Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
from operator import attrgetter
2-
from typing import Collection, Dict, List, cast
1+
from typing import Dict, List, Tuple, cast
32

43
from ..type import (
54
GraphQLArgument,
@@ -24,7 +23,6 @@
2423
is_non_null_type,
2524
is_object_type,
2625
is_scalar_type,
27-
is_specified_scalar_type,
2826
is_union_type,
2927
)
3028

@@ -34,15 +32,24 @@
3432
def lexicographic_sort_schema(schema: GraphQLSchema) -> GraphQLSchema:
3533
"""Sort GraphQLSchema."""
3634

37-
cache: Dict[str, GraphQLNamedType] = {}
35+
def replace_type(type_):
36+
if is_list_type(type_):
37+
return GraphQLList(replace_type(type_.of_type))
38+
elif is_non_null_type(type_):
39+
return GraphQLNonNull(replace_type(type_.of_type))
40+
else:
41+
return replace_named_type(type_)
42+
43+
def replace_named_type(type_: GraphQLNamedType) -> GraphQLNamedType:
44+
return type_map[type_.name]
3845

39-
def sort_maybe_type(maybe_type):
40-
return maybe_type and sort_named_type(maybe_type)
46+
def replace_maybe_type(maybe_type):
47+
return maybe_type and replace_named_type(maybe_type)
4148

4249
def sort_directive(directive):
4350
kwargs = directive.to_kwargs()
4451
kwargs.update(
45-
locations=sorted(directive.locations, key=attrgetter("name")),
52+
locations=sorted(directive.locations, key=sort_by_name_key),
4653
args=sort_args(directive.args),
4754
)
4855
return GraphQLDirective(**kwargs)
@@ -51,58 +58,43 @@ def sort_args(args_map):
5158
args = {}
5259
for name, arg in sorted(args_map.items()):
5360
kwargs = arg.to_kwargs()
54-
kwargs.update(type_=sort_type(arg.type))
61+
kwargs.update(type_=replace_type(arg.type))
5562
args[name] = GraphQLArgument(**kwargs)
5663
return args
5764

5865
def sort_fields(fields_map):
5966
fields = {}
6067
for name, field in sorted(fields_map.items()):
6168
kwargs = field.to_kwargs()
62-
kwargs.update(type_=sort_type(field.type), args=sort_args(field.args))
69+
kwargs.update(type_=replace_type(field.type), args=sort_args(field.args))
6370
fields[name] = GraphQLField(**kwargs)
6471
return fields
6572

6673
def sort_input_fields(fields_map):
6774
return {
6875
name: GraphQLInputField(
69-
sort_type(field.type),
76+
replace_type(field.type),
7077
description=field.description,
7178
default_value=field.default_value,
7279
ast_node=field.ast_node,
7380
)
7481
for name, field in sorted(fields_map.items())
7582
}
7683

77-
def sort_type(type_):
78-
if is_list_type(type_):
79-
return GraphQLList(sort_type(type_.of_type))
80-
elif is_non_null_type(type_):
81-
return GraphQLNonNull(sort_type(type_.of_type))
82-
else:
83-
return sort_named_type(type_)
84+
def sort_types(arr: List[GraphQLNamedType]) -> List[GraphQLNamedType]:
85+
return [
86+
replace_named_type(type_) for type_ in sorted(arr, key=sort_by_name_key)
87+
]
8488

8589
def sort_named_type(type_: GraphQLNamedType) -> GraphQLNamedType:
86-
if is_specified_scalar_type(type_) or is_introspection_type(type_):
87-
return type_
88-
89-
sorted_type = cache.get(type_.name)
90-
if not sorted_type:
91-
sorted_type = sort_named_type_impl(type_)
92-
cache[type_.name] = sorted_type
93-
return sorted_type
94-
95-
def sort_types(arr: Collection[GraphQLNamedType]) -> List[GraphQLNamedType]:
96-
return [sort_named_type(type_) for type_ in sorted(arr, key=attrgetter("name"))]
97-
98-
def sort_named_type_impl(type_: GraphQLNamedType) -> GraphQLNamedType:
99-
if is_scalar_type(type_):
90+
if is_scalar_type(type_) or is_introspection_type(type_):
10091
return type_
10192
elif is_object_type(type_):
10293
kwargs = type_.to_kwargs()
10394
object_type = cast(GraphQLObjectType, type_)
95+
# noinspection PyTypeChecker
10496
kwargs.update(
105-
interfaces=lambda: sort_types(object_type.interfaces),
97+
interfaces=lambda: sort_types(object_type.interfaces), # type: ignore
10698
fields=lambda: sort_fields(object_type.fields),
10799
)
108100
return GraphQLObjectType(**kwargs)
@@ -114,7 +106,8 @@ def sort_named_type_impl(type_: GraphQLNamedType) -> GraphQLNamedType:
114106
elif is_union_type(type_):
115107
kwargs = type_.to_kwargs()
116108
union_type = cast(GraphQLUnionType, type_)
117-
kwargs.update(types=lambda: sort_types(union_type.types))
109+
# noinspection PyTypeChecker
110+
kwargs.update(types=lambda: sort_types(union_type.types)) # type: ignore
118111
return GraphQLUnionType(**kwargs)
119112
elif is_enum_type(type_):
120113
kwargs = type_.to_kwargs()
@@ -134,18 +127,29 @@ def sort_named_type_impl(type_: GraphQLNamedType) -> GraphQLNamedType:
134127
elif is_input_object_type(type_):
135128
kwargs = type_.to_kwargs()
136129
input_object_type = cast(GraphQLInputObjectType, type_)
137-
kwargs.update(fields=sort_input_fields(input_object_type.fields))
130+
kwargs.update(fields=lambda: sort_input_fields(input_object_type.fields))
138131
return GraphQLInputObjectType(**kwargs)
139132
raise TypeError(f"Unknown type: '{type_}'")
140133

134+
type_map: Dict[str, GraphQLNamedType] = {
135+
type_.name: sort_named_type(type_)
136+
for type_ in sorted(schema.type_map.values(), key=sort_by_name_key)
137+
}
138+
141139
return GraphQLSchema(
142-
types=sort_types(schema.type_map.values()),
140+
types=list(type_map.values()),
143141
directives=[
144142
sort_directive(directive)
145-
for directive in sorted(schema.directives, key=attrgetter("name"))
143+
for directive in sorted(schema.directives, key=sort_by_name_key)
146144
],
147-
query=sort_maybe_type(schema.query_type),
148-
mutation=sort_maybe_type(schema.mutation_type),
149-
subscription=sort_maybe_type(schema.subscription_type),
145+
query=replace_maybe_type(schema.query_type),
146+
mutation=replace_maybe_type(schema.mutation_type),
147+
subscription=replace_maybe_type(schema.subscription_type),
150148
ast_node=schema.ast_node,
151149
)
150+
151+
152+
def sort_by_name_key(type_) -> Tuple[bool, str]:
153+
name = type_.name
154+
# GraphQL.JS sorts '_' first using localeCompare
155+
return not name.startswith("_"), name

0 commit comments

Comments
 (0)