Skip to content

Commit

Permalink
bugfix unconsidered warnings/errors for return code #706 #702
Browse files Browse the repository at this point in the history
  • Loading branch information
tfranzel committed Apr 20, 2022
1 parent cc29171 commit ef0d828
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 9 deletions.
22 changes: 16 additions & 6 deletions drf_spectacular/drainage.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,22 @@ def emit_summary(self):
GENERATOR_STATS = GeneratorStats()


def warn(msg):
GENERATOR_STATS.emit(msg, 'warning')


def error(msg):
GENERATOR_STATS.emit(msg, 'error')
def warn(msg, delayed=None):
if delayed:
warnings = get_override(delayed, 'warnings', [])
warnings.append(msg)
set_override(delayed, 'warnings', warnings)
else:
GENERATOR_STATS.emit(msg, 'warning')


def error(msg, delayed=None):
if delayed:
errors = get_override(delayed, 'errors', [])
errors.append(msg)
set_override(delayed, 'errors', errors)
else:
GENERATOR_STATS.emit(msg, 'error')


def reset_generator_stats():
Expand Down
8 changes: 7 additions & 1 deletion drf_spectacular/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from rest_framework.schemas.generators import EndpointEnumerator as BaseEndpointEnumerator
from rest_framework.settings import api_settings

from drf_spectacular.drainage import add_trace_message, reset_generator_stats
from drf_spectacular.drainage import add_trace_message, get_override, reset_generator_stats
from drf_spectacular.extensions import OpenApiViewExtension
from drf_spectacular.openapi import AutoSchema
from drf_spectacular.plumbing import (
Expand Down Expand Up @@ -203,6 +203,12 @@ def parse(self, input_request, public):
path_prefix = '^' + path_prefix # make sure regex only matches from the start

for path, path_regex, method, view in endpoints:
# emit queued up warnings/error that happened prior to generation (decoration)
for w in get_override(view, 'warnings', []):
warn(w)
for e in get_override(view, 'errors', []):
error(e)

view.request = spectacular_settings.GET_MOCK_REQUEST(method, path, view, input_request)

if not (public or self.has_view_permissions(path, method, view)):
Expand Down
6 changes: 4 additions & 2 deletions drf_spectacular/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,8 @@ def get_external_docs(self):
if operation_id is not None or operation is not None:
error(
f'using @extend_schema on viewset class {f.__name__} with parameters '
f'operation_id or operation will most likely result in a broken schema.'
f'operation_id or operation will most likely result in a broken schema.',
delayed=f,
)
# reorder schema class MRO so that view method annotation takes precedence
# over view class annotation. only relevant if there is a method annotation
Expand Down Expand Up @@ -559,7 +560,8 @@ def decorator(view):
if method_name not in available_view_methods:
warn(
f'@extend_schema_view argument "{method_name}" was not found on view '
f'{view.__name__}. method override for "{method_name}" will be ignored.'
f'{view.__name__}. method override for "{method_name}" will be ignored.',
delayed=view
)
continue

Expand Down
7 changes: 7 additions & 0 deletions tests/test_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,14 +327,21 @@ def get(self, request):


def test_warning_operation_id_on_extend_schema_view(capsys):
from drf_spectacular.drainage import GENERATOR_STATS

@extend_schema(operation_id='Invalid', responses=int)
class XAPIView(APIView):
def get(self, request):
pass # pragma: no cover

generate_schema('x', view=XAPIView)
stderr = capsys.readouterr().err
# check basic emittance of error message to stdout
assert 'using @extend_schema on viewset class XAPIView with parameters' in stderr
# check that delayed error message was persisted on view class
assert getattr(XAPIView, '_spectacular_annotation', {}).get('errors')
# check that msg survived pre-generation warning/error cache reset
assert 'using @extend_schema on viewset' in list(GENERATOR_STATS._error_cache.keys())[0]


def test_warning_request_body_not_resolvable(capsys):
Expand Down

0 comments on commit ef0d828

Please sign in to comment.