#27337: Convoluted MTI with abstract model mixin fails on PY2, works on PY3
     Reporter:  Tim Heap                      |      Owner:  nobody
         Type:  Bug                           |     Status:  new
    Component:  Database layer (models, ORM)  |    Version:  1.10
     Severity:  Normal                        |   Keywords:  python2, mti
 Triage Stage:  Unreviewed                    |  Has patch:  0
Easy pickings:  0                             |      UI/UX:  0
 This is a rather convoluted situation, but with the set up below, PY2
 fails but PY3 works. For context, this is roughly the same model set up
 used in Wagtail:

 * A Page class with custom Metaclass,
 * Developers extend Page using MTI to make custom page types
 * Mixins can be used for adding common functionality from e.g. plugins.

 from django.db import models
 from django.utils import six
 from django.test import TestCase

 class ConvolutedMTIWithAbtractMixinTests(TestCase):
     def test_convoluted_mti(self):

         class PageBase(type(models.Model)):
             Wagtail's metaclass does some things, but nothing related.
             This empty metaclass still spoils things for some reason?

         class Page(six.with_metaclass(PageBase, models.Model)):
             """The base page model. Every page should inherit from
             url = models.CharField(max_length=255)

             class Meta:
                 app_label = 'tests'

         class FancyMixin(models.Model):
             """A model mixin with extra functionality, including extra
 model fields."""
             fancy_field = models.CharField(max_length=10)

             class Meta:
                 abstract = True

         class MyPage(FancyMixin, Page):
             """My custom page type. Extends Page using MTI, and mixes in
             content = models.CharField(max_length=255)

             class Meta:
                 app_label = 'tests'

         # The page_ptr from MyPage to Page is created.
         self.assertTrue(hasattr(MyPage, 'page_ptr'))

         # The other fields are all there

         # The page_ptr field exists as a parent pointer to page.
         self.assertIn(Page, MyPage._meta.parents)

         # But Django on py27 gets confused, and 'page_ptr' is not
         # (There is no nice _meta.has_field, so try: catch will do.)
         except FieldDoesNotExist:
             self.fail("MyPage.page_ptr field is missing!")

 I stuck this test in `tests/model_inheritance/tests.py` when testing this
 out, but the tests can probably go anywhere. For some tests failing in the
 wild, this Travis CI build (https://travis-
 ci.org/takeflight/wagtail/builds/167013485) of some patches to Wagtail
 shows this happening on Django 1.8, 1.9 and 1.10 at least, but only on
 Python 2.7.

 I've poked around a little bit to see if I could work out what is going
 on, but I am not familiar enough with the model internals to make much

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

You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
For more options, visit https://groups.google.com/d/optout.

Reply via email to