Skip to content

Commit

Permalink
feat(relay): add option for strict connection types (#1504)
Browse files Browse the repository at this point in the history
* types: add option for strict connection types

* chore: appease linter

* chore: appease linter

* test: add test

---------

Co-authored-by: Erik Wrede <erikwrede@users.noreply.github.com>
  • Loading branch information
shrouxm and erikwrede authored Jul 26, 2023
1 parent 6b8cd2d commit ea7ccc3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
18 changes: 13 additions & 5 deletions graphene/relay/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@


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:
Expand Down Expand Up @@ -83,7 +89,9 @@ 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"
Expand Down Expand Up @@ -111,10 +119,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.",
)

Expand Down
17 changes: 17 additions & 0 deletions graphene/relay/tests/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit ea7ccc3

Please sign in to comment.