pytype icon indicating copy to clipboard operation
pytype copied to clipboard

Django models.TextChoices is not-indexable?

Open junha6316 opened this issue 4 years ago • 3 comments

I made project with django and I applied type-hinting by using pytype. But pytype gives me type-error like this

type_test.py", line 11, in <module>: class ReportCategoryChoices is not indexable [not-indexable]
  ('ReportCategoryChoices' does not subclass Generic)

For more details, see https://google.github.io/pytype/errors.html#not-indexable
ninja: build stopped: subcommand failed.

type_test.py

category = ReportCategoryChoices['A']

and here is the ReportCategoryClass


class ReportCategoryChoices(models.TextChoices):
     A = "A", _("a")
     B = "B", _("b")
     C = "C", _("c")

# type of ReportCategoryChoices: <class 'django.db.models.enums.ChoicesMeta'>

in django ReportCategoryClass is Indexable. why did pytype say ReportCategory is not indexable?

junha6316 avatar Nov 12 '21 04:11 junha6316

Thanks for the report, and sorry for taking so long to respond - I somehow missed the notification for this. This looks like another consequence of not supporting https://github.com/google/pytype/issues/151 - pytype doesn't have stubs for django, so types are treated as Any, and class ReportCategoryChoices(Any) isn't seen as indexable.

I'm going to leave this open as a separate issue, since (1) django is a widely used library and we should verify that this works once pytype has type information available and (2) there are possibly other ways to resolve this (such as allowing anything that inherits from Any to be treated as indexable).

rchen152 avatar Nov 19 '21 20:11 rchen152

@rchen152 Thank you for replying the issue I reported! I left some code for someone who wants to solve this problem temporarily. redeclare explicitly your TextChoices type is Choices

from django.db.models.enums import Choices

class ReportCategoryChoices(models.TextChoices):
     A = "A", _("a")
     B = "B", _("b")
     C = "C", _("c")

ReportCategoryChoices: Type[Choices] = ReportCategoryChoices

junha6316 avatar Nov 22 '21 01:11 junha6316

I have also encountered this issue. Providing enum.Enum as a redundant base class appears to satisfy pytype.

$ pytype --version
2022.08.23

bad.py:

from django.db.models import TextChoices


class Choices(TextChoices):
    ONE = 1
    TWO = 2


print(Choices["ONE"])
$ pytype bad.py
Computing dependencies
Analyzing 1 sources with 0 local dependencies
ninja: Entering directory `.pytype'
[1/1] check bad
FAILED: [redacted]/.pytype/pyi/bad.pyi
/usr/local/bin/python -m pytype.single --imports_info [redacted]/.pytype/imports/bad.imports --module-name bad --platform linux -V 3.10 -o [redacted]/.pytype/pyi/bad.pyi --analyze-annotated --nofail --quick [redacted]/bad.py
File "[redacted]/bad.py", line 9, in <module>: class Choices is not indexable [not-indexable]
  ('Choices' does not subclass Generic)

For more details, see https://google.github.io/pytype/errors.html#not-indexable
ninja: build stopped: subcommand failed.
Leaving directory '.pytype'

good.py:

from enum import Enum

from django.db.models import TextChoices


class Choices(TextChoices, Enum):
    ONE = 1
    TWO = 2


print(Choices["ONE"])
$ pytype good.py
Computing dependencies
Analyzing 1 sources with 0 local dependencies
ninja: Entering directory `.pytype'
ninja: no work to do.
Leaving directory '.pytype'
Success: no errors found

smkent avatar Nov 09 '22 19:11 smkent