Skip to content

Commit

Permalink
Add support for optional arguments when a default value is provided (#82
Browse files Browse the repository at this point in the history
)

* added support for optional arguments when a default value is provided

* fixed no default arguments case

* Switched default argument detection to use inspect.signature, added tests for default arguments with custom types

* added release info
  • Loading branch information
jaydenwindle authored and patrick91 committed Jun 7, 2019
1 parent 0651357 commit f380a5d
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 2 deletions.
18 changes: 18 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Release type: minor

Added support for optional fields with default arguments in the GraphQL schema when default arguments are passed to the resolver.

Example:
```python
@strawberry.type
class Query:
@strawberry.field
def hello(self, info, name: str = "world") -> str:
return name
```

```graphql
type Query {
hello(name: String = "world"): String
}
```
6 changes: 5 additions & 1 deletion strawberry/field.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import inspect
import typing

import dataclasses
Expand Down Expand Up @@ -202,6 +203,7 @@ def _get_field(
name = wrap.__name__

annotations = typing.get_type_hints(wrap, None, REGISTRY)
parameters = inspect.signature(wrap).parameters
field_type = get_graphql_type_for_annotation(annotations["return"], name)

arguments_annotations = {
Expand All @@ -211,7 +213,9 @@ def _get_field(
}

arguments = {
to_camel_case(name): get_graphql_type_for_annotation(annotation, name)
to_camel_case(name): get_graphql_type_for_annotation(
annotation, name, parameters[name].default != inspect._empty
)
for name, annotation in arguments_annotations.items()
}

Expand Down
49 changes: 48 additions & 1 deletion tests/test_field.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import pytest

import strawberry
from graphql import GraphQLField, GraphQLNonNull
from graphql import (
GraphQLField,
GraphQLInputObjectType,
GraphQLNonNull,
GraphQLScalarType,
)
from strawberry.exceptions import (
MissingArgumentsAnnotationsError,
MissingReturnAnnotationError,
Expand Down Expand Up @@ -29,6 +34,48 @@ def hello(self, info, id: int) -> str:
assert hello.field.args["id"].type.of_type.name == "Int"


def test_field_default_arguments_are_optional():
@strawberry.field
def hello(self, info, test: int, id: int = 1, asdf: str = "hello") -> str:
return "I'm a resolver"

assert hello.field

assert type(hello.field) == GraphQLField
assert type(hello.field.type) == GraphQLNonNull
assert hello.field.type.of_type.name == "String"

assert type(hello.field.args["id"].type) == GraphQLScalarType
assert hello.field.args["id"].type.name == "Int"

assert type(hello.field.args["asdf"].type) == GraphQLScalarType
assert hello.field.args["asdf"].type.name == "String"


def test_field_default_optional_argument_custom_type():
@strawberry.input
class CustomInputType:
field: str

@strawberry.field
def hello(
self, info, required: CustomInputType, optional: CustomInputType = None
) -> str:
return "I'm a resolver"

assert hello.field

assert type(hello.field) == GraphQLField
assert type(hello.field.type) == GraphQLNonNull
assert hello.field.type.of_type.name == "String"

assert type(hello.field.args["required"].type) == GraphQLNonNull
assert hello.field.args["required"].type.of_type.name == "CustomInputType"

assert type(hello.field.args["optional"].type) == GraphQLInputObjectType
assert hello.field.args["optional"].type.name == "CustomInputType"


def test_raises_error_when_return_annotation_missing():
with pytest.raises(MissingReturnAnnotationError) as e:

Expand Down

0 comments on commit f380a5d

Please sign in to comment.