Traceback (most recent call last):
File "/usr/local/bin/django-admin", line 8, in <module>
sys.exit(execute_from_command_line())
File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 330, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 371, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/management/commands/spectacular.py", line 50, in handle
schema = generator.get_schema(request=None, public=True)
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/generators.py", line 257, in get_schema
paths=self.parse(request, public),
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/generators.py", line 231, in parse
operation = view.schema.get_operation(
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/openapi.py", line 84, in get_operation
operation['responses'] = self._get_response_bodies()
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/openapi.py", line 1013, in _get_response_bodies
return {'200': self._get_response_for_code(response_serializers, '200')}
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/openapi.py", line 1058, in _get_response_for_code
component = self.resolve_serializer(serializer, 'response')
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/openapi.py", line 1204, in resolve_serializer
component.schema = self._map_serializer(serializer, direction)
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/openapi.py", line 705, in _map_serializer
schema = self._map_basic_serializer(serializer, direction)
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/openapi.py", line 769, in _map_basic_serializer
schema = self._map_serializer_field(field, direction)
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/openapi.py", line 646, in _map_serializer_field
return append_meta(self._map_response_type_hint(method), meta)
File "/usr/local/lib/python3.8/site-packages/drf_spectacular/openapi.py", line 831, in _map_response_type_hint
hint = get_override(method, 'field') or typing.get_type_hints(method).get('return')
File "/usr/local/lib/python3.8/typing.py", line 1255, in get_type_hints
raise TypeError('{!r} is not a module, class, method, '
TypeError: functools.partial(<bound method MySerializer._get_generic_ct_field of MySerializer():
element = SerializerMethodField()
other= SerializerMethodField() >, field='other') is not a module, class, method, or function.
from functools import partialmethod
from rest_framework import serializers
from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes
class MySerializer(serializers.Serializer):
foo = serializers.SerializerMethodField()
bar = serializers.SerializerMethodField()
@extend_schema_field(OpenApiTypes.ANY)
def _private_method(self, field, extra_param):
# do some real stuff
print(field, extra_param)
def _private_method_2(self, field, extra_param):
# do some real stuff
print(field, extra_param)
get_foo = partialmethod(_private_method, extra_param='foo')
get_bar = extend_schema_field(OpenApiTypes.ANY)(partialmethod(_private_method_2, extra_param='bar'))
This will throw the abovementioned error.
As of now a partialmethod object can be recognized since it has an attribute called _partialmethod where it stores the original partial object which is called by the interpreter.
Describe the bug
When a serializer defines any
SerializerMethodFieldas afunctools.partialmethodis impossible to specify any extra attribute on this method, thus resulting in a typerror.To Reproduce
Just define a basic serializer with a partialmethod:
This will throw the abovementioned error.
Expected behavior
No error should be thrown, if type annotation was setted on base method it should be used.
As of now a partialmethod object can be recognized since it has an attribute called
_partialmethodwhere it stores the original partial object which is called by the interpreter.