Skip to content

Commit 9f2b23c

Browse files
committed
Make 'extensions' non-optional in schema types
Replicates graphql/graphql-js@ec57f06
1 parent ecc5e13 commit 9f2b23c

File tree

10 files changed

+86
-79
lines changed

10 files changed

+86
-79
lines changed

src/graphql/type/definition.py

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class GraphQLNamedType(GraphQLType):
196196

197197
name: str
198198
description: Optional[str]
199-
extensions: Optional[Dict[str, Any]]
199+
extensions: Dict[str, Any]
200200
ast_node: Optional[TypeDefinitionNode]
201201
extension_ast_nodes: FrozenList[TypeExtensionNode]
202202

@@ -214,9 +214,10 @@ def __init__(
214214
raise TypeError("The name must be a string.")
215215
if description is not None and not is_description(description):
216216
raise TypeError("The description must be a string.")
217-
if extensions is not None and (
218-
not isinstance(extensions, dict)
219-
or not all(isinstance(key, str) for key in extensions)
217+
if extensions is None:
218+
extensions = {}
219+
elif not isinstance(extensions, dict) or not all(
220+
isinstance(key, str) for key in extensions
220221
):
221222
raise TypeError(f"{name} extensions must be a dictionary with string keys.")
222223
if ast_node and not isinstance(ast_node, TypeDefinitionNode):
@@ -435,7 +436,7 @@ class GraphQLField:
435436
subscribe: Optional["GraphQLFieldResolver"]
436437
description: Optional[str]
437438
deprecation_reason: Optional[str]
438-
extensions: Optional[Dict[str, Any]]
439+
extensions: Dict[str, Any]
439440
ast_node: Optional[FieldDefinitionNode]
440441

441442
def __init__(
@@ -478,9 +479,10 @@ def __init__(
478479
raise TypeError("The description must be a string.")
479480
if deprecation_reason is not None and not is_description(deprecation_reason):
480481
raise TypeError("The deprecation reason must be a string.")
481-
if extensions is not None and (
482-
not isinstance(extensions, dict)
483-
or not all(isinstance(key, str) for key in extensions)
482+
if extensions is None:
483+
extensions = {}
484+
elif not isinstance(extensions, dict) or not all(
485+
isinstance(key, str) for key in extensions
484486
):
485487
raise TypeError("Field extensions must be a dictionary with string keys.")
486488
if ast_node and not isinstance(ast_node, FieldDefinitionNode):
@@ -581,7 +583,7 @@ class GraphQLArgument:
581583
description: Optional[str]
582584
deprecation_reason: Optional[str]
583585
out_name: Optional[str] # for transforming names (extension of GraphQL.js)
584-
extensions: Optional[Dict[str, Any]]
586+
extensions: Dict[str, Any]
585587
ast_node: Optional[InputValueDefinitionNode]
586588

587589
def __init__(
@@ -602,9 +604,10 @@ def __init__(
602604
raise TypeError("Argument deprecation reason must be a string.")
603605
if out_name is not None and not isinstance(out_name, str):
604606
raise TypeError("Argument out name must be a string.")
605-
if extensions is not None and (
606-
not isinstance(extensions, dict)
607-
or not all(isinstance(key, str) for key in extensions)
607+
if extensions is None:
608+
extensions = {}
609+
elif not isinstance(extensions, dict) or not all(
610+
isinstance(key, str) for key in extensions
608611
):
609612
raise TypeError(
610613
"Argument extensions must be a dictionary with string keys."
@@ -1187,7 +1190,7 @@ class GraphQLEnumValue:
11871190
value: Any
11881191
description: Optional[str]
11891192
deprecation_reason: Optional[str]
1190-
extensions: Optional[Dict[str, Any]]
1193+
extensions: Dict[str, Any]
11911194
ast_node: Optional[EnumValueDefinitionNode]
11921195

11931196
def __init__(
@@ -1204,9 +1207,10 @@ def __init__(
12041207
raise TypeError(
12051208
"The deprecation reason for the enum value must be a string."
12061209
)
1207-
if extensions is not None and (
1208-
not isinstance(extensions, dict)
1209-
or not all(isinstance(key, str) for key in extensions)
1210+
if extensions is None:
1211+
extensions = {}
1212+
elif not isinstance(extensions, dict) or not all(
1213+
isinstance(key, str) for key in extensions
12101214
):
12111215
raise TypeError(
12121216
"Enum value extensions must be a dictionary with string keys."
@@ -1376,7 +1380,7 @@ class GraphQLInputField:
13761380
description: Optional[str]
13771381
deprecation_reason: Optional[str]
13781382
out_name: Optional[str] # for transforming names (extension of GraphQL.js)
1379-
extensions: Optional[Dict[str, Any]]
1383+
extensions: Dict[str, Any]
13801384
ast_node: Optional[InputValueDefinitionNode]
13811385

13821386
def __init__(
@@ -1397,9 +1401,10 @@ def __init__(
13971401
raise TypeError("Input field deprecation reason must be a string.")
13981402
if out_name is not None and not isinstance(out_name, str):
13991403
raise TypeError("Input field out name must be a string.")
1400-
if extensions is not None and (
1401-
not isinstance(extensions, dict)
1402-
or not all(isinstance(key, str) for key in extensions)
1404+
if extensions is None:
1405+
extensions = {}
1406+
elif not isinstance(extensions, dict) or not all(
1407+
isinstance(key, str) for key in extensions
14031408
):
14041409
raise TypeError(
14051410
"Input field extensions must be a dictionary with string keys."

src/graphql/type/directives.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class GraphQLDirective:
3232
is_repeatable: bool
3333
args: Dict[str, GraphQLArgument]
3434
description: Optional[str]
35-
extensions: Optional[Dict[str, Any]]
35+
extensions: Dict[str, Any]
3636
ast_node: Optional[ast.DirectiveDefinitionNode]
3737

3838
def __init__(
@@ -87,9 +87,10 @@ def __init__(
8787
raise TypeError(f"{name} AST node must be a DirectiveDefinitionNode.")
8888
if description is not None and not is_description(description):
8989
raise TypeError(f"{name} description must be a string.")
90-
if extensions is not None and (
91-
not isinstance(extensions, dict)
92-
or not all(isinstance(key, str) for key in extensions)
90+
if extensions is None:
91+
extensions = {}
92+
elif not isinstance(extensions, dict) or not all(
93+
isinstance(key, str) for key in extensions
9394
):
9495
raise TypeError(f"{name} extensions must be a dictionary with string keys.")
9596
self.name = name

src/graphql/type/schema.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class GraphQLSchema:
9898
type_map: TypeMap
9999
directives: FrozenList[GraphQLDirective]
100100
description: Optional[str]
101-
extensions: Optional[Dict[str, Any]]
101+
extensions: Dict[str, Any]
102102
ast_node: Optional[ast.SchemaDefinitionNode]
103103
extension_ast_nodes: FrozenList[ast.SchemaExtensionNode]
104104

@@ -151,9 +151,10 @@ def __init__(
151151
directives = FrozenList(directives)
152152
if description is not None and not is_description(description):
153153
raise TypeError("Schema description must be a string.")
154-
if extensions is not None and (
155-
not isinstance(extensions, dict)
156-
or not all(isinstance(key, str) for key in extensions)
154+
if extensions is None:
155+
extensions = {}
156+
elif not isinstance(extensions, dict) or not all(
157+
isinstance(key, str) for key in extensions
157158
):
158159
raise TypeError("Schema extensions must be a dictionary with string keys.")
159160
if ast_node and not isinstance(ast_node, ast.SchemaDefinitionNode):

src/graphql/utilities/build_ast_schema.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def build_ast_schema(
4646
description=None,
4747
types=[],
4848
directives=[],
49-
extensions=None,
49+
extensions={},
5050
ast_node=None,
5151
extension_ast_nodes=[],
5252
assume_valid=False,

src/graphql/utilities/extend_schema.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ def build_type(ast_node: TypeDefinitionNode) -> GraphQLNamedType:
662662
"description": schema_def.description.value
663663
if schema_def and schema_def.description
664664
else None,
665-
"extensions": None,
665+
"extensions": {},
666666
"ast_node": schema_def or schema_kwargs["ast_node"],
667667
"extension_ast_nodes": schema_kwargs["extension_ast_nodes"] + schema_extensions,
668668
"assume_valid": assume_valid,

tests/type/test_definition.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def defines_a_scalar_type():
7373
"serialize": None,
7474
"parse_value": None,
7575
"parse_literal": None,
76-
"extensions": None,
76+
"extensions": {},
7777
"ast_node": None,
7878
"extension_ast_nodes": [],
7979
}
@@ -274,7 +274,7 @@ def defines_a_field():
274274
"subscribe": None,
275275
"description": None,
276276
"deprecation_reason": None,
277-
"extensions": None,
277+
"extensions": {},
278278
"ast_node": None,
279279
}
280280

@@ -421,7 +421,7 @@ def accepts_an_object_type_with_a_field_function():
421421
assert field.resolve is None
422422
assert field.subscribe is None
423423
assert field.deprecation_reason is None
424-
assert field.extensions is None
424+
assert field.extensions == {}
425425
assert field.ast_node is None
426426

427427
def thunk_for_fields_of_object_type_is_resolved_only_once():
@@ -455,12 +455,12 @@ def accepts_an_object_type_with_field_args():
455455
assert arg.type is ScalarType
456456
assert arg.default_value is Undefined
457457
assert arg.deprecation_reason is None
458-
assert arg.extensions is None
458+
assert arg.extensions == {}
459459
assert arg.ast_node is None
460460
assert field.resolve is None
461461
assert field.subscribe is None
462462
assert field.deprecation_reason is None
463-
assert field.extensions is None
463+
assert field.extensions == {}
464464
assert field.ast_node is None
465465

466466
def accepts_an_object_type_with_list_interfaces():
@@ -687,15 +687,15 @@ def defines_an_interface_type():
687687
assert interface.fields == fields
688688
assert interface.fields is not fields
689689
assert interface.resolve_type is None
690-
assert interface.extensions is None
690+
assert interface.extensions == {}
691691
kwargs = interface.to_kwargs()
692692
assert kwargs == {
693693
"name": "AnotherInterface",
694694
"description": None,
695695
"fields": fields,
696696
"interfaces": [],
697697
"resolve_type": None,
698-
"extensions": None,
698+
"extensions": {},
699699
"ast_node": None,
700700
"extension_ast_nodes": [],
701701
}
@@ -1040,7 +1040,7 @@ def defines_an_enum_type_with_deprecated_value():
10401040
assert deprecated_value == GraphQLEnumValue(deprecation_reason="Just because")
10411041
assert deprecated_value.deprecation_reason == "Just because"
10421042
assert deprecated_value.value is None
1043-
assert deprecated_value.extensions is None
1043+
assert deprecated_value.extensions == {}
10441044
assert deprecated_value.ast_node is None
10451045

10461046
def defines_an_enum_type_with_a_value_of_none_and_invalid():
@@ -1058,19 +1058,19 @@ def defines_an_enum_type_with_a_value_of_none_and_invalid():
10581058
assert null_value.description is None
10591059
assert null_value.value is None
10601060
assert null_value.deprecation_reason is None
1061-
assert null_value.extensions is None
1061+
assert null_value.extensions == {}
10621062
assert null_value.ast_node is None
10631063
null_value = EnumTypeWithNullishValue.values["NAN"]
10641064
assert null_value.description is None
10651065
assert isnan(null_value.value)
10661066
assert null_value.deprecation_reason is None
1067-
assert null_value.extensions is None
1067+
assert null_value.extensions == {}
10681068
assert null_value.ast_node is None
10691069
no_custom_value = EnumTypeWithNullishValue.values["NO_CUSTOM_VALUE"]
10701070
assert no_custom_value.description is None
10711071
assert no_custom_value.value is Undefined
10721072
assert no_custom_value.deprecation_reason is None
1073-
assert no_custom_value.extensions is None
1073+
assert no_custom_value.extensions == {}
10741074
assert no_custom_value.ast_node is None
10751075

10761076
def accepts_a_well_defined_enum_type_with_empty_value_definition():
@@ -1444,7 +1444,7 @@ def accepts_an_input_object_type_with_fields():
14441444
assert input_field.type is ScalarType
14451445
assert input_field.default_value is Undefined
14461446
assert input_field.deprecation_reason is None
1447-
assert input_field.extensions is None
1447+
assert input_field.extensions == {}
14481448
assert input_field.ast_node is None
14491449
assert input_field.out_name is None
14501450

@@ -1468,7 +1468,7 @@ def accepts_an_input_object_type_with_a_field_function():
14681468
assert input_field.type is ScalarType
14691469
assert input_field.default_value is Undefined
14701470
assert input_field.deprecation_reason is None
1471-
assert input_field.extensions is None
1471+
assert input_field.extensions == {}
14721472
assert input_field.ast_node is None
14731473
assert input_field.out_name is None
14741474

tests/type/test_directives.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def can_create_instance():
2222
assert directive.args == {"arg": arg}
2323
assert directive.is_repeatable is True
2424
assert directive.description == "test description"
25-
assert directive.extensions is None
25+
assert directive.extensions == {}
2626
assert directive.ast_node is node
2727

2828
def defines_a_directive_with_no_args():
@@ -32,7 +32,7 @@ def defines_a_directive_with_no_args():
3232
assert directive.name == "Foo"
3333
assert directive.args == {}
3434
assert directive.is_repeatable is False
35-
assert directive.extensions is None
35+
assert directive.extensions == {}
3636
assert directive.locations == locations
3737

3838
def defines_a_directive_with_multiple_args():

0 commit comments

Comments
 (0)