Skip to content

Commit 826b7a1

Browse files
committed
Show warning when trying to deep copy a schema (#100)
1 parent 4c94212 commit 826b7a1

File tree

5 files changed

+49
-5
lines changed

5 files changed

+49
-5
lines changed

src/graphql/pyutils/frozen_dict.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ def __iadd__(self, value):
2424
def __hash__(self):
2525
return hash(tuple(self.items()))
2626

27-
def __copy__(self):
27+
def __copy__(self) -> "FrozenDict":
2828
return FrozenDict(self)
2929

3030
copy = __copy__
3131

32-
def __deepcopy__(self, memo):
32+
def __deepcopy__(self, memo: Dict) -> "FrozenDict":
3333
return FrozenDict({k: deepcopy(v, memo) for k, v in self.items()})
3434

3535
def clear(self):

src/graphql/pyutils/frozen_list.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from copy import deepcopy
2-
from typing import List, TypeVar
2+
from typing import Dict, List, TypeVar
33

44
from .frozen_error import FrozenError
55

@@ -35,10 +35,10 @@ def __imul__(self, value):
3535
def __hash__(self):
3636
return hash(tuple(self))
3737

38-
def __copy__(self):
38+
def __copy__(self) -> "FrozenList":
3939
return FrozenList(self)
4040

41-
def __deepcopy__(self, memo):
41+
def __deepcopy__(self, memo: Dict) -> "FrozenList":
4242
return FrozenList(deepcopy(value, memo) for value in self)
4343

4444
def append(self, x):

src/graphql/type/definition.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ def to_kwargs(self) -> Dict[str, Any]:
252252
extension_ast_nodes=self.extension_ast_nodes or FrozenList(),
253253
)
254254

255+
def __copy__(self) -> "GraphQLNamedType": # pragma: no cover
256+
return self.__class__(**self.to_kwargs())
257+
255258

256259
def is_named_type(type_: Any) -> bool:
257260
return isinstance(type_, GraphQLNamedType)
@@ -428,6 +431,9 @@ def to_kwargs(self) -> Dict[str, Any]:
428431
specified_by_url=self.specified_by_url,
429432
)
430433

434+
def __copy__(self) -> "GraphQLScalarType": # pragma: no cover
435+
return self.__class__(**self.to_kwargs())
436+
431437

432438
def is_scalar_type(type_: Any) -> bool:
433439
return isinstance(type_, GraphQLScalarType)
@@ -539,6 +545,9 @@ def to_kwargs(self) -> Dict[str, Any]:
539545
ast_node=self.ast_node,
540546
)
541547

548+
def __copy__(self) -> "GraphQLField": # pragma: no cover
549+
return self.__class__(**self.to_kwargs())
550+
542551
@property
543552
def is_deprecated(self) -> bool:
544553
return self.deprecation_reason is not None
@@ -649,6 +658,9 @@ def to_kwargs(self) -> Dict[str, Any]:
649658
ast_node=self.ast_node,
650659
)
651660

661+
def __copy__(self) -> "GraphQLArgument": # pragma: no cover
662+
return self.__class__(**self.to_kwargs())
663+
652664

653665
def is_required_argument(arg: GraphQLArgument) -> bool:
654666
return is_non_null_type(arg.type) and arg.default_value is Undefined
@@ -736,6 +748,9 @@ def to_kwargs(self) -> Dict[str, Any]:
736748
is_type_of=self.is_type_of,
737749
)
738750

751+
def __copy__(self) -> "GraphQLObjectType": # pragma: no cover
752+
return self.__class__(**self.to_kwargs())
753+
739754
@cached_property
740755
def fields(self) -> GraphQLFieldMap:
741756
"""Get provided fields, wrapping them as GraphQLFields if needed."""
@@ -856,6 +871,9 @@ def to_kwargs(self) -> Dict[str, Any]:
856871
resolve_type=self.resolve_type,
857872
)
858873

874+
def __copy__(self) -> "GraphQLInterfaceType": # pragma: no cover
875+
return self.__class__(**self.to_kwargs())
876+
859877
@cached_property
860878
def fields(self) -> GraphQLFieldMap:
861879
"""Get provided fields, wrapping them as GraphQLFields if needed."""
@@ -974,6 +992,9 @@ def to_kwargs(self) -> Dict[str, Any]:
974992
**super().to_kwargs(), types=self.types, resolve_type=self.resolve_type
975993
)
976994

995+
def __copy__(self) -> "GraphQLUnionType": # pragma: no cover
996+
return self.__class__(**self.to_kwargs())
997+
977998
@cached_property
978999
def types(self) -> List[GraphQLObjectType]:
9791000
"""Get provided types."""
@@ -1095,6 +1116,9 @@ def __init__(
10951116
def to_kwargs(self) -> Dict[str, Any]:
10961117
return dict(**super().to_kwargs(), values=self.values.copy())
10971118

1119+
def __copy__(self) -> "GraphQLEnumType": # pragma: no cover
1120+
return self.__class__(**self.to_kwargs())
1121+
10981122
@cached_property
10991123
def _value_lookup(self) -> Dict[Any, str]:
11001124
# use first value or name as lookup
@@ -1232,6 +1256,9 @@ def to_kwargs(self) -> Dict[str, Any]:
12321256
ast_node=self.ast_node,
12331257
)
12341258

1259+
def __copy__(self) -> "GraphQLEnumValue": # pragma: no cover
1260+
return self.__class__(**self.to_kwargs())
1261+
12351262
@property
12361263
def is_deprecated(self) -> bool:
12371264
return self.deprecation_reason is not None
@@ -1321,6 +1348,9 @@ def to_kwargs(self) -> Dict[str, Any]:
13211348
else self.out_type,
13221349
)
13231350

1351+
def __copy__(self) -> "GraphQLInputObjectType": # pragma: no cover
1352+
return self.__class__(**self.to_kwargs())
1353+
13241354
@cached_property
13251355
def fields(self) -> GraphQLInputFieldMap:
13261356
"""Get provided fields, wrap them as GraphQLInputField if needed."""
@@ -1422,6 +1452,9 @@ def to_kwargs(self) -> Dict[str, Any]:
14221452
ast_node=self.ast_node,
14231453
)
14241454

1455+
def __copy__(self) -> "GraphQLInputField": # pragma: no cover
1456+
return self.__class__(**self.to_kwargs())
1457+
14251458

14261459
def is_required_input_field(field: GraphQLInputField) -> bool:
14271460
return is_non_null_type(field.type) and field.default_value is Undefined

src/graphql/type/directives.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ def to_kwargs(self) -> Dict[str, Any]:
128128
ast_node=self.ast_node,
129129
)
130130

131+
def __copy__(self) -> "GraphQLDirective": # pragma: no cover
132+
return self.__class__(**self.to_kwargs())
133+
131134

132135
def is_directive(directive: Any) -> bool:
133136
"""Test if the given value is a GraphQL directive."""

src/graphql/type/schema.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
Union,
1010
cast,
1111
)
12+
from warnings import warn
1213

1314
from ..error import GraphQLError
1415
from ..language import ast
@@ -285,6 +286,13 @@ def to_kwargs(self) -> Dict[str, Any]:
285286
assume_valid=self._validation_errors is not None,
286287
)
287288

289+
def __copy__(self) -> "GraphQLSchema": # pragma: no cover
290+
return self.__class__(**self.to_kwargs())
291+
292+
def __deepcopy__(self, memo_: Dict) -> "GraphQLSchema": # pragma: no cover
293+
warn("Cannot deep copy a schema. Creating a flat copy instead.")
294+
return self.__copy__()
295+
288296
def get_type(self, name: str) -> Optional[GraphQLNamedType]:
289297
return self.type_map.get(name)
290298

0 commit comments

Comments
 (0)