1. Use a strict mypy configuration:
{{{
[mypy]
check_untyped_defs = true
disallow_untyped_defs = true
ignore_missing_imports = true
no_implicit_optional = true
warn_redundant_casts = true
warn_return_any = true
warn_unused_ignores = true
}}}
1. Create a model method which returns an optional instance:
{{{
@property
def area(self) -> Optional[Area]:
}}}
1. Try to use this elsewhere as though it's not optional:
`instance.area.code`
1. Verify that `mypy` catches this issue:
{{{
error: Item "None" of "Optional[Area]" has no attribute "code"
}}}
1. Change the `@property` annotation to `@cached_property`.
What happens:
`mypy` stops complaining about the broken typing.
What should happen:
`mypy` should still complain like above.
--
Ticket URL: <https://code.djangoproject.com/ticket/30612>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* resolution: => needsinfo
* version: 2.2 => master
* component: Uncategorized => Utilities
* type: Uncategorized => Bug
Comment:
Please provide a minimal sample project to reproduce this issue, currently
it is hard for me to decide where is an issue (if any). Remember about
minimal `mypy` configuration, most of provided custom configuration is
probably unnecessary.
--
Ticket URL: <https://code.djangoproject.com/ticket/30612#comment:1>
Comment (by dms-cat):
Replying to [comment:1 felixxm]:
> Please provide a minimal sample project to reproduce this issue,
currently it is hard for me to decide where is an issue (if any).
To reproduce (not showing stdout/stderr):
{{{
$ cd "$(mktemp --directory)"
$ python -m venv virtualenv
$ . virtualenv/bin/activate
$ pip install Django==2.2.2 mypy==0.701
$ django-admin startproject mysite
$ cat > setup.cfg <<EOF
> [mypy]
> check_untyped_defs = true
> disallow_untyped_defs = true
> ignore_missing_imports = true
> no_implicit_optional = true
> warn_redundant_casts = true
> warn_return_any = true
> warn_unused_ignores = true
> EOF
cat > mysite/mysite/models.py <<EOF
from typing import Optional
from django.db import models
from django.utils import cached_property
class Area(models.Model):
pass
class Site(models.Model):
area = models.ForeignKey(Area, on_delete=models.CASCADE)
@cached_property
def the_area(self) -> Optional[Area]:
area: Area = self.area
return area
area = Area.objects.create()
site = Site(area)
print(site.the_area.code)
EOF
$ mypy mysite/mysite/models.py
}}}
The last command reports nothing. If you change `@cached_property` to
`@property` it correctly reports 'mysite/mysite/models.py:22: error: Item
"None" of "Optional[Area]" has no attribute "code"'
> Remember about minimal `mypy` configuration, most of provided custom
configuration is probably unnecessary.
This isn't provided configuration, we arrived at this configuration in the
project as the level of validation we're comfortable with.
--
Ticket URL: <https://code.djangoproject.com/ticket/30612#comment:2>
* resolution: needsinfo => invalid
Comment:
Thanks for info. Custom `mypy` configuration is not necessary to reproduce
this issue, it behaves the same without `setup.cfg`.
I was able to reproduce this behavior, however I don't think that it is a
bug in Django. We can consider to re-open this ticket if you will be able
to confirm that it is an issue in Django e.g. by providing a patch.
--
Ticket URL: <https://code.djangoproject.com/ticket/30612#comment:3>