django-stubs icon indicating copy to clipboard operation
django-stubs copied to clipboard

error: Definition of "_meta" in base class "PermissionsMixin" is incompatible with definition in base class "AbstractBaseUser"

Open anentropic opened this issue 4 years ago • 18 comments

Bug report

What's wrong

We have defined a custom AuthUser model in our project like:

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin

class AuthUser(PermissionsMixin, AbstractBaseUser):
    class Meta:
        verbose_name = _('Auth User')
        abstract = False
        db_table = 'auth_user'

mypy gives an error:

myproject/models/auth.py:3: error: Definition of "_meta" in base class "PermissionsMixin" is incompatible with definition in base class "AbstractBaseUser"

(from the class AuthUser(PermissionsMixin, AbstractBaseUser): line)

The slightly weird part is Django's PermissionMixin and AbstractBaseUser both have an identical Meta:

    class Meta:
        abstract = True

How is that should be

No error

System information

  • OS:
  • python version: 3.8.3
  • django version: 2.2.12
  • mypy version: 0.782
  • django-stubs version: 1.5.0

anentropic avatar Sep 23 '20 09:09 anentropic

@anentropic I'm not able to reproduce this bug, could you post a result of reveal_type(AuthUser) and mypy --tb .myproject/models/auth.py?

kszmigiel avatar Sep 23 '20 13:09 kszmigiel

myproject/models/auth.py:19: error: Definition of "_meta" in base class "PermissionsMixin" is incompatible with definition in base class "AbstractBaseUser"
myproject/models/auth.py:111: note: Revealed type is 'def (*args: Any, **kwargs: Any) -> myproject.models.auth.AuthUser'

anentropic avatar Sep 23 '20 13:09 anentropic

@anentropic Shouldn't you use from django.contrib.auth.base_user import AbstractBaseUser? Or maybe AbstractUser from django.contrib.auth.models would do the job?

kszmigiel avatar Sep 23 '20 14:09 kszmigiel

importing the same class as from django.contrib.auth.base_user import AbstractBaseUser does not make a difference in the mypy error

we couldn't use AbstractUser as it defines stuff we don't want

anentropic avatar Sep 23 '20 14:09 anentropic

Ok, so I'm out of ideas at this point, sorry. Maybe @sobolevn will come up with something?

kszmigiel avatar Sep 23 '20 14:09 kszmigiel

I would also love to see ._meta attributes of all AbstractBaseUser, PermissionsMixin, and your type.

Thanks a lot for the help! 👍

sobolevn avatar Sep 23 '20 15:09 sobolevn

if TYPE_CHECKING:
    reveal_type(AuthUser._meta)
    reveal_type(PermissionsMixin._meta)
    reveal_type(AbstractBaseUser._meta)
myproject/models/auth.py:111: note: Revealed type is 'django.db.models.options.Options[django.contrib.auth.models.PermissionsMixin]'
myproject/models/auth.py:112: note: Revealed type is 'django.db.models.options.Options[django.contrib.auth.models.PermissionsMixin]'
myproject/models/auth.py:113: note: Revealed type is 'django.db.models.options.Options[django.contrib.auth.base_user.AbstractBaseUser]'

anentropic avatar Sep 23 '20 16:09 anentropic

We can try to tweak the variance of _meta to be contravariant. My wild guess that this can be the case (I am totally not sure).

sobolevn avatar Sep 23 '20 16:09 sobolevn

if you have a branch with the contravariant change at some point I'll be happy to try it out on my problem Django project

anentropic avatar Sep 23 '20 17:09 anentropic

@anentropic According to https://code.djangoproject.com/ticket/31437 (thanks to @syastrov for the link):

(...) overriding multiply inherited fields has never been supported

So, it seems like # type: ignore is the only solution (maybe?) I've spent quite a lot of time trying to fix the error coming from the piece of code mentioned in the link above as it was the last one failing in CI (see my PR #445). @sobolevn we definitely need to update Django version we test on more often 😂

kszmigiel avatar Sep 24 '20 22:09 kszmigiel

@kszmigiel I'm not saying it's not somehow... but it's not clear to me if that issue (about overriding fields of abstract models in multiple inheritance scenario) is related to this error

presumably Django itself has the same problem since their AbstractUser class looks like:

class AbstractUser(AbstractBaseUser, PermissionsMixin):
    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        abstract = True

anentropic avatar Sep 25 '20 09:09 anentropic

Reproduced:

git clone https://github.com/syastrov/django-stubs-471.git
cd django-stubs-471
python3 -m venv venv
source ./venv/bin/activate
pip3 install -r requirements.txt 
mypy app1/

Output

authtest/settings.py:28: error: Need type annotation for 'ALLOWED_HOSTS' (hint: "ALLOWED_HOSTS: List[<type>] = ...")
app1/models.py:4: error: Definition of "_meta" in base class "PermissionsMixin" is incompatible with definition in base class "AbstractBaseUser"
Found 2 errors in 2 files (checked 7 source files)

Disabling the plugin removes the error...

syastrov avatar Sep 27 '20 11:09 syastrov

@syastrov thank you! I'll get back to this as soon as I get back home from holidays.

kszmigiel avatar Sep 29 '20 22:09 kszmigiel

Hey all, is there any update for this issue? I'm having the same problem.

zkne avatar Dec 11 '20 10:12 zkne

After upgrading mypy to 0.800 this issue was resolved for me.

MicicFilip avatar Jan 28 '21 13:01 MicicFilip

I'm on mypy version 0.931 and I'm having this same issue.

epicserve avatar Feb 16 '22 21:02 epicserve

I'm having this issue to. Is there a fix?

nickmccullum avatar Mar 05 '22 00:03 nickmccullum

mypy 0.950 django-stubs 1.11.0 Still having this issue

vkurilin avatar Jun 06 '22 06:06 vkurilin

I'm still having this issue too. How can we fix it? Or at least set it to ignore if you aren't going to.

adambirds avatar Jan 30 '23 04:01 adambirds

is there a workaround for this?

samuel-andres avatar May 06 '23 22:05 samuel-andres