Skip to content

Commit 00b9f25

Browse files
committed
Moving DSLSelectable and DSLSelectableWithAlias up, DSLSelector down
1 parent 408e1f1 commit 00b9f25

File tree

1 file changed

+135
-135
lines changed

1 file changed

+135
-135
lines changed

gql/dsl.py

Lines changed: 135 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -329,78 +329,6 @@ def __getattr__(self, name: str) -> "DSLType":
329329
return DSLType(type_def, self)
330330

331331

332-
class DSLSelector(ABC):
333-
"""DSLSelector is an abstract class which defines the
334-
:meth:`select <gql.dsl.DSLSelector.select>` method to select
335-
children fields in the query.
336-
337-
Inherited by
338-
:class:`DSLRootFieldSelector <gql.dsl.DSLRootFieldSelector>`,
339-
:class:`DSLFieldSelector <gql.dsl.DSLFieldSelector>`
340-
:class:`DSLFragmentSelector <gql.dsl.DSLFragmentSelector>`
341-
"""
342-
343-
selection_set: SelectionSetNode
344-
345-
def __init__(
346-
self,
347-
*fields: "DSLSelectable",
348-
**fields_with_alias: "DSLSelectableWithAlias",
349-
):
350-
""":meta private:"""
351-
self.selection_set = SelectionSetNode(selections=())
352-
353-
if fields or fields_with_alias:
354-
self.select(*fields, **fields_with_alias)
355-
356-
@abstractmethod
357-
def is_valid_field(self, field: "DSLSelectable") -> bool:
358-
raise NotImplementedError(
359-
"Any DSLSelector subclass must have a is_valid_field method"
360-
) # pragma: no cover
361-
362-
def select(
363-
self,
364-
*fields: "DSLSelectable",
365-
**fields_with_alias: "DSLSelectableWithAlias",
366-
) -> Any:
367-
r"""Select the fields which should be added.
368-
369-
:param \*fields: fields or fragments
370-
:type \*fields: DSLSelectable
371-
:param \**fields_with_alias: fields or fragments with alias as key
372-
:type \**fields_with_alias: DSLSelectable
373-
374-
:raises TypeError: if an argument is not an instance of :class:`DSLSelectable`
375-
:raises graphql.error.GraphQLError: if an argument is not a valid field
376-
"""
377-
# Concatenate fields without and with alias
378-
added_fields: Tuple["DSLSelectable", ...] = DSLField.get_aliased_fields(
379-
fields, fields_with_alias
380-
)
381-
382-
# Check that each field is valid
383-
for field in added_fields:
384-
if not isinstance(field, DSLSelectable):
385-
raise TypeError(
386-
"Fields should be instances of DSLSelectable. "
387-
f"Received: {type(field)}"
388-
)
389-
390-
if not self.is_valid_field(field):
391-
raise GraphQLError(f"Invalid field for {self!r}: {field!r}")
392-
393-
# Get a list of AST Nodes for each added field
394-
added_selections: Tuple[
395-
Union[FieldNode, InlineFragmentNode, FragmentSpreadNode], ...
396-
] = tuple(field.ast_field for field in added_fields)
397-
398-
# Update the current selection list with new selections
399-
self.selection_set.selections = self.selection_set.selections + added_selections
400-
401-
log.debug(f"Added fields: {added_fields} in {self!r}")
402-
403-
404332
class DSLDirective:
405333
"""The DSLDirective represents a GraphQL directive for the DSL code.
406334
@@ -612,6 +540,138 @@ def directives_ast(self) -> Tuple[DirectiveNode, ...]:
612540
return tuple(directive.ast_directive for directive in self._directives)
613541

614542

543+
class DSLSelectable(DSLDirectable):
544+
"""DSLSelectable is an abstract class which indicates that
545+
the subclasses can be used as arguments of the
546+
:meth:`select <gql.dsl.DSLSelector.select>` method.
547+
548+
Inherited by
549+
:class:`DSLField <gql.dsl.DSLField>`,
550+
:class:`DSLFragment <gql.dsl.DSLFragment>`
551+
:class:`DSLInlineFragment <gql.dsl.DSLInlineFragment>`
552+
"""
553+
554+
ast_field: Union[FieldNode, InlineFragmentNode, FragmentSpreadNode]
555+
556+
@staticmethod
557+
def get_aliased_fields(
558+
fields: Iterable["DSLSelectable"],
559+
fields_with_alias: Dict[str, "DSLSelectableWithAlias"],
560+
) -> Tuple["DSLSelectable", ...]:
561+
"""
562+
:meta private:
563+
564+
Concatenate all the fields (with or without alias) in a Tuple.
565+
566+
Set the requested alias for the fields with alias.
567+
"""
568+
569+
return (
570+
*fields,
571+
*(field.alias(alias) for alias, field in fields_with_alias.items()),
572+
)
573+
574+
def __str__(self) -> str:
575+
return print_ast(self.ast_field)
576+
577+
578+
class DSLSelectableWithAlias(DSLSelectable):
579+
"""DSLSelectableWithAlias is an abstract class which indicates that
580+
the subclasses can be selected with an alias.
581+
"""
582+
583+
ast_field: FieldNode
584+
585+
def alias(self, alias: str) -> Self:
586+
"""Set an alias
587+
588+
.. note::
589+
You can also pass the alias directly at the
590+
:meth:`select <gql.dsl.DSLSelector.select>` method.
591+
:code:`ds.Query.human.select(my_name=ds.Character.name)` is equivalent to:
592+
:code:`ds.Query.human.select(ds.Character.name.alias("my_name"))`
593+
594+
:param alias: the alias
595+
:type alias: str
596+
:return: itself
597+
"""
598+
599+
self.ast_field.alias = NameNode(value=alias)
600+
return self
601+
602+
603+
class DSLSelector(ABC):
604+
"""DSLSelector is an abstract class which defines the
605+
:meth:`select <gql.dsl.DSLSelector.select>` method to select
606+
children fields in the query.
607+
608+
Inherited by
609+
:class:`DSLRootFieldSelector <gql.dsl.DSLRootFieldSelector>`,
610+
:class:`DSLFieldSelector <gql.dsl.DSLFieldSelector>`
611+
:class:`DSLFragmentSelector <gql.dsl.DSLFragmentSelector>`
612+
"""
613+
614+
selection_set: SelectionSetNode
615+
616+
def __init__(
617+
self,
618+
*fields: DSLSelectable,
619+
**fields_with_alias: DSLSelectableWithAlias,
620+
):
621+
""":meta private:"""
622+
self.selection_set = SelectionSetNode(selections=())
623+
624+
if fields or fields_with_alias:
625+
self.select(*fields, **fields_with_alias)
626+
627+
@abstractmethod
628+
def is_valid_field(self, field: DSLSelectable) -> bool:
629+
raise NotImplementedError(
630+
"Any DSLSelector subclass must have a is_valid_field method"
631+
) # pragma: no cover
632+
633+
def select(
634+
self,
635+
*fields: DSLSelectable,
636+
**fields_with_alias: DSLSelectableWithAlias,
637+
) -> Any:
638+
r"""Select the fields which should be added.
639+
640+
:param \*fields: fields or fragments
641+
:type \*fields: DSLSelectable
642+
:param \**fields_with_alias: fields or fragments with alias as key
643+
:type \**fields_with_alias: DSLSelectable
644+
645+
:raises TypeError: if an argument is not an instance of :class:`DSLSelectable`
646+
:raises graphql.error.GraphQLError: if an argument is not a valid field
647+
"""
648+
# Concatenate fields without and with alias
649+
added_fields: Tuple[DSLSelectable, ...] = DSLField.get_aliased_fields(
650+
fields, fields_with_alias
651+
)
652+
653+
# Check that each field is valid
654+
for field in added_fields:
655+
if not isinstance(field, DSLSelectable):
656+
raise TypeError(
657+
"Fields should be instances of DSLSelectable. "
658+
f"Received: {type(field)}"
659+
)
660+
661+
if not self.is_valid_field(field):
662+
raise GraphQLError(f"Invalid field for {self!r}: {field!r}")
663+
664+
# Get a list of AST Nodes for each added field
665+
added_selections: Tuple[
666+
Union[FieldNode, InlineFragmentNode, FragmentSpreadNode], ...
667+
] = tuple(field.ast_field for field in added_fields)
668+
669+
# Update the current selection list with new selections
670+
self.selection_set.selections = self.selection_set.selections + added_selections
671+
672+
log.debug(f"Added fields: {added_fields} in {self!r}")
673+
674+
615675
class DSLExecutable(DSLSelector, DSLDirectable):
616676
"""Interface for the root elements which can be executed
617677
in the :func:`dsl_gql <gql.dsl.dsl_gql>` function
@@ -635,8 +695,8 @@ def executable_ast(self):
635695

636696
def __init__(
637697
self,
638-
*fields: "DSLSelectable",
639-
**fields_with_alias: "DSLSelectableWithAlias",
698+
*fields: DSLSelectable,
699+
**fields_with_alias: DSLSelectableWithAlias,
640700
):
641701
r"""Given arguments of type :class:`DSLSelectable` containing GraphQL requests,
642702
generate an operation which can be converted to a Document
@@ -673,7 +733,7 @@ class DSLRootFieldSelector(DSLSelector):
673733
:class:`DSLOperation <gql.dsl.DSLOperation>`
674734
"""
675735

676-
def is_valid_field(self, field: "DSLSelectable") -> bool:
736+
def is_valid_field(self, field: DSLSelectable) -> bool:
677737
"""Check that a field is valid for a root field.
678738
679739
For operations, the fields arguments should be fields of root GraphQL types
@@ -940,41 +1000,6 @@ def __repr__(self) -> str:
9401000
return f"<{self.__class__.__name__} {self._type!r}>"
9411001

9421002

943-
class DSLSelectable(DSLDirectable):
944-
"""DSLSelectable is an abstract class which indicates that
945-
the subclasses can be used as arguments of the
946-
:meth:`select <gql.dsl.DSLSelector.select>` method.
947-
948-
Inherited by
949-
:class:`DSLField <gql.dsl.DSLField>`,
950-
:class:`DSLFragment <gql.dsl.DSLFragment>`
951-
:class:`DSLInlineFragment <gql.dsl.DSLInlineFragment>`
952-
"""
953-
954-
ast_field: Union[FieldNode, InlineFragmentNode, FragmentSpreadNode]
955-
956-
@staticmethod
957-
def get_aliased_fields(
958-
fields: Iterable["DSLSelectable"],
959-
fields_with_alias: Dict[str, "DSLSelectableWithAlias"],
960-
) -> Tuple["DSLSelectable", ...]:
961-
"""
962-
:meta private:
963-
964-
Concatenate all the fields (with or without alias) in a Tuple.
965-
966-
Set the requested alias for the fields with alias.
967-
"""
968-
969-
return (
970-
*fields,
971-
*(field.alias(alias) for alias, field in fields_with_alias.items()),
972-
)
973-
974-
def __str__(self) -> str:
975-
return print_ast(self.ast_field)
976-
977-
9781003
class DSLFragmentSelector(DSLSelector):
9791004
"""Class used to define the
9801005
:meth:`is_valid_field <gql.dsl.DSLFragmentSelector.is_valid_field>` method
@@ -1041,31 +1066,6 @@ def is_valid_field(self, field: DSLSelectable) -> bool:
10411066
return False
10421067

10431068

1044-
class DSLSelectableWithAlias(DSLSelectable):
1045-
"""DSLSelectableWithAlias is an abstract class which indicates that
1046-
the subclasses can be selected with an alias.
1047-
"""
1048-
1049-
ast_field: FieldNode
1050-
1051-
def alias(self, alias: str) -> Self:
1052-
"""Set an alias
1053-
1054-
.. note::
1055-
You can also pass the alias directly at the
1056-
:meth:`select <gql.dsl.DSLSelector.select>` method.
1057-
:code:`ds.Query.human.select(my_name=ds.Character.name)` is equivalent to:
1058-
:code:`ds.Query.human.select(ds.Character.name.alias("my_name"))`
1059-
1060-
:param alias: the alias
1061-
:type alias: str
1062-
:return: itself
1063-
"""
1064-
1065-
self.ast_field.alias = NameNode(value=alias)
1066-
return self
1067-
1068-
10691069
class DSLField(DSLSelectableWithAlias, DSLFieldSelector):
10701070
"""The DSLField represents a GraphQL field for the DSL code.
10711071

0 commit comments

Comments
 (0)