Skip to content

Commit 6faad38

Browse files
committed
DSL Add default method for variables
1 parent a4641d0 commit 6faad38

File tree

3 files changed

+101
-19
lines changed

3 files changed

+101
-19
lines changed

docs/advanced/dsl_module.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,35 @@ will generate a query equivalent to::
206206
}
207207
}
208208

209+
Variable arguments with a default value
210+
"""""""""""""""""""""""""""""""""""""""
211+
212+
If you want to provide a **default value** for your variable, you can use
213+
the :code:`default` method on a variable.
214+
215+
The following code:
216+
217+
.. code-block:: python
218+
219+
var = DSLVariableDefinitions()
220+
op = DSLMutation(
221+
ds.Mutation.createReview.args(
222+
review=var.review.default({"stars": 5, "commentary": "Wow!"}),
223+
episode=var.episode,
224+
).select(ds.Review.stars, ds.Review.commentary)
225+
)
226+
op.variable_definitions = var
227+
query = dsl_gql(op)
228+
229+
will generate a query equivalent to::
230+
231+
mutation ($review: ReviewInput = {stars: 5, commentary: "Wow!"}, $episode: Episode) {
232+
createReview(review: $review, episode: $episode) {
233+
stars
234+
commentary
235+
}
236+
}
237+
209238
Subscriptions
210239
^^^^^^^^^^^^^
211240

gql/dsl.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
FragmentDefinitionNode,
1919
FragmentSpreadNode,
2020
GraphQLArgument,
21+
GraphQLEnumType,
2122
GraphQLError,
2223
GraphQLField,
2324
GraphQLID,
@@ -28,9 +29,9 @@
2829
GraphQLNamedType,
2930
GraphQLNonNull,
3031
GraphQLObjectType,
32+
GraphQLScalarType,
3133
GraphQLSchema,
3234
GraphQLString,
33-
GraphQLWrappingType,
3435
InlineFragmentNode,
3536
IntValueNode,
3637
ListTypeNode,
@@ -50,7 +51,6 @@
5051
ValueNode,
5152
VariableDefinitionNode,
5253
VariableNode,
53-
assert_named_type,
5454
get_named_type,
5555
introspection_types,
5656
is_enum_type,
@@ -134,7 +134,7 @@ def ast_from_value(value: Any, type_: GraphQLInputType) -> Optional[ValueNode]:
134134
of if we receive a Null value for a Non-Null type.
135135
"""
136136
if isinstance(value, DSLVariable):
137-
return value.set_type(type_).ast_variable
137+
return value.set_type(type_).ast_variable_name
138138

139139
if is_non_null_type(type_):
140140
type_ = cast(GraphQLNonNull, type_)
@@ -529,26 +529,33 @@ class DSLVariable:
529529

530530
def __init__(self, name: str):
531531
""":meta private:"""
532-
self.type: Optional[TypeNode] = None
533532
self.name = name
534-
self.ast_variable = VariableNode(name=NameNode(value=self.name))
533+
self.ast_variable_type: Optional[TypeNode] = None
534+
self.ast_variable_name = VariableNode(name=NameNode(value=self.name))
535+
self.default_value = None
536+
self.type: Optional[GraphQLInputType] = None
535537

536-
def to_ast_type(
537-
self, type_: Union[GraphQLWrappingType, GraphQLNamedType]
538-
) -> TypeNode:
538+
def to_ast_type(self, type_: GraphQLInputType) -> TypeNode:
539539
if is_wrapping_type(type_):
540540
if isinstance(type_, GraphQLList):
541541
return ListTypeNode(type=self.to_ast_type(type_.of_type))
542+
542543
elif isinstance(type_, GraphQLNonNull):
543544
return NonNullTypeNode(type=self.to_ast_type(type_.of_type))
544545

545-
type_ = assert_named_type(type_)
546+
assert isinstance(
547+
type_, (GraphQLScalarType, GraphQLEnumType, GraphQLInputObjectType)
548+
)
549+
546550
return NamedTypeNode(name=NameNode(value=type_.name))
547551

548-
def set_type(
549-
self, type_: Union[GraphQLWrappingType, GraphQLNamedType]
550-
) -> "DSLVariable":
551-
self.type = self.to_ast_type(type_)
552+
def set_type(self, type_: GraphQLInputType) -> "DSLVariable":
553+
self.type = type_
554+
self.ast_variable_type = self.to_ast_type(type_)
555+
return self
556+
557+
def default(self, default_value: Any) -> "DSLVariable":
558+
self.default_value = default_value
552559
return self
553560

554561

@@ -581,9 +588,11 @@ def get_ast_definitions(self) -> Tuple[VariableDefinitionNode, ...]:
581588
"""
582589
return tuple(
583590
VariableDefinitionNode(
584-
type=var.type,
585-
variable=var.ast_variable,
586-
default_value=None,
591+
type=var.ast_variable_type,
592+
variable=var.ast_variable_name,
593+
default_value=None
594+
if var.default_value is None
595+
else ast_from_value(var.default_value, var.type),
587596
)
588597
for var in self.variables.values()
589598
if var.type is not None # only variables used

tests/starwars/test_dsl.py

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@ def test_ast_from_serialized_value_untyped_typeerror():
111111

112112

113113
def test_variable_to_ast_type_passing_wrapping_type():
114-
wrapping_type = GraphQLNonNull(GraphQLList(StarWarsSchema.get_type("Droid")))
115-
variable = DSLVariable("droids")
114+
wrapping_type = GraphQLNonNull(GraphQLList(StarWarsSchema.get_type("ReviewInput")))
115+
variable = DSLVariable("review_input")
116116
ast = variable.to_ast_type(wrapping_type)
117117
assert ast == NonNullTypeNode(
118-
type=ListTypeNode(type=NamedTypeNode(name=NameNode(value="Droid")))
118+
type=ListTypeNode(type=NamedTypeNode(name=NameNode(value="ReviewInput")))
119119
)
120120

121121

@@ -170,6 +170,50 @@ def test_add_variable_definitions(ds):
170170
)
171171

172172

173+
def test_add_variable_definitions_with_default_value_enum(ds):
174+
var = DSLVariableDefinitions()
175+
op = DSLMutation(
176+
ds.Mutation.createReview.args(
177+
review=var.review, episode=var.episode.default(4)
178+
).select(ds.Review.stars, ds.Review.commentary)
179+
)
180+
op.variable_definitions = var
181+
query = dsl_gql(op)
182+
183+
assert (
184+
print_ast(query)
185+
== """mutation ($review: ReviewInput, $episode: Episode = NEWHOPE) {
186+
createReview(review: $review, episode: $episode) {
187+
stars
188+
commentary
189+
}
190+
}"""
191+
)
192+
193+
194+
def test_add_variable_definitions_with_default_value_input_object(ds):
195+
var = DSLVariableDefinitions()
196+
op = DSLMutation(
197+
ds.Mutation.createReview.args(
198+
review=var.review.default({"stars": 5, "commentary": "Wow!"}),
199+
episode=var.episode,
200+
).select(ds.Review.stars, ds.Review.commentary)
201+
)
202+
op.variable_definitions = var
203+
query = dsl_gql(op)
204+
205+
assert (
206+
print_ast(query)
207+
== """
208+
mutation ($review: ReviewInput = {stars: 5, commentary: "Wow!"}, $episode: Episode) {
209+
createReview(review: $review, episode: $episode) {
210+
stars
211+
commentary
212+
}
213+
}""".strip()
214+
)
215+
216+
173217
def test_add_variable_definitions_in_input_object(ds):
174218
var = DSLVariableDefinitions()
175219
op = DSLMutation(

0 commit comments

Comments
 (0)