@@ -245,7 +245,7 @@ def __init__(
245
245
self .variable_definitions : DSLVariableDefinitions = DSLVariableDefinitions ()
246
246
247
247
# Concatenate fields without and with alias
248
- all_fields : Tuple ["DSLField " , ...] = DSLField .get_aliased_fields (
248
+ all_fields : Tuple ["DSLSelection " , ...] = DSLField .get_aliased_fields (
249
249
fields , fields_with_alias
250
250
)
251
251
@@ -265,7 +265,7 @@ def __init__(
265
265
)
266
266
267
267
self .selection_set : SelectionSetNode = SelectionSetNode (
268
- selections = FrozenList (DSLField .get_ast_fields (all_fields ))
268
+ selections = FrozenList (DSLSelection .get_ast_fields (all_fields ))
269
269
)
270
270
271
271
@@ -397,56 +397,35 @@ def __repr__(self) -> str:
397
397
return f"<{ self .__class__ .__name__ } { self ._type !r} >"
398
398
399
399
400
- class DSLField :
401
- """The DSLField represents a GraphQL field for the DSL code.
402
-
403
- Instances of this class are generated for you automatically as attributes
404
- of the :class:`DSLType`
400
+ class DSLSelection (ABC ):
401
+ """DSLSelection is an abstract class which define the
402
+ :meth:`select <gql.dsl.DSLSelection.select>` method to select
403
+ children fields in the query.
405
404
406
- If this field contains children fields, then you need to select which ones
407
- you want in the request using the :meth:`select <gql.dsl. DSLField.select> `
408
- method.
405
+ subclasses:
406
+ :class:` DSLField`
407
+ :class:`DSLFragment`
409
408
"""
410
409
411
410
_type : Union [GraphQLObjectType , GraphQLInterfaceType ]
412
- ast_field : FieldNode
413
- field : GraphQLField
414
-
415
- def __init__ (
416
- self ,
417
- name : str ,
418
- graphql_type : Union [GraphQLObjectType , GraphQLInterfaceType ],
419
- graphql_field : GraphQLField ,
420
- ):
421
- """Initialize the DSLField.
422
-
423
- .. warning::
424
- Don't instantiate this class yourself.
425
- Use attributes of the :class:`DSLType` instead.
426
-
427
- :param name: the name of the field
428
- :param graphql_type: the GraphQL type definition from the schema
429
- :param graphql_field: the GraphQL field definition from the schema
430
- """
431
- self ._type = graphql_type
432
- self .field = graphql_field
433
- self .ast_field = FieldNode (name = NameNode (value = name ), arguments = FrozenList ())
434
- log .debug (f"Creating { self !r} " )
411
+ ast_field : Union [FieldNode , InlineFragmentNode ]
435
412
436
413
@staticmethod
437
- def get_ast_fields (fields : Iterable ["DSLField" ]) -> List [FieldNode ]:
414
+ def get_ast_fields (
415
+ fields : Iterable ["DSLSelection" ],
416
+ ) -> List [Union [FieldNode , InlineFragmentNode ]]:
438
417
"""
439
418
:meta private:
440
419
441
420
Equivalent to: :code:`[field.ast_field for field in fields]`
442
421
But with a type check for each field in the list.
443
422
444
423
:raises TypeError: if any of the provided fields are not instances
445
- of the :class:`DSLField ` class.
424
+ of the :class:`DSLSelection ` class.
446
425
"""
447
426
ast_fields = []
448
427
for field in fields :
449
- if isinstance (field , DSLField ):
428
+ if isinstance (field , DSLSelection ):
450
429
ast_fields .append (field .ast_field )
451
430
else :
452
431
raise TypeError (f'Received incompatible field: "{ field } ".' )
@@ -455,8 +434,8 @@ def get_ast_fields(fields: Iterable["DSLField"]) -> List[FieldNode]:
455
434
456
435
@staticmethod
457
436
def get_aliased_fields (
458
- fields : Iterable ["DSLField " ], fields_with_alias : Dict [str , "DSLField" ]
459
- ) -> Tuple ["DSLField " , ...]:
437
+ fields : Iterable ["DSLSelection " ], fields_with_alias : Dict [str , "DSLField" ]
438
+ ) -> Tuple ["DSLSelection " , ...]:
460
439
"""
461
440
:meta private:
462
441
@@ -471,30 +450,32 @@ def get_aliased_fields(
471
450
)
472
451
473
452
def select (
474
- self , * fields : "DSLField " , ** fields_with_alias : "DSLField"
475
- ) -> "DSLField " :
453
+ self , * fields : "DSLSelection " , ** fields_with_alias : "DSLField"
454
+ ) -> "DSLSelection " :
476
455
r"""Select the new children fields
477
456
that we want to receive in the request.
478
457
479
458
If used multiple times, we will add the new children fields
480
459
to the existing children fields.
481
460
482
461
:param \*fields: new children fields
483
- :type \*fields: DSLField
462
+ :type \*fields: DSLSelection ( DSLField or DSLFragment)
484
463
:param \**fields_with_alias: new children fields with alias as key
485
464
:type \**fields_with_alias: DSLField
486
465
:return: itself
487
466
488
467
:raises TypeError: if any of the provided fields are not instances
489
- of the :class:`DSLField ` class.
468
+ of the :class:`DSLSelection ` class.
490
469
"""
491
470
492
471
# Concatenate fields without and with alias
493
- added_fields : Tuple ["DSLField " , ...] = self .get_aliased_fields (
472
+ added_fields : Tuple ["DSLSelection " , ...] = self .get_aliased_fields (
494
473
fields , fields_with_alias
495
474
)
496
475
497
- added_selections : List [FieldNode ] = self .get_ast_fields (added_fields )
476
+ added_selections : List [
477
+ Union [FieldNode , InlineFragmentNode ]
478
+ ] = self .get_ast_fields (added_fields )
498
479
499
480
current_selection_set : Optional [SelectionSetNode ] = self .ast_field .selection_set
500
481
@@ -511,6 +492,58 @@ def select(
511
492
512
493
return self
513
494
495
+ @property
496
+ def type_name (self ):
497
+ """:meta private:"""
498
+ return self ._type .name
499
+
500
+ def __str__ (self ) -> str :
501
+ return print_ast (self .ast_field )
502
+
503
+
504
+ class DSLField (DSLSelection ):
505
+ """The DSLField represents a GraphQL field for the DSL code.
506
+
507
+ Instances of this class are generated for you automatically as attributes
508
+ of the :class:`DSLType`
509
+
510
+ If this field contains children fields, then you need to select which ones
511
+ you want in the request using the :meth:`select <gql.dsl.DSLField.select>`
512
+ method.
513
+ """
514
+
515
+ ast_field : FieldNode
516
+ field : GraphQLField
517
+
518
+ def __init__ (
519
+ self ,
520
+ name : str ,
521
+ graphql_type : Union [GraphQLObjectType , GraphQLInterfaceType ],
522
+ graphql_field : GraphQLField ,
523
+ ):
524
+ """Initialize the DSLField.
525
+
526
+ .. warning::
527
+ Don't instantiate this class yourself.
528
+ Use attributes of the :class:`DSLType` instead.
529
+
530
+ :param name: the name of the field
531
+ :param graphql_type: the GraphQL type definition from the schema
532
+ :param graphql_field: the GraphQL field definition from the schema
533
+ """
534
+ self ._type = graphql_type
535
+ self .field = graphql_field
536
+ self .ast_field = FieldNode (name = NameNode (value = name ), arguments = FrozenList ())
537
+ log .debug (f"Creating { self !r} " )
538
+
539
+ def select (
540
+ self , * fields : "DSLSelection" , ** fields_with_alias : "DSLField"
541
+ ) -> "DSLField" :
542
+ """Calling :meth:`select <gql.dsl.DSLSelection.select>` method with
543
+ corrected typing hints
544
+ """
545
+ return cast ("DSLField" , super ().select (* fields , ** fields_with_alias ))
546
+
514
547
def __call__ (self , ** kwargs ) -> "DSLField" :
515
548
return self .args (** kwargs )
516
549
@@ -519,7 +552,7 @@ def alias(self, alias: str) -> "DSLField":
519
552
520
553
.. note::
521
554
You can also pass the alias directly at the
522
- :meth:`select <gql.dsl.DSLField .select>` method.
555
+ :meth:`select <gql.dsl.DSLSelection .select>` method.
523
556
:code:`ds.Query.human.select(my_name=ds.Character.name)` is equivalent to:
524
557
:code:`ds.Query.human.select(ds.Character.name.alias("my_name"))`
525
558
@@ -579,34 +612,41 @@ def _get_argument(self, name: str) -> GraphQLArgument:
579
612
580
613
return arg
581
614
582
- @property
583
- def type_name (self ):
584
- """:meta private:"""
585
- return self ._type .name
615
+ def __repr__ (self ) -> str :
616
+ return (
617
+ f"<{ self .__class__ .__name__ } { self ._type .name } "
618
+ f"::{ self .ast_field .name .value } >"
619
+ )
586
620
587
- def __str__ (self ) -> str :
588
- return print_ast (self .ast_field )
589
621
590
- def __repr__ (self ) -> str :
591
- name = self ._type .name
592
- try :
593
- name += f"::{ self .ast_field .name .value } "
594
- except AttributeError :
595
- pass
596
- return f"<{ self .__class__ .__name__ } { name } >"
622
+ class DSLFragment (DSLSelection ):
597
623
624
+ ast_field : InlineFragmentNode
598
625
599
- class DSLFragment (DSLField ):
600
- def __init__ (
601
- self , type_condition : Optional [DSLType ] = None ,
602
- ):
603
- self .ast_field = InlineFragmentNode () # type: ignore
604
- if type_condition :
605
- self .on (type_condition )
626
+ def __init__ (self ):
627
+ self .ast_field = InlineFragmentNode ()
628
+
629
+ def select (
630
+ self , * fields : "DSLSelection" , ** fields_with_alias : "DSLField"
631
+ ) -> "DSLFragment" :
632
+ """Calling :meth:`select <gql.dsl.DSLSelection.select>` method with
633
+ corrected typing hints
634
+ """
635
+ return cast ("DSLFragment" , super ().select (* fields , ** fields_with_alias ))
606
636
607
637
def on (self , type_condition : DSLType ):
608
638
self ._type = type_condition ._type
609
- self .ast_field .type_condition = NamedTypeNode ( # type: ignore
639
+ self .ast_field .type_condition = NamedTypeNode (
610
640
name = NameNode (value = self ._type .name )
611
641
)
612
642
return self
643
+
644
+ def __repr__ (self ) -> str :
645
+ type_info = ""
646
+
647
+ try :
648
+ type_info += f" on { self ._type .name } "
649
+ except AttributeError :
650
+ pass
651
+
652
+ return f"<{ self .__class__ .__name__ } { type_info } >"
0 commit comments