From 3943353e66175f069ffdfa54fb8664e666a6b7ee Mon Sep 17 00:00:00 2001 From: shrouxm Date: Thu, 4 May 2023 13:58:36 -0700 Subject: [PATCH 1/4] types: add option for strict connection types --- graphene/relay/connection.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/graphene/relay/connection.py b/graphene/relay/connection.py index ea497367..69cbd60b 100644 --- a/graphene/relay/connection.py +++ b/graphene/relay/connection.py @@ -13,12 +13,12 @@ def get_edge_class( - connection_class: Type["Connection"], _node: Type[AbstractNode], base_name: str + connection_class: Type["Connection"], _node: Type[AbstractNode], base_name: str, strict_types: bool = False ): edge_class = getattr(connection_class, "Edge", None) class EdgeBase: - node = Field(_node, description="The item at the end of the edge") + node = Field(NonNull(_node) if strict_types else _node, description="The item at the end of the edge") cursor = String(required=True, description="A cursor for use in pagination") class EdgeMeta: @@ -83,7 +83,7 @@ class Meta: abstract = True @classmethod - def __init_subclass_with_meta__(cls, node=None, name=None, _meta=None, **options): + def __init_subclass_with_meta__(cls, node=None, name=None, strict_types=False, _meta=None, **options): if not _meta: _meta = ConnectionOptions(cls) assert node, f"You have to provide a node in {cls.__name__}.Meta" @@ -111,10 +111,10 @@ def __init_subclass_with_meta__(cls, node=None, name=None, _meta=None, **options ) if "edges" not in _meta.fields: - edge_class = get_edge_class(cls, node, base_name) # type: ignore + edge_class = get_edge_class(cls, node, base_name, strict_types) # type: ignore cls.Edge = edge_class _meta.fields["edges"] = Field( - NonNull(List(edge_class)), + NonNull(List(NonNull(edge_class) if strict_types else edge_class)), description="Contains the nodes in this connection.", ) From 692e98589f04f287ca0b0d414c9239f44f8a7e05 Mon Sep 17 00:00:00 2001 From: shrouxm Date: Thu, 18 May 2023 09:13:58 -0700 Subject: [PATCH 2/4] chore: appease linter --- graphene/relay/connection.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/graphene/relay/connection.py b/graphene/relay/connection.py index 69cbd60b..f3b1322b 100644 --- a/graphene/relay/connection.py +++ b/graphene/relay/connection.py @@ -13,12 +13,18 @@ def get_edge_class( - connection_class: Type["Connection"], _node: Type[AbstractNode], base_name: str, strict_types: bool = False + connection_class: Type["Connection"], + _node: Type[AbstractNode], + base_name: str, + strict_types: bool = False, ): edge_class = getattr(connection_class, "Edge", None) class EdgeBase: - node = Field(NonNull(_node) if strict_types else _node, description="The item at the end of the edge") + node = Field( + NonNull(_node) if strict_types else _node, + description="The item at the end of the edge" + ) cursor = String(required=True, description="A cursor for use in pagination") class EdgeMeta: @@ -83,7 +89,9 @@ class Meta: abstract = True @classmethod - def __init_subclass_with_meta__(cls, node=None, name=None, strict_types=False, _meta=None, **options): + def __init_subclass_with_meta__( + cls, node=None, name=None, strict_types=False, _meta=None, **options + ): if not _meta: _meta = ConnectionOptions(cls) assert node, f"You have to provide a node in {cls.__name__}.Meta" From cf29f5de15f6d905a3539e156dca7c4ce8f9f40d Mon Sep 17 00:00:00 2001 From: shrouxm Date: Thu, 8 Jun 2023 15:32:32 -0700 Subject: [PATCH 3/4] chore: appease linter --- graphene/relay/connection.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graphene/relay/connection.py b/graphene/relay/connection.py index f3b1322b..cc7d2da0 100644 --- a/graphene/relay/connection.py +++ b/graphene/relay/connection.py @@ -22,8 +22,8 @@ def get_edge_class( class EdgeBase: node = Field( - NonNull(_node) if strict_types else _node, - description="The item at the end of the edge" + NonNull(_node) if strict_types else _node, + description="The item at the end of the edge", ) cursor = String(required=True, description="A cursor for use in pagination") From 4077084d338e5a01bb420ee57186bf64d37fbd7b Mon Sep 17 00:00:00 2001 From: shrouxm Date: Thu, 8 Jun 2023 15:32:38 -0700 Subject: [PATCH 4/4] test: add test --- graphene/relay/tests/test_connection.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/graphene/relay/tests/test_connection.py b/graphene/relay/tests/test_connection.py index d45eea96..9c8b89d1 100644 --- a/graphene/relay/tests/test_connection.py +++ b/graphene/relay/tests/test_connection.py @@ -299,3 +299,20 @@ def resolve_test_connection(root, info, **args): executed = schema.execute("{ testConnection { edges { cursor } } }") assert not executed.errors assert executed.data == {"testConnection": {"edges": []}} + + +def test_connectionfield_strict_types(): + class MyObjectConnection(Connection): + class Meta: + node = MyObject + strict_types = True + + connection_field = ConnectionField(MyObjectConnection) + edges_field_type = connection_field.type._meta.fields["edges"].type + assert isinstance(edges_field_type, NonNull) + + edges_list_element_type = edges_field_type.of_type.of_type + assert isinstance(edges_list_element_type, NonNull) + + node_field = edges_list_element_type.of_type._meta.fields["node"] + assert isinstance(node_field.type, NonNull)