Skip to content

Commit

Permalink
fix Optional typing hint for SerializerMethodField
Browse files Browse the repository at this point in the history
  • Loading branch information
etene committed Aug 1, 2019
1 parent ab6444a commit d7a81b1
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/drf_yasg/inspectors/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,8 @@ def field_to_swagger_object(self, field, swagger_object_type, use_references, **
# look for Python 3.5+ style type hinting of the return value
hint_class = inspect_signature(method).return_annotation

if not inspect.isclass(hint_class) and hasattr(hint_class, '__args__'):
hint_class = hint_class.__args__[0]
if inspect.isclass(hint_class) and not issubclass(hint_class, inspect._empty):
type_info = get_basic_type_info_from_hint(hint_class)

Expand Down
41 changes: 41 additions & 0 deletions tests/test_schema_generator.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import sys
from collections import OrderedDict

import pytest
Expand All @@ -17,6 +18,11 @@
from drf_yasg.generators import OpenAPISchemaGenerator
from drf_yasg.utils import swagger_auto_schema

try:
import typing
except ImportError:
typing = None


def test_schema_is_valid(swagger, codec_yaml):
codec_yaml.encode(swagger)
Expand Down Expand Up @@ -293,3 +299,38 @@ class JSONViewSet(viewsets.ModelViewSet):
swagger = generator.get_schema(None, True)
property_schema = swagger["definitions"]["TestJSONField"]["properties"]["json"]
assert property_schema == openapi.Schema(title='Json', type=openapi.TYPE_OBJECT)


@pytest.mark.parametrize('py_type, expected_type', [
(str, openapi.TYPE_STRING),
(int, openapi.TYPE_INTEGER),
(float, openapi.TYPE_NUMBER),
(bool, openapi.TYPE_BOOLEAN),
])
@pytest.mark.skipif(typing is None or sys.version_info.major < 3, reason="typing not supported")
def test_optional_return_type(py_type, expected_type):

class OptionalMethodSerializer(serializers.Serializer):
x = serializers.SerializerMethodField()

def get_x(self, instance):
pass

# Add the type annotation here in order to avoid a SyntaxError in py27
get_x.__annotations__["return"] = typing.Optional[py_type]

class OptionalMethodViewSet(viewsets.ViewSet):
@swagger_auto_schema(responses={200: openapi.Response("OK", OptionalMethodSerializer)})
def retrieve(self, request, pk=None):
return Response({'optional': None})

router = routers.DefaultRouter()
router.register(r'optional', OptionalMethodViewSet, **_basename_or_base_name('optional'))

generator = OpenAPISchemaGenerator(
info=openapi.Info(title='Test optional parameter', default_version='v1'),
patterns=router.urls
)
swagger = generator.get_schema(None, True)
property_schema = swagger["definitions"]["OptionalMethod"]["properties"]["x"]
assert property_schema == openapi.Schema(title='X', type=expected_type, readOnly=True)

0 comments on commit d7a81b1

Please sign in to comment.