[Django] #34608: Migrations generates code that it can't execute

16 views
Skip to first unread message

Django

unread,
May 30, 2023, 12:55:19 PM5/30/23
to django-...@googlegroups.com
#34608: Migrations generates code that it can't execute
-----------------------------------------+---------------------------------
Reporter: Michael | Owner: nobody
Type: Uncategorized | Status: new
Component: Migrations | Version: 4.0
Severity: Normal | Keywords: make migrations
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+---------------------------------
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 ...
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/34608>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 30, 2023, 1:20:17 PM5/30/23
to django-...@googlegroups.com
#34608: Migrations generates code that it can't execute
---------------------------------+--------------------------------------

Reporter: Michael | Owner: nobody
Type: Uncategorized | Status: new
Component: Migrations | Version: 4.0
Severity: Normal | Resolution:

Keywords: make migrations | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+--------------------------------------

Comment (by Michael):

Changing this line from:


{{{
bases=(core.djpp.permpp.PermissionsMixin_factory.<locals>.PermissionsMixin,
models.Model, djpp.modelpp.NiceNameMixin),
}}}

to:
{{{
bases=(models.Model, djpp.modelpp.NiceNameMixin),
}}}
Make it work fine, since `PermissionsMixin` does not define any DB fields,
is just run time behavior, but I thought this issue might highlight an
underlying problem.

--
Ticket URL: <https://code.djangoproject.com/ticket/34608#comment:1>

Django

unread,
May 30, 2023, 1:21:44 PM5/30/23
to django-...@googlegroups.com
#34608: Migrations generates code that it can't execute
-------------------------------+--------------------------------------
Reporter: Michael | Owner: nobody
Type: Uncategorized | Status: closed
Component: Migrations | Version: 4.0
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage: Unreviewed

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Natalia Bidart):

* keywords: make migrations =>
* status: new => closed
* resolution: => invalid


Comment:

Hello!

First of all, please note that you are using a version of Django that is
no longer supported (4.0.1).
Secondly, the error seems to be caused by either:

1. a possible misconfiguration/bug in your code, or
2. the result from squashing the migrations is somehow invalid.

For the first case, the recommended approach is to first ensure whether
the error you are getting is a bug in Django itself, or not in your code.
To do that, you can follow
[https://docs.djangoproject.com/en/4.2/internals/contributing/bugs-and-
features/#reporting-bugs the bug reporting guide] and seek help in the
Django User channels to evaluate whether your problem is caused by a
configuration issue.

For the second case, we would need a minimal example of two working
migrations and their minimal models that, when squashed, would generate
the invalid result. It's important to try to narrow the models and
migrations to the bare minimum that triggers the issue, and that what's
shared in the bug is fully functional. At the very least we'd need the
migrations that were squashed down to the result you pasted in this
report.

Closing this ticket as invalid for now, but if you find a concrete bug in
Django itself or if you can provide a reproducer for the faulty squashed
migration, please let us know and we'll analyze this further. Thanks!

--
Ticket URL: <https://code.djangoproject.com/ticket/34608#comment:2>

Django

unread,
May 3, 2024, 9:24:31 AMMay 3
to django-...@googlegroups.com
#34608: Migrations generates code that it can't execute
-------------------------------+--------------------------------------
Reporter: Michael | Owner: nobody
Type: Uncategorized | Status: closed
Component: Migrations | Version: 4.0
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by Michael):

Hi, there is not an error or bug in my code. Django generates code that
cannot run. My code runs fine. Everytime I generate migrations, I have to
manually edit them so they are runnable. This is a bug in Django.
--
Ticket URL: <https://code.djangoproject.com/ticket/34608#comment:3>

Django

unread,
May 3, 2024, 9:24:51 AMMay 3
to django-...@googlegroups.com
#34608: Migrations generates code that it can't execute
-------------------------------+--------------------------------------
Reporter: Michael | Owner: nobody
Type: Uncategorized | Status: new
Component: Migrations | Version: 4.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Michael):

* resolution: invalid =>
* status: closed => new

--
Ticket URL: <https://code.djangoproject.com/ticket/34608#comment:4>

Django

unread,
May 3, 2024, 9:27:47 AMMay 3
to django-...@googlegroups.com
#34608: Migrations generates code that it can't execute
-------------------------------+--------------------------------------
Reporter: Michael | Owner: nobody
Type: Uncategorized | Status: new
Component: Migrations | Version: 5.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Michael):

* version: 4.0 => 5.0

--
Ticket URL: <https://code.djangoproject.com/ticket/34608#comment:5>

Django

unread,
May 3, 2024, 10:17:46 AMMay 3
to django-...@googlegroups.com
#34608: Migrations generates code that it can't execute
-------------------------------+--------------------------------------
Reporter: Michael | Owner: nobody
Type: Uncategorized | Status: new
Component: Migrations | Version: 5.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by Michael):

I created a minimal reproducible example:
https://github.com/mangelozzi/djangomigrationbug

1. Check accounts/migrations/0001_initial.py
2. You will see this line
bases=(plug.permpp.PermissionsMixin_factory.<locals>.PermissionsMixin,
models.Model, accounts.modelpp.NiceNameMixin),
- It has an error `<locals>`
3. Delete the above migration file
4. Run python manage.py makemigrations
5. The file above with the error will be created by the Django.
--
Ticket URL: <https://code.djangoproject.com/ticket/34608#comment:6>

Django

unread,
May 6, 2024, 3:59:00 AMMay 6
to django-...@googlegroups.com
#34608: Migrations generates code that it can't execute
-------------------------------+--------------------------------------
Reporter: Michael | Owner: nobody
Type: Uncategorized | Status: closed
Component: Migrations | Version: 5.0
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Sarah Boyce):

* resolution: => invalid
* status: new => closed

Comment:

Hi Micheal, thank you for providing more information here. Django does
generate migrations that cannot be applied.
The generated migration file usually reflects what you have asked Django
to do and it can only apply successfully if it is "valid".
Here `User` is dependant on `PermissionsMixin` (it is possible that
`PermissionsMixin` has some fields defined on it for example) and
`PermissionsMixin` is dependant on your locals as this is an output of a
function ran at startup. IMO you can simplify your code to have a valid
migration generated.

If you need any support with your project, please use one of our support
channels such as the [https://forum.djangoproject.com/c/users/6 Django
forum]. It is recommended to go there first and confirm with others if
there is agreement that this is either a bug in Django or something new
Django should support.
--
Ticket URL: <https://code.djangoproject.com/ticket/34608#comment:7>
Reply all
Reply to author
Forward
0 new messages