﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
34608	Migrations generates code that it can't execute	Michael	nobody	"Migrations have been fine, until I rebuilt them to squash them down.

When I run `makemigrations` it generates this line of code:
{{{
bases=(core.djpp.permpp.PermissionsMixin_factory.<locals>.PermissionsMixin, models.Model, djpp.modelpp.NiceNameMixin),
}}}

Which when it tries to run falls over:
{{{
  File ""/home/user/project/src/dist/app/plug/migrations/accounts/0001_initial.py"", line 92
    bases=(core.djpp.permpp.PermissionsMixin_factory.<locals>.PermissionsMixin, models.Model, djpp.modelpp.NiceNameMixin),
    ^
SyntaxError: expression cannot contain assignment, perhaps you meant ""==""?
}}}

Here is most of the migration, I left out some other operations:
{{{
# Generated by Django 4.0.1 on 2023-05-30 16:17

import accounts.models
import core.djpp.permpp
import django.contrib.auth.models
from django.db import migrations, models
import django.utils.timezone
import djpp.modelpp
import lib.timelib.ttb


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('auth', '0012_alter_user_first_name_max_length'),
    ]

    operations = [
       ...,
        migrations.CreateModel(
            name='User',
            fields=[
                ('id', models.SmallAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('password', models.CharField(max_length=128, verbose_name='password')),
                ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
                ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
                ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
                ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
                ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
                ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
                ('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')),
                ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='admin access')),
                ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
                ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
            ],
            options={
                'db_table': 'auth_user',
            },
            bases=(core.djpp.permpp.PermissionsMixin_factory.<locals>.PermissionsMixin, models.Model, djpp.modelpp.NiceNameMixin),
            managers=[
                ('objects', accounts.models.UserManager()),
            ],
        ),
    ]
}}}

In Django's defense it is quite a convoluted iheritance chain for the user model, that looks like this:

{{{
#permpp.py - permission mixin factory which the user model inherits from
def PermissionsMixin_factory(group_roles: GroupRoles, user_perms: UserPerms) -> type:
    class PermissionsMixin:
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            # user.has_perm is built into Django, call ours user.permissions
            setattr(self, GETTER_ATTR, PermissionGetter(self, group_roles, user_perms))

        @property
        def cached_groups(self):
              print('cached_group things')

    return PermissionsMixin

PermissionsMixin = permpp.PermissionsMixin_factory(grs, ups)
}}}

{{{
#perm.py - Constructs the permission mixin
from core.djpp import permpp
...

PermissionsMixin = permpp.PermissionsMixin_factory(...)
}}}


{{{
#app/plug/user.py - mixin for customising user model for this project
from django.db import models
from .perm import PermissionsMixin

class UserMixin(PermissionsMixin, models.Model):
    class Meta:
        abstract = True

    @property
    def foo(self):
        return 'foo'
}}}

{{{ 
#accounts/user.py - define the user model
class User(UserMixin, AbstractUser, modelpp.NiceNameMixin):
    """"""
    Requirements:
    - Must be defined in models.py, due to the way settings.AUTH_USER_MODEL is defined
    """"""

    objects = UserManager()

    username = None
    email = models.EmailField('email address', unique=True)
    is_staff = models.BooleanField(
        'admin access',
        default=False,
        help_text='Designates whether the user can log into this admin site.',
    )

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ('first_name',)

    def __str__(self):
        return self.get_full_name()

    class Meta:
        db_table = 'auth_user'

    #Other of custom methods ...
}}}"	Uncategorized	closed	Migrations	5.0	Normal	invalid			Unreviewed	0	0	0	0	0	0
