From 55dde0286fc2aef9d2dc477c8193c9fb0e48cca3 Mon Sep 17 00:00:00 2001
From: Simon Charette <charette.s@gmail.com>
Date: Tue, 29 Jan 2013 00:28:09 -0500
Subject: [PATCH] Fixed #19688 -- Allow model subclassing with a custom
metaclass using six.with_metaclass
---
django/db/models/base.py | 3 +++
tests/modeltests/base/models.py | 5 +++++
tests/modeltests/base/tests.py | 36 ++++++++++++++++++++++++++++++++++++
3 files changed, 44 insertions(+)
create mode 100644 tests/modeltests/base/__init__.py
create mode 100644 tests/modeltests/base/models.py
create mode 100644 tests/modeltests/base/tests.py
diff --git a/django/db/models/base.py b/django/db/models/base.py
index 38afc60..abb6a32 100644
a
|
b
|
class ModelBase(type):
|
60 | 60 | super_new = super(ModelBase, cls).__new__ |
61 | 61 | # six.with_metaclass() inserts an extra class called 'NewBase' in the |
62 | 62 | # inheritance tree: Model -> NewBase -> object. Ignore this class. |
| 63 | if (name == 'NewBase' and |
| 64 | any(isinstance(b, ModelBase) for b in bases)): |
| 65 | return super_new(cls, name, bases, attrs) |
63 | 66 | parents = [b for b in bases if isinstance(b, ModelBase) and |
64 | 67 | not (b.__name__ == 'NewBase' and b.__mro__ == (b, object))] |
65 | 68 | if not parents: |
diff --git a/tests/modeltests/base/__init__.py b/tests/modeltests/base/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/modeltests/base/models.py b/tests/modeltests/base/models.py
new file mode 100644
index 0000000..bea762e
-
|
+
|
|
| 1 | from django.db import models |
| 2 | |
| 3 | |
| 4 | class CustomBaseModel(models.base.ModelBase): |
| 5 | pass |
| 6 | No newline at end of file |
diff --git a/tests/modeltests/base/tests.py b/tests/modeltests/base/tests.py
new file mode 100644
index 0000000..d4d75f8
-
|
+
|
|
| 1 | from __future__ import unicode_literals |
| 2 | |
| 3 | from django.db import models |
| 4 | from django.test.testcases import SimpleTestCase |
| 5 | from django.utils import six |
| 6 | from django.utils.unittest.case import skipIf |
| 7 | |
| 8 | from .models import CustomBaseModel |
| 9 | |
| 10 | |
| 11 | class CustomBaseTest(SimpleTestCase): |
| 12 | @skipIf(six.PY3, 'test metaclass definition under Python 2') |
| 13 | def test_py2_custom_base(self): |
| 14 | """ |
| 15 | Make sure models.Model can be subclassed with a valid custom base |
| 16 | using __metaclass__ |
| 17 | """ |
| 18 | try: |
| 19 | class PY2CustomModel(models.Model): |
| 20 | __metaclass__ = CustomBaseModel |
| 21 | except Exception: |
| 22 | self.fail("models.Model couldn't be subclassed with a valid " |
| 23 | "custom base using __metaclass__.") |
| 24 | |
| 25 | def test_six_custom_base(self): |
| 26 | """ |
| 27 | Make sure models.Model can be subclassed with a valid custom base |
| 28 | using `six.with_metaclass`. |
| 29 | """ |
| 30 | try: |
| 31 | class SixCustomModel(six.with_metaclass(CustomBaseModel, |
| 32 | models.Model)): |
| 33 | pass |
| 34 | except Exception: |
| 35 | self.fail("models.Model couldn't be subclassed with a valid " |
| 36 | "custom base using `six.with_metaclass`.") |
| 37 | No newline at end of file |