From 6ecdc7b59d787ba06413072a8951255812ea2a42 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Mon, 5 Mar 2012 11:25:13 +0000 Subject: [PATCH] Added FutureWarning for inherited classes not declaring allow_inheritance Refs #437 --- docs/changelog.rst | 1 + mongoengine/base.py | 15 +++++++++++++-- setup.py | 2 +- tests/document.py | 38 ++++++++++++++++++++++++++++++++++---- tests/dynamic_document.py | 1 + tests/fixtures.py | 2 +- tests/queryset.py | 1 + 7 files changed, 52 insertions(+), 8 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 43eac27e..f0a95d80 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,7 @@ Changelog Changes in 0.6 ============== +- Added FutureWarning to inherited classes not declaring 'allow_inheritance' as the default will change in 0.7 - Added support for covered indexes when inheritance is off - No longer always upsert on save for items with a '_id' - Error raised if update doesn't have an operation diff --git a/mongoengine/base.py b/mongoengine/base.py index aa79b40c..04b3f1ff 100644 --- a/mongoengine/base.py +++ b/mongoengine/base.py @@ -1,3 +1,5 @@ +import warnings + from queryset import QuerySet, QuerySetManager from queryset import DoesNotExist, MultipleObjectsReturned from queryset import DO_NOTHING @@ -116,7 +118,6 @@ class BaseField(object): validation=None, choices=None, verbose_name=None, help_text=None): self.db_field = (db_field or name) if not primary_key else '_id' if name: - import warnings msg = "Fields' 'name' attribute deprecated in favour of 'db_field'" warnings.warn(msg, DeprecationWarning) self.name = None @@ -471,7 +472,6 @@ class DocumentMetaclass(type): """Metaclass for all documents. """ - def __new__(cls, name, bases, attrs): def _get_mixin_fields(base): attrs = {} @@ -512,6 +512,13 @@ class DocumentMetaclass(type): # inheritance may be disabled to remove dependency on # additional fields _cls and _types class_name.append(base._class_name) + if not base._meta.get('allow_inheritance_defined', True): + warnings.warn( + "%s uses inheritance, the default for allow_inheritance " + "is changing to off by default. Please add it to the " + "document meta." % name, + FutureWarning + ) if base._meta.get('allow_inheritance', True) == False: raise ValueError('Document %s may not be subclassed' % base.__name__) @@ -673,6 +680,10 @@ class TopLevelDocumentMetaclass(DocumentMetaclass): 'delete_rules': {}, 'allow_inheritance': True } + + allow_inheritance_defined = ('allow_inheritance' in base_meta or + 'allow_inheritance'in attrs.get('meta', {})) + meta['allow_inheritance_defined'] = allow_inheritance_defined meta.update(base_meta) # Apply document-defined meta options diff --git a/setup.py b/setup.py index 7a69d83a..d92c4910 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ setup(name='mongoengine', author='Harry Marr', author_email='harry.marr@{nospam}gmail.com', maintainer="Ross Lawley", - maintainer_email="ross.lawley@gmail.com", + maintainer_email="ross.lawley@{nospam}gmail.com", url='http://mongoengine.org/', license='MIT', include_package_data=True, diff --git a/tests/document.py b/tests/document.py index a9bb70c8..910a78fc 100644 --- a/tests/document.py +++ b/tests/document.py @@ -23,11 +23,32 @@ class DocumentTest(unittest.TestCase): class Person(Document): name = StringField() age = IntField() + + meta = {'allow_inheritance': True} + self.Person = Person def tearDown(self): self.Person.drop_collection() + def test_future_warning(self): + """Add FutureWarning for future allow_inhertiance default change. + """ + + with warnings.catch_warnings(True) as errors: + + class SimpleBase(Document): + a = IntField() + + class InheritedClass(SimpleBase): + b = IntField() + + InheritedClass() + self.assertEquals(len(errors), 1) + warning = errors[0] + self.assertEquals(FutureWarning, warning.category) + self.assertTrue("InheritedClass" in warning.message.message) + def test_drop_collection(self): """Ensure that the collection may be dropped from the database. """ @@ -145,7 +166,8 @@ class DocumentTest(unittest.TestCase): def test_get_superclasses(self): """Ensure that the correct list of superclasses is assembled. """ - class Animal(Document): pass + class Animal(Document): + meta = {'allow_inheritance': True} class Fish(Animal): pass class Mammal(Animal): pass class Human(Mammal): pass @@ -194,7 +216,8 @@ class DocumentTest(unittest.TestCase): def test_polymorphic_queries(self): """Ensure that the correct subclasses are returned from a query""" - class Animal(Document): pass + class Animal(Document): + meta = {'allow_inheritance': True} class Fish(Animal): pass class Mammal(Animal): pass class Human(Mammal): pass @@ -223,7 +246,8 @@ class DocumentTest(unittest.TestCase): """Ensure that the correct subclasses are returned from a query when using references / generic references """ - class Animal(Document): pass + class Animal(Document): + meta = {'allow_inheritance': True} class Fish(Animal): pass class Mammal(Animal): pass class Human(Mammal): pass @@ -302,7 +326,8 @@ class DocumentTest(unittest.TestCase): self.Person._get_collection_name()) # Ensure that MRO error is not raised - class A(Document): pass + class A(Document): + meta = {'allow_inheritance': True} class B(A): pass class C(B): pass @@ -597,6 +622,7 @@ class DocumentTest(unittest.TestCase): 'tags', ('category', '-date') ], + 'allow_inheritance': True } BlogPost.drop_collection() @@ -996,6 +1022,8 @@ class DocumentTest(unittest.TestCase): username = StringField(primary_key=True) name = StringField() + meta = {'allow_inheritance': True} + User.drop_collection() self.assertEqual(User._fields['username'].db_field, '_id') @@ -1045,6 +1073,8 @@ class DocumentTest(unittest.TestCase): class Place(Document): name = StringField() + meta = {'allow_inheritance': True} + class NicePlace(Place): pass diff --git a/tests/dynamic_document.py b/tests/dynamic_document.py index ec0ee1db..6ff199a0 100644 --- a/tests/dynamic_document.py +++ b/tests/dynamic_document.py @@ -12,6 +12,7 @@ class DynamicDocTest(unittest.TestCase): class Person(DynamicDocument): name = StringField() + meta = {'allow_inheritance': True} Person.drop_collection() diff --git a/tests/fixtures.py b/tests/fixtures.py index a97e8eba..fd9062ec 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -20,4 +20,4 @@ class Mixin(object): class Base(Document): - pass + meta = {'allow_inheritance': True} diff --git a/tests/queryset.py b/tests/queryset.py index 3c98d9ef..97048953 100644 --- a/tests/queryset.py +++ b/tests/queryset.py @@ -20,6 +20,7 @@ class QuerySetTest(unittest.TestCase): class Person(Document): name = StringField() age = IntField() + meta = {'allow_inheritance': True} self.Person = Person def test_initialisation(self):