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 |