Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MERGE AFTER #868] fix type hints when using postponed evaluation of annotations (PEP-563) #840

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fix type hints when using postponed evaluation of annotations (PEP-563)
  • Loading branch information
terencehonles committed Nov 6, 2024
commit a7f484ad42bc45dbefe4b157e4e39b1ab07e644d
25 changes: 13 additions & 12 deletions src/drf_yasg/inspectors/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from contextlib import suppress
from collections import OrderedDict
from decimal import Decimal
from inspect import signature as inspect_signature

import typing
from django.core import validators
Expand Down Expand Up @@ -617,17 +616,19 @@ def field_to_swagger_object(self, field, swagger_object_type, use_references, **
return self.probe_field_inspectors(serializer, swagger_object_type, use_references, read_only=True)
else:
# 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)

if type_info is not None:
SwaggerType, ChildSwaggerType = self._get_partial_types(field, swagger_object_type,
use_references, **kwargs)
return SwaggerType(**type_info)
hint_class = typing.get_type_hints(method).get('return')

# annotations such as typing.Optional have an __instancecheck__
# hook and will not look like classes, but `issubclass` needs
# a class as its first argument, so only in that case abort
if inspect.isclass(hint_class) and issubclass(hint_class, inspect._empty):
return NotHandled

type_info = get_basic_type_info_from_hint(hint_class)
if type_info is not None:
SwaggerType, ChildSwaggerType = self._get_partial_types(field, swagger_object_type,
use_references, **kwargs)
return SwaggerType(**type_info)

return NotHandled

Expand Down
2 changes: 1 addition & 1 deletion tests/test_schema_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def retrieve(self, request, pk=None):
)
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)
assert property_schema == openapi.Schema(title='X', type=expected_type, readOnly=True, x_nullable=True)


EXPECTED_DESCRIPTION = """\
Expand Down