-
Notifications
You must be signed in to change notification settings - Fork 271
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
Type hint support for Enums / TextChoices #492
Comments
Hi, i understand the goal you are trying to achieve. We have a whole heap of supported typings, but i think this approach is not correct.
What does work is the following. Not looking that pretty, but semantically and syntactically correct: @extend_schema_field(serializers.ListField(child=serializers.ChoiceField(choices=Bar.choices)))
def get_active_bars(self, obj):
return [Bar.A] EDIT: forgot to wrap the suggestion in a list |
Entirely true and fair.
Besides not actually being possible, it's also not semantically correct from an actual return type perspective if I'm not mistaken.
Indeed that's both semantically and syntactically correct. However, since it's possible to represent as a serializer fields, wouldn't it be possible to support it from the type hinting? I do realize it's difficult for any enum, but it seems like enums defined from Django's The workaround is fine, just not pretty, and it just seems like something that would be nice out of the box. Happy to give a PR a shot myself if it's something you agree should be supported. |
Turns out the truth is somewhere in between. I had a reason to not include it back then, but my understanding was incomplete. The implementation has had two goals:
class BarA(Enum):
A = "a"
B = "b"
# DRF serialization fails
def get_foo(self, obj) -> BarA:
return BarA.A
# MYPY complains: BarA != str
def get_foo(self, obj) -> BarA:
return BarA.A.value
# ---------------------------
class BarB(Choices):
A = "a"
B = "b"
# DRF serialization fails
def get_foo(self, obj) -> BarB:
return BarB.A
# MYPY complains: BarB != str
def get_foo(self, obj) -> BarB:
return BarB.A.value
# ---------------------------
class BarC(TextChoices):
A = "a"
B = "b"
# WORKS!
def get_foo(self, obj) -> BarC:
return BarC.A So I'm unsure whether we should also support |
From the Django docs, it really seems like Looking at the code for My personal opinion is:
My OCD is pushing me to encourage support for the most universal options, but realistically, I would imagine basic support for even just |
@tfranzel I checked out your branch to test out a few things, but seems like everything is passing. Was it fixed or is there a way for me to test out the scenarios you have outlined? Happy to setup scenarios myself, but if you happen to have a "playground" setup, that would be awesome. |
that caught me too. So TextChoices, IntegerChoices are pretty much the only sensible "choices" for types. yes the branch does cover everything including |
The Django docs does show an example that uses
Makes sense, I mainly wanted to test if supporting |
i refactored the change and it is now on master. please have a look. it should work for |
@tfranzel tested using the Thank you!!! |
Guys, it seems like this is closed, but how do you actually type hint with a TextChoices subclass? |
if you look at the merged PR you can see the added test using this feature: drf-spectacular/tests/test_postprocessing.py Lines 294 to 303 in 82c00f8
|
Hey, as far as I can tell this works with class Bar(TextChoices)
A = "a"
B = "b"
class FooSerializer(serializers.Serializer):
bar_list = serializers.SerializerMethodField()
bar_dict = serializers.SerializerMethodField()
def get_bar_list(self, obj) -> list[Bar]:
return [Bar.A]
def get_bar_dict(self, obj) -> dict[Bar, int]:
return {Bar.A: 1} Generated docs look like this:
The schema has |
Describe the bug
When using type hints with a serializer method field that returns a
TextChoices
/Enum
type, we get the "unable to resolve type hint for function" warning.While Enum value types are not guaranteed to be strings, Django provides the
TextChoices
andIntegerChoices
base classes that havestr
andint
values respectively.It may be possible to support an even wider arrange of
Enum
by checking for both subclasses of bothEnum
and a basic supported type. This would cover enums defines asFoo(int, Enum)
, which is effectively howIntegerChoices
is defined.To Reproduce
Expected behavior
drf-spectacular
should be correct identify the OpenAPI types forTextChoices
(string) andIntegerChoices
(number) enums.The text was updated successfully, but these errors were encountered: