@@ -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-
404332class 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+
615675class 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-
9781003class 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-
10691069class DSLField (DSLSelectableWithAlias , DSLFieldSelector ):
10701070 """The DSLField represents a GraphQL field for the DSL code.
10711071
0 commit comments