fix Optional typing hint for SerializerMethodField (#428)
parent
8578b93eba
commit
1352c2a23b
|
|
@ -610,6 +610,8 @@ class SerializerMethodFieldInspector(FieldInspector):
|
||||||
# look for Python 3.5+ style type hinting of the return value
|
# look for Python 3.5+ style type hinting of the return value
|
||||||
hint_class = inspect_signature(method).return_annotation
|
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):
|
if inspect.isclass(hint_class) and not issubclass(hint_class, inspect._empty):
|
||||||
type_info = get_basic_type_info_from_hint(hint_class)
|
type_info = get_basic_type_info_from_hint(hint_class)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import json
|
import json
|
||||||
|
import sys
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
@ -17,6 +18,11 @@ from drf_yasg.errors import SwaggerGenerationError
|
||||||
from drf_yasg.generators import OpenAPISchemaGenerator
|
from drf_yasg.generators import OpenAPISchemaGenerator
|
||||||
from drf_yasg.utils import swagger_auto_schema
|
from drf_yasg.utils import swagger_auto_schema
|
||||||
|
|
||||||
|
try:
|
||||||
|
import typing
|
||||||
|
except ImportError:
|
||||||
|
typing = None
|
||||||
|
|
||||||
|
|
||||||
def test_schema_is_valid(swagger, codec_yaml):
|
def test_schema_is_valid(swagger, codec_yaml):
|
||||||
codec_yaml.encode(swagger)
|
codec_yaml.encode(swagger)
|
||||||
|
|
@ -293,3 +299,38 @@ def test_json_field():
|
||||||
swagger = generator.get_schema(None, True)
|
swagger = generator.get_schema(None, True)
|
||||||
property_schema = swagger["definitions"]["TestJSONField"]["properties"]["json"]
|
property_schema = swagger["definitions"]["TestJSONField"]["properties"]["json"]
|
||||||
assert property_schema == openapi.Schema(title='Json', type=openapi.TYPE_OBJECT)
|
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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue