Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#23418 closed Cleanup/optimization (fixed)

Classes embedded inside other classes are not serialized correctly

Reported by: Dan Loewenherz Owned by: Markus Holtermann
Component: Migrations Version: 1.7
Severity: Normal Keywords:
Cc: info+coding@… Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Simple example:

class Store(models.Model):
    @deconstructible
    class IgnoreFormatString(object):
        def __init__(self, s):
            self.s = s

        def __str__(self):
            return self.s

        def __mod__(self, k):
            return self

    name = models.CharField(max_length=64, null=True)
    rating = models.IntegerField(error_messages={'invalid': IgnoreFormatString("You've entered an invalid value.")}, null=True)

The migration is created appropriately, but running it will fail with something like the following:

Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "my_project/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "my_project/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "my_project/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "my_project/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "my_project/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 63, in handle
    executor = MigrationExecutor(connection, self.migration_progress_callback)
  File "my_project/lib/python2.7/site-packages/django/db/migrations/executor.py", line 17, in __init__
    self.loader = MigrationLoader(self.connection)
  File "my_project/lib/python2.7/site-packages/django/db/migrations/loader.py", line 48, in __init__
    self.build_graph()
  File "my_project/lib/python2.7/site-packages/django/db/migrations/loader.py", line 173, in build_graph
    self.load_disk()
  File "my_project/lib/python2.7/site-packages/django/db/migrations/loader.py", line 103, in load_disk
    migration_module = import_module("%s.%s" % (module_name, migration_name))
  File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "my_project/app/migrations/0001_initial.py", line 8, in <module>
    class Migration(migrations.Migration):
  File "my_project/app/migrations/0001_initial.py", line 19, in Migration
    ('rating', models.IntegerField(null=True, error_messages={b'invalid': app.models.IgnoreFormatString(b"You've entered an invalid value.")})),
AttributeError: 'module' object has no attribute 'IgnoreFormatString

Let me know if you need anything else to help diagnose the issue or have any questions. Cheers!

Change History (13)

comment:1 by Andrew Godwin, 10 years ago

Resolution: invalid
Status: newclosed

Unfortunately, this is unserializable, as there's no way to get the reference to the surrounding class from the inner class. I'll update the docs to mention this, but the only fix for you is to move InvalidFormatString to the outer scope.

comment:2 by Andrew Godwin <andrew@…>, 10 years ago

In 45768e6b72607b4bc913358c560830454f3336a7:

Update docs to be more clear about nested classes (refs #23418)

comment:3 by Andrew Godwin <andrew@…>, 10 years ago

In e5cdfb151039cdd22a17480f0f1fb9ccbad5eb56:

[1.7.x] Update docs to be more clear about nested classes (refs #23418)

comment:4 by Dan Loewenherz, 10 years ago

@Andrew Any way we can prevent the migration itself from being created as well? Although the docs mention it now, the migration is still created and users won't encounter the error until after running it. Thoughts?

comment:5 by Dan Loewenherz, 10 years ago

Resolution: invalid
Status: closednew

Reopening since I'm not convinced a doc-only change is sufficient. I'm happy to contribute a patch if needed.

comment:6 by Markus Holtermann, 10 years ago

Cc: info+coding@… added
Has patch: set
Owner: changed from nobody to Markus Holtermann
Status: newassigned
Type: BugCleanup/optimization

comment:7 by Dan Loewenherz, 10 years ago

Awesome, thanks!

comment:8 by Markus Holtermann <info@…>, 10 years ago

Resolution: fixed
Status: assignedclosed

In d28b5f13b332bda4317949b98e33f528d30ec006:

Fixed #23418 -- Fail when migration deconstruct produces invalid import

comment:9 by Tim Graham <timograham@…>, 10 years ago

In b0def3bcac1a2e1117050e00fa1b187a897f0c2e:

[1.7.x] Fixed #23418 -- Fail when migration deconstruct produces invalid import

Backport of d28b5f13b3 from master

comment:10 by Tim Graham <timograham@…>, 10 years ago

In 16548cfc7c9d86ae7b0d13425ec7608f0571130c:

Fixed broken test from da160d440f; refs #23418.

comment:11 by Tim Graham <timograham@…>, 10 years ago

In 1f1a32928873a4e7cfe2f8f15631aa63df335490:

[1.7.x] Fixed broken test from da160d440f; refs #23418.

Backport of 16548cfc7c from master

comment:12 by Tim Graham <timograham@…>, 10 years ago

In fbeb7979ee43cb386265ff7aec757e35b4cf61f8:

Avoided using deprecated version of importlib; refs #23418.

comment:13 by Tim Graham <timograham@…>, 10 years ago

In 4500784b24856b23924e7d36b405f2df1499ea83:

[1.7.x] Avoided using deprecated version of importlib; refs #23418.

Backport of fbeb7979ee from master

Note: See TracTickets for help on using tickets.
Back to Top