Hi everyone,
I’m working on a Django project and I’m trying to use mypy
to enforce type checking. To avoid circular imports, I’ve used TYPE_CHECKING
and raw strings for type annotations, particularly for my CustomUser
class.
When I run mypy
on the entire accounts/
module, I encounter the following errors:
mypy accounts/
accounts/managers.py:16: error: "_T" has no attribute "set_password" [attr-defined]
accounts/managers.py:18: error: Incompatible return value type (got "_T", expected "CustomUser") [return-value]
Found 2 errors in 1 file (checked 11 source files)
However, if I run mypy
on individual files (managers.py
or models.py
), everything works fine:
mypy managers.py
Success: no issues found in 1 source file
mypy models.py
Success: no issues found in 1 source file
Here are the relevant parts of my code:
accounts/models.py
:
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.db import models
from accounts.managers import CustomUserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
email: models.EmailField = models.EmailField(
max_length=255,
unique=True,
blank=False
)
is_active: models.BooleanField = models.BooleanField(default=True)
is_staff: models.BooleanField = models.BooleanField(default=False)
is_superuser: models.BooleanField = models.BooleanField(default=False)
zip_code: models.CharField = models.CharField(blank=True, max_length=5)
objects = CustomUserManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
def __str__(self) -> str:
return self.email
class Meta:
verbose_name = "utilisateur"
accounts/managers.py
:
from typing import Optional, TYPE_CHECKING
from django.contrib.auth.base_user import BaseUserManager
if TYPE_CHECKING:
from accounts.models import CustomUser
class CustomUserManager(BaseUserManager):
def create_user(self, email: str, password: Optional[str] = None) -> "CustomUser":
if not email:
raise ValueError("Le champ email est obligatoire")
email = self.normalize_email(email)
user = self.model(email=email)
user.set_password(password)
user.save() # user.save(using=self._db) si on veut s'assurer que l'utilisateur est sauvegardé dans la base de données correcte
return user
def create_superuser(self, email: str, password: Optional[str] = None) -> "CustomUser":
user = self.create_user(email=email, password=password)
user.is_staff = True
user.is_superuser = True
user.save() # user.save(using=self._db) si on veut s'assurer que l'utilisateur est sauvegardé dans la base de données correcte
return user
Is this a known issue with mypy
and Django, or is there a better approach to handling these type errors? Would it be advisable to ignore these specific errors, or should I refactor the code to resolve them?
Thank you ahead.