Skip to content

Commit fc89fa4

Browse files
committed
Use 'Undefined' instead of 'INVALID'
This is more similar to undefined in JavaScript and to the spelling of None in Python as capitalized word. INVALID can still be imported as an alias from the root level, but is now considered deprecated.
1 parent 990b73a commit fc89fa4

37 files changed

+273
-259
lines changed

docs/modules/error.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,3 @@ Error
1313
.. autofunction:: format_error
1414
.. autofunction:: located_error
1515
.. autofunction:: print_error
16-
17-
.. autodata:: INVALID

docs/modules/pyutils.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ PyUtils
3131
.. autoclass:: Path
3232
:members:
3333
.. autofunction:: print_path_list
34+
35+
.. autodata:: Undefined

src/graphql/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,6 @@
327327
located_error,
328328
format_error,
329329
print_error,
330-
INVALID,
331330
)
332331

333332
# Utilities for operating on GraphQL type schema and parsed sources.
@@ -397,6 +396,11 @@
397396
find_dangerous_changes,
398397
)
399398

399+
# Utilities for compatibility with the Python language.
400+
from .pyutils import Undefined, UndefinedType
401+
402+
INVALID = Undefined # deprecated alias
403+
400404
# The GraphQL-core version info.
401405
__version__ = version
402406
__version_info__ = version_info
@@ -651,7 +655,6 @@
651655
"located_error",
652656
"format_error",
653657
"print_error",
654-
"INVALID",
655658
"get_introspection_query",
656659
"get_operation_ast",
657660
"get_operation_root_type",
@@ -685,4 +688,6 @@
685688
"BreakingChangeType",
686689
"DangerousChange",
687690
"DangerousChangeType",
691+
"Undefined",
692+
"UndefinedType",
688693
]

src/graphql/error/__init__.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,7 @@
1212

1313
from .format_error import format_error
1414

15-
from .invalid import INVALID, InvalidType
16-
1715
__all__ = [
18-
"INVALID",
19-
"InvalidType",
2016
"GraphQLError",
2117
"GraphQLSyntaxError",
2218
"format_error",

src/graphql/error/invalid.py

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/graphql/execution/execute.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
cast,
1616
)
1717

18-
from ..error import GraphQLError, INVALID, located_error
18+
from ..error import GraphQLError, located_error
1919
from ..language import (
2020
DocumentNode,
2121
FieldNode,
@@ -33,6 +33,7 @@
3333
AwaitableOrValue,
3434
FrozenList,
3535
Path,
36+
Undefined,
3637
)
3738
from ..utilities.get_operation_root_type import get_operation_root_type
3839
from ..utilities.type_from_ast import type_from_ast
@@ -382,7 +383,7 @@ def execute_fields_serially(
382383
result = self.resolve_field(
383384
parent_type, source_value, field_nodes, field_path
384385
)
385-
if result is INVALID:
386+
if result is Undefined:
386387
continue
387388
if isawaitable(results):
388389
# noinspection PyShadowingNames
@@ -434,7 +435,7 @@ def execute_fields(
434435
result = self.resolve_field(
435436
parent_type, source_value, field_nodes, field_path
436437
)
437-
if result is not INVALID:
438+
if result is not Undefined:
438439
results[response_name] = result
439440
if isawaitable(result):
440441
append_awaitable(response_name)
@@ -592,7 +593,7 @@ def resolve_field(
592593

593594
field_def = get_field_def(self.schema, parent_type, field_name)
594595
if not field_def:
595-
return INVALID
596+
return Undefined
596597

597598
resolve_fn = field_def.resolve or self.field_resolver
598599

@@ -762,7 +763,7 @@ def complete_value(
762763
)
763764
return completed
764765

765-
# If result value is null-ish (null, INVALID, or NaN) then return null.
766+
# If result value is null-ish (null, Undefined, or NaN) then return null.
766767
if is_nullish(result):
767768
return None
768769

src/graphql/execution/values.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Any, Callable, Dict, List, Optional, Union, cast
22

3-
from ..error import GraphQLError, INVALID
3+
from ..error import GraphQLError
44
from ..language import (
55
DirectiveNode,
66
ExecutableDefinitionNode,
@@ -14,7 +14,7 @@
1414
VariableNode,
1515
print_ast,
1616
)
17-
from ..pyutils import inspect, print_path_list, FrozenList
17+
from ..pyutils import inspect, print_path_list, FrozenList, Undefined
1818
from ..type import (
1919
GraphQLDirective,
2020
GraphQLField,
@@ -161,7 +161,7 @@ def get_argument_values(
161161
argument_node = arg_node_map.get(name)
162162

163163
if argument_node is None:
164-
if arg_def.default_value is not INVALID:
164+
if arg_def.default_value is not Undefined:
165165
coerced_values[arg_def.out_name or name] = arg_def.default_value
166166
elif is_non_null_type(arg_type):
167167
raise GraphQLError(
@@ -177,7 +177,7 @@ def get_argument_values(
177177
if isinstance(value_node, VariableNode):
178178
variable_name = value_node.name.value
179179
if variable_values is None or variable_name not in variable_values:
180-
if arg_def.default_value is not INVALID:
180+
if arg_def.default_value is not Undefined:
181181
coerced_values[arg_def.out_name or name] = arg_def.default_value
182182
elif is_non_null_type(arg_type):
183183
raise GraphQLError(
@@ -196,7 +196,7 @@ def get_argument_values(
196196
)
197197

198198
coerced_value = value_from_ast(value_node, arg_type, variable_values)
199-
if coerced_value is INVALID:
199+
if coerced_value is Undefined:
200200
# Note: `values_of_correct_type` validation should catch this before
201201
# execution. This is a runtime check to ensure execution does not
202202
# continue with an invalid argument value.

src/graphql/pyutils/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from .frozen_dict import FrozenDict
3434
from .path import Path
3535
from .print_path_list import print_path_list
36+
from .undefined import Undefined, UndefinedType
3637

3738
__all__ = [
3839
"camel_to_snake",
@@ -60,4 +61,6 @@
6061
"FrozenDict",
6162
"Path",
6263
"print_path_list",
64+
"Undefined",
65+
"UndefinedType",
6366
]

src/graphql/pyutils/identity_func.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from typing import cast, Any, TypeVar
22

3-
from ..error import INVALID
3+
from .undefined import Undefined
44

55
__all__ = ["identity_func"]
66

77

88
T = TypeVar("T")
99

1010

11-
def identity_func(x: T = cast(Any, INVALID), *_args: Any) -> T:
11+
def identity_func(x: T = cast(Any, Undefined), *_args: Any) -> T:
1212
"""Return the first received argument."""
1313
return x

src/graphql/pyutils/inspect.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
)
1212
from typing import Any, List
1313

14-
from ..error import INVALID
14+
from .undefined import Undefined
1515

1616
__all__ = ["inspect"]
1717

@@ -35,7 +35,7 @@ def inspect(value: Any) -> str:
3535

3636

3737
def inspect_recursive(value: Any, seen_values: List) -> str:
38-
if value is None or value is INVALID or isinstance(value, (bool, float, complex)):
38+
if value is None or value is Undefined or isinstance(value, (bool, float, complex)):
3939
return repr(value)
4040
if isinstance(value, (int, str, bytes, bytearray)):
4141
return trunc_str(repr(value))

src/graphql/pyutils/is_invalid.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from typing import Any
22

3-
from ..error import INVALID
3+
from .undefined import Undefined
44

55
__all__ = ["is_invalid"]
66

77

88
def is_invalid(value: Any) -> bool:
99
"""Return true if a value is undefined, or NaN."""
10-
return value is INVALID or value != value
10+
return value is Undefined or value != value

src/graphql/pyutils/is_nullish.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
from math import isnan
22
from typing import Any
33

4-
from ..error import INVALID
4+
from .undefined import Undefined
55

66
__all__ = ["is_nullish"]
77

88

99
def is_nullish(value: Any) -> bool:
1010
"""Return true if a value is null, undefined, or NaN."""
1111
return (
12-
value is None or value is INVALID or (isinstance(value, float) and isnan(value))
12+
value is None
13+
or value is Undefined
14+
or (isinstance(value, float) and isnan(value))
1315
)

src/graphql/pyutils/undefined.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
__all__ = ["Undefined", "UndefinedType"]
2+
3+
4+
class UndefinedType(ValueError):
5+
"""Auxiliary class for creating the Undefined singleton."""
6+
7+
def __repr__(self):
8+
return "Undefined"
9+
10+
__str__ = __repr__
11+
12+
def __hash__(self):
13+
return hash(UndefinedType)
14+
15+
def __bool__(self):
16+
return False
17+
18+
def __eq__(self, other):
19+
return other is Undefined
20+
21+
def __ne__(self, other):
22+
return not self == other
23+
24+
25+
# Used to indicate undefined or invalid values (like "undefined" in JavaScript):
26+
Undefined = UndefinedType()
27+
28+
Undefined.__doc__ = """Symbol for undefined values
29+
30+
This singleton object is used to describe undefined or invalid values.
31+
It can be used in places where you would use ``undefined`` in GraphQL.js.
32+
"""

0 commit comments

Comments
 (0)