Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions graphene/relay/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@

from graphql_relay import connection_from_array

import inspect

from ..types import Boolean, Enum, Int, Interface, List, NonNull, Scalar, String, Union
from ..types.field import Field
from ..types.objecttype import ObjectType, ObjectTypeOptions
from ..types.utils import get_type
from ..utils.thenables import maybe_thenable
from .node import is_node, AbstractNode

Expand Down Expand Up @@ -81,7 +84,15 @@ def page_info_adapter(startCursor, endCursor, hasPreviousPage, hasNextPage):


class ConnectionOptions(ObjectTypeOptions):
node = None
_node = None

@property
def node(self):
return get_type(self._node)

@node.setter
def node(self, value):
self._node = value


class Connection(ObjectType):
Expand All @@ -95,11 +106,27 @@ def __init_subclass_with_meta__(
if not _meta:
_meta = ConnectionOptions(cls)
assert node, f"You have to provide a node in {cls.__name__}.Meta"
assert isinstance(node, NonNull) or issubclass(
node, (Scalar, Enum, ObjectType, Interface, Union, NonNull)
assert (
isinstance(node, (str, NonNull))
or inspect.isfunction(node)
or isinstance(node, partial)
or (
inspect.isclass(node)
and issubclass(
node, (Scalar, Enum, ObjectType, Interface, Union, NonNull)
)
)
), f'Received incompatible node "{node}" for Connection {cls.__name__}.'

base_name = re.sub("Connection$", "", name or cls.__name__) or node._meta.name
base_name = re.sub("Connection$", "", name or cls.__name__) or (
node._meta.name
if hasattr(node, "_meta")
else (
node.split(".")[-1]
if isinstance(node, str)
else get_type(node)._meta.name
)
)
if not name:
name = f"{base_name}Connection"

Expand Down
31 changes: 31 additions & 0 deletions graphene/relay/tests/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,34 @@ class Meta:

node_field = edges_list_element_type.of_type._meta.fields["node"]
assert isinstance(node_field.type, NonNull)


def test_connection_with_lazy_string_node():
class MyLazyStringConnection(Connection):
class Meta:
node = "graphene.relay.tests.test_connection.MyObject"

assert MyLazyStringConnection._meta.name == "MyLazyStringConnection"
assert MyLazyStringConnection._meta.node == MyObject
edge_fields = MyLazyStringConnection.Edge._meta.fields
assert edge_fields["node"].type == MyObject


def test_connection_with_lazy_callable_node():
class MyLazyCallableConnection(Connection):
class Meta:
node = lambda: MyObject # noqa: E731

assert MyLazyCallableConnection._meta.name == "MyLazyCallableConnection"
assert MyLazyCallableConnection._meta.node == MyObject
edge_fields = MyLazyCallableConnection.Edge._meta.fields
assert edge_fields["node"].type == MyObject


def test_connection_named_connection_with_lazy_string_node():
class Connection(globals()["Connection"]):
class Meta:
node = "graphene.relay.tests.test_connection.MyObject"

assert Connection._meta.name == "MyObjectConnection"
assert Connection._meta.node == MyObject