Skip to content

Commit 71763a3

Browse files
committed
Refinement of non null types
Also removed internal tuples of types, they could be confusing. Roughly replicates graphql/graphql-js@c526767
1 parent 55547d8 commit 71763a3

File tree

5 files changed

+104
-84
lines changed

5 files changed

+104
-84
lines changed

src/graphql/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@
325325
GraphQLAbstractType,
326326
GraphQLWrappingType,
327327
GraphQLNullableType,
328+
GraphQLNullableInputType,
329+
GraphQLNullableOutputType,
328330
GraphQLNamedType,
329331
GraphQLNamedInputType,
330332
GraphQLNamedOutputType,
@@ -543,6 +545,8 @@
543545
"GraphQLAbstractType",
544546
"GraphQLWrappingType",
545547
"GraphQLNullableType",
548+
"GraphQLNullableInputType",
549+
"GraphQLNullableOutputType",
546550
"GraphQLNamedType",
547551
"GraphQLNamedInputType",
548552
"GraphQLNamedOutputType",

src/graphql/type/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@
8282
GraphQLAbstractType,
8383
GraphQLWrappingType,
8484
GraphQLNullableType,
85+
GraphQLNullableInputType,
86+
GraphQLNullableOutputType,
8587
GraphQLNamedType,
8688
GraphQLNamedInputType,
8789
GraphQLNamedOutputType,
@@ -234,6 +236,8 @@
234236
"GraphQLAbstractType",
235237
"GraphQLWrappingType",
236238
"GraphQLNullableType",
239+
"GraphQLNullableInputType",
240+
"GraphQLNullableOutputType",
237241
"GraphQLNamedType",
238242
"GraphQLNamedInputType",
239243
"GraphQLNamedOutputType",

src/graphql/type/definition.py

Lines changed: 94 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@
144144
"GraphQLNamedInputType",
145145
"GraphQLNamedOutputType",
146146
"GraphQLNullableType",
147+
"GraphQLNullableInputType",
148+
"GraphQLNullableOutputType",
147149
"GraphQLNonNull",
148150
"GraphQLResolveInfo",
149151
"GraphQLScalarType",
@@ -169,7 +171,7 @@ class GraphQLType:
169171
"""Base class for all GraphQL types"""
170172

171173
# Note: We don't use slots for GraphQLType objects because memory considerations
172-
# are not really important for the schema definition and it would make caching
174+
# are not really important for the schema definition, and it would make caching
173175
# properties slower or more complicated.
174176

175177

@@ -188,7 +190,7 @@ def assert_type(type_: Any) -> GraphQLType:
188190

189191
# These types wrap and modify other types
190192

191-
GT = TypeVar("GT", bound=GraphQLType)
193+
GT = TypeVar("GT", bound=GraphQLType, covariant=True)
192194

193195

194196
class GraphQLWrappingType(GraphQLType, Generic[GT]):
@@ -1609,7 +1611,7 @@ def is_required_input_field(field: GraphQLInputField) -> bool:
16091611
# Wrapper types
16101612

16111613

1612-
class GraphQLList(Generic[GT], GraphQLWrappingType[GT]):
1614+
class GraphQLList(GraphQLWrappingType[GT]):
16131615
"""List Type Wrapper
16141616
16151617
A list is a wrapping type which points to another type. Lists are often created
@@ -1645,10 +1647,10 @@ def assert_list_type(type_: Any) -> GraphQLList:
16451647
return type_
16461648

16471649

1648-
GNT = TypeVar("GNT", bound="GraphQLNullableType")
1650+
GNT = TypeVar("GNT", bound="GraphQLNullableType", covariant=True)
16491651

16501652

1651-
class GraphQLNonNull(GraphQLWrappingType[GNT], Generic[GNT]):
1653+
class GraphQLNonNull(GraphQLWrappingType[GNT]):
16521654
"""Non-Null Type Wrapper
16531655
16541656
A non-null is a wrapping type which points to another type. Non-null types enforce
@@ -1680,41 +1682,108 @@ def __str__(self) -> str:
16801682
return f"{self.of_type}!"
16811683

16821684

1683-
def is_non_null_type(type_: Any) -> TypeGuard[GraphQLNonNull]:
1684-
return isinstance(type_, GraphQLNonNull)
1685-
1686-
1687-
def assert_non_null_type(type_: Any) -> GraphQLNonNull:
1688-
if not is_non_null_type(type_):
1689-
raise TypeError(f"Expected {type_} to be a GraphQL Non-Null type.")
1690-
return type_
1691-
1692-
16931685
# These types can all accept null as a value.
16941686

1695-
graphql_nullable_types = (
1687+
GraphQLNullableType: TypeAlias = Union[
16961688
GraphQLScalarType,
16971689
GraphQLObjectType,
16981690
GraphQLInterfaceType,
16991691
GraphQLUnionType,
17001692
GraphQLEnumType,
17011693
GraphQLInputObjectType,
17021694
GraphQLList,
1703-
)
1695+
]
17041696

1705-
GraphQLNullableType: TypeAlias = Union[
1697+
1698+
# These types may be used as input types for arguments and directives.
1699+
1700+
GraphQLNullableInputType: TypeAlias = Union[
1701+
GraphQLScalarType,
1702+
GraphQLEnumType,
1703+
GraphQLInputObjectType,
1704+
# actually GraphQLList[GraphQLInputType], but we can't recurse
1705+
GraphQLList,
1706+
]
1707+
1708+
GraphQLInputType: TypeAlias = Union[
1709+
GraphQLNullableInputType, GraphQLNonNull[GraphQLNullableInputType]
1710+
]
1711+
1712+
1713+
# These types may be used as output types as the result of fields.
1714+
1715+
GraphQLNullableOutputType: TypeAlias = Union[
17061716
GraphQLScalarType,
17071717
GraphQLObjectType,
17081718
GraphQLInterfaceType,
17091719
GraphQLUnionType,
17101720
GraphQLEnumType,
1711-
GraphQLInputObjectType,
1721+
# actually GraphQLList[GraphQLOutputType], but we can't recurse
17121722
GraphQLList,
17131723
]
17141724

1725+
GraphQLOutputType: TypeAlias = Union[
1726+
GraphQLNullableOutputType, GraphQLNonNull[GraphQLNullableOutputType]
1727+
]
1728+
1729+
1730+
# Predicates and Assertions
1731+
1732+
1733+
def is_input_type(type_: Any) -> TypeGuard[GraphQLInputType]:
1734+
return isinstance(
1735+
type_, (GraphQLScalarType, GraphQLEnumType, GraphQLInputObjectType)
1736+
) or (isinstance(type_, GraphQLWrappingType) and is_input_type(type_.of_type))
1737+
1738+
1739+
def assert_input_type(type_: Any) -> GraphQLInputType:
1740+
if not is_input_type(type_):
1741+
raise TypeError(f"Expected {type_} to be a GraphQL input type.")
1742+
return type_
1743+
1744+
1745+
def is_output_type(type_: Any) -> TypeGuard[GraphQLOutputType]:
1746+
return isinstance(
1747+
type_,
1748+
(
1749+
GraphQLScalarType,
1750+
GraphQLObjectType,
1751+
GraphQLInterfaceType,
1752+
GraphQLUnionType,
1753+
GraphQLEnumType,
1754+
),
1755+
) or (isinstance(type_, GraphQLWrappingType) and is_output_type(type_.of_type))
1756+
1757+
1758+
def assert_output_type(type_: Any) -> GraphQLOutputType:
1759+
if not is_output_type(type_):
1760+
raise TypeError(f"Expected {type_} to be a GraphQL output type.")
1761+
return type_
1762+
1763+
1764+
def is_non_null_type(type_: Any) -> TypeGuard[GraphQLNonNull]:
1765+
return isinstance(type_, GraphQLNonNull)
1766+
1767+
1768+
def assert_non_null_type(type_: Any) -> GraphQLNonNull:
1769+
if not is_non_null_type(type_):
1770+
raise TypeError(f"Expected {type_} to be a GraphQL Non-Null type.")
1771+
return type_
1772+
17151773

17161774
def is_nullable_type(type_: Any) -> TypeGuard[GraphQLNullableType]:
1717-
return isinstance(type_, graphql_nullable_types)
1775+
return isinstance(
1776+
type_,
1777+
(
1778+
GraphQLScalarType,
1779+
GraphQLObjectType,
1780+
GraphQLInterfaceType,
1781+
GraphQLUnionType,
1782+
GraphQLEnumType,
1783+
GraphQLInputObjectType,
1784+
GraphQLList,
1785+
),
1786+
)
17181787

17191788

17201789
def assert_nullable_type(type_: Any) -> GraphQLNullableType:
@@ -1747,59 +1816,6 @@ def get_nullable_type(
17471816
return cast(Optional[GraphQLNullableType], type_)
17481817

17491818

1750-
# These types may be used as input types for arguments and directives.
1751-
1752-
graphql_input_types = (GraphQLScalarType, GraphQLEnumType, GraphQLInputObjectType)
1753-
1754-
GraphQLInputType: TypeAlias = Union[
1755-
GraphQLScalarType, GraphQLEnumType, GraphQLInputObjectType, GraphQLWrappingType
1756-
]
1757-
1758-
1759-
def is_input_type(type_: Any) -> TypeGuard[GraphQLInputType]:
1760-
return isinstance(type_, graphql_input_types) or (
1761-
isinstance(type_, GraphQLWrappingType) and is_input_type(type_.of_type)
1762-
)
1763-
1764-
1765-
def assert_input_type(type_: Any) -> GraphQLInputType:
1766-
if not is_input_type(type_):
1767-
raise TypeError(f"Expected {type_} to be a GraphQL input type.")
1768-
return type_
1769-
1770-
1771-
# These types may be used as output types as the result of fields.
1772-
1773-
graphql_output_types = (
1774-
GraphQLScalarType,
1775-
GraphQLObjectType,
1776-
GraphQLInterfaceType,
1777-
GraphQLUnionType,
1778-
GraphQLEnumType,
1779-
)
1780-
1781-
GraphQLOutputType: TypeAlias = Union[
1782-
GraphQLScalarType,
1783-
GraphQLObjectType,
1784-
GraphQLInterfaceType,
1785-
GraphQLUnionType,
1786-
GraphQLEnumType,
1787-
GraphQLWrappingType,
1788-
]
1789-
1790-
1791-
def is_output_type(type_: Any) -> TypeGuard[GraphQLOutputType]:
1792-
return isinstance(type_, graphql_output_types) or (
1793-
isinstance(type_, GraphQLWrappingType) and is_output_type(type_.of_type)
1794-
)
1795-
1796-
1797-
def assert_output_type(type_: Any) -> GraphQLOutputType:
1798-
if not is_output_type(type_):
1799-
raise TypeError(f"Expected {type_} to be a GraphQL output type.")
1800-
return type_
1801-
1802-
18031819
# These named types do not include modifiers like List or NonNull.
18041820

18051821
GraphQLNamedInputType: TypeAlias = Union[
@@ -1847,13 +1863,11 @@ def get_named_type(type_: Optional[GraphQLType]) -> Optional[GraphQLNamedType]:
18471863

18481864
# These types may describe types which may be leaf values.
18491865

1850-
graphql_leaf_types = (GraphQLScalarType, GraphQLEnumType)
1851-
18521866
GraphQLLeafType: TypeAlias = Union[GraphQLScalarType, GraphQLEnumType]
18531867

18541868

18551869
def is_leaf_type(type_: Any) -> TypeGuard[GraphQLLeafType]:
1856-
return isinstance(type_, graphql_leaf_types)
1870+
return isinstance(type_, (GraphQLScalarType, GraphQLEnumType))
18571871

18581872

18591873
def assert_leaf_type(type_: Any) -> GraphQLLeafType:
@@ -1864,15 +1878,15 @@ def assert_leaf_type(type_: Any) -> GraphQLLeafType:
18641878

18651879
# These types may describe the parent context of a selection set.
18661880

1867-
graphql_composite_types = (GraphQLObjectType, GraphQLInterfaceType, GraphQLUnionType)
1868-
18691881
GraphQLCompositeType: TypeAlias = Union[
18701882
GraphQLObjectType, GraphQLInterfaceType, GraphQLUnionType
18711883
]
18721884

18731885

18741886
def is_composite_type(type_: Any) -> TypeGuard[GraphQLCompositeType]:
1875-
return isinstance(type_, graphql_composite_types)
1887+
return isinstance(
1888+
type_, (GraphQLObjectType, GraphQLInterfaceType, GraphQLUnionType)
1889+
)
18761890

18771891

18781892
def assert_composite_type(type_: Any) -> GraphQLType:
@@ -1883,13 +1897,11 @@ def assert_composite_type(type_: Any) -> GraphQLType:
18831897

18841898
# These types may describe abstract types.
18851899

1886-
graphql_abstract_types = (GraphQLInterfaceType, GraphQLUnionType)
1887-
18881900
GraphQLAbstractType: TypeAlias = Union[GraphQLInterfaceType, GraphQLUnionType]
18891901

18901902

18911903
def is_abstract_type(type_: Any) -> TypeGuard[GraphQLAbstractType]:
1892-
return isinstance(type_, graphql_abstract_types)
1904+
return isinstance(type_, (GraphQLInterfaceType, GraphQLUnionType))
18931905

18941906

18951907
def assert_abstract_type(type_: Any) -> GraphQLAbstractType:

src/graphql/utilities/type_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ def enter_argument(self, node: ArgumentNode) -> None:
201201

202202
# noinspection PyUnusedLocal
203203
def enter_list_value(self, node: ListValueNode) -> None:
204-
list_type = get_nullable_type(self.get_input_type()) # type: ignore
204+
list_type = get_nullable_type(self.get_input_type())
205205
item_type = list_type.of_type if is_list_type(list_type) else list_type
206206
# List positions never have a default value.
207207
self._default_value_stack.append(Undefined)

src/graphql/validation/rules/values_of_correct_type.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class ValuesOfCorrectTypeRule(ValidationRule):
4545
def enter_list_value(self, node: ListValueNode, *_args: Any) -> VisitorAction:
4646
# Note: TypeInfo will traverse into a list's item type, so look to the parent
4747
# input type to check if it is a list.
48-
type_ = get_nullable_type(self.context.get_parent_input_type()) # type: ignore
48+
type_ = get_nullable_type(self.context.get_parent_input_type())
4949
if not is_list_type(type_):
5050
self.is_valid_value_node(node)
5151
return SKIP # Don't traverse further.

0 commit comments

Comments
 (0)