Added FutureWarning for inherited classes not declaring allow_inheritance
Refs #437
This commit is contained in:
parent
b7d0d8f0cc
commit
6ecdc7b59d
@ -5,6 +5,7 @@ Changelog
|
|||||||
Changes in 0.6
|
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
|
- Added support for covered indexes when inheritance is off
|
||||||
- No longer always upsert on save for items with a '_id'
|
- No longer always upsert on save for items with a '_id'
|
||||||
- Error raised if update doesn't have an operation
|
- Error raised if update doesn't have an operation
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import warnings
|
||||||
|
|
||||||
from queryset import QuerySet, QuerySetManager
|
from queryset import QuerySet, QuerySetManager
|
||||||
from queryset import DoesNotExist, MultipleObjectsReturned
|
from queryset import DoesNotExist, MultipleObjectsReturned
|
||||||
from queryset import DO_NOTHING
|
from queryset import DO_NOTHING
|
||||||
@ -116,7 +118,6 @@ class BaseField(object):
|
|||||||
validation=None, choices=None, verbose_name=None, help_text=None):
|
validation=None, choices=None, verbose_name=None, help_text=None):
|
||||||
self.db_field = (db_field or name) if not primary_key else '_id'
|
self.db_field = (db_field or name) if not primary_key else '_id'
|
||||||
if name:
|
if name:
|
||||||
import warnings
|
|
||||||
msg = "Fields' 'name' attribute deprecated in favour of 'db_field'"
|
msg = "Fields' 'name' attribute deprecated in favour of 'db_field'"
|
||||||
warnings.warn(msg, DeprecationWarning)
|
warnings.warn(msg, DeprecationWarning)
|
||||||
self.name = None
|
self.name = None
|
||||||
@ -471,7 +472,6 @@ class DocumentMetaclass(type):
|
|||||||
"""Metaclass for all documents.
|
"""Metaclass for all documents.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
def _get_mixin_fields(base):
|
def _get_mixin_fields(base):
|
||||||
attrs = {}
|
attrs = {}
|
||||||
@ -512,6 +512,13 @@ class DocumentMetaclass(type):
|
|||||||
# inheritance may be disabled to remove dependency on
|
# inheritance may be disabled to remove dependency on
|
||||||
# additional fields _cls and _types
|
# additional fields _cls and _types
|
||||||
class_name.append(base._class_name)
|
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:
|
if base._meta.get('allow_inheritance', True) == False:
|
||||||
raise ValueError('Document %s may not be subclassed' %
|
raise ValueError('Document %s may not be subclassed' %
|
||||||
base.__name__)
|
base.__name__)
|
||||||
@ -673,6 +680,10 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
|
|||||||
'delete_rules': {},
|
'delete_rules': {},
|
||||||
'allow_inheritance': True
|
'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)
|
meta.update(base_meta)
|
||||||
|
|
||||||
# Apply document-defined meta options
|
# Apply document-defined meta options
|
||||||
|
2
setup.py
2
setup.py
@ -39,7 +39,7 @@ setup(name='mongoengine',
|
|||||||
author='Harry Marr',
|
author='Harry Marr',
|
||||||
author_email='harry.marr@{nospam}gmail.com',
|
author_email='harry.marr@{nospam}gmail.com',
|
||||||
maintainer="Ross Lawley",
|
maintainer="Ross Lawley",
|
||||||
maintainer_email="ross.lawley@gmail.com",
|
maintainer_email="ross.lawley@{nospam}gmail.com",
|
||||||
url='http://mongoengine.org/',
|
url='http://mongoengine.org/',
|
||||||
license='MIT',
|
license='MIT',
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
|
@ -23,11 +23,32 @@ class DocumentTest(unittest.TestCase):
|
|||||||
class Person(Document):
|
class Person(Document):
|
||||||
name = StringField()
|
name = StringField()
|
||||||
age = IntField()
|
age = IntField()
|
||||||
|
|
||||||
|
meta = {'allow_inheritance': True}
|
||||||
|
|
||||||
self.Person = Person
|
self.Person = Person
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.Person.drop_collection()
|
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):
|
def test_drop_collection(self):
|
||||||
"""Ensure that the collection may be dropped from the database.
|
"""Ensure that the collection may be dropped from the database.
|
||||||
"""
|
"""
|
||||||
@ -145,7 +166,8 @@ class DocumentTest(unittest.TestCase):
|
|||||||
def test_get_superclasses(self):
|
def test_get_superclasses(self):
|
||||||
"""Ensure that the correct list of superclasses is assembled.
|
"""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 Fish(Animal): pass
|
||||||
class Mammal(Animal): pass
|
class Mammal(Animal): pass
|
||||||
class Human(Mammal): pass
|
class Human(Mammal): pass
|
||||||
@ -194,7 +216,8 @@ class DocumentTest(unittest.TestCase):
|
|||||||
|
|
||||||
def test_polymorphic_queries(self):
|
def test_polymorphic_queries(self):
|
||||||
"""Ensure that the correct subclasses are returned from a query"""
|
"""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 Fish(Animal): pass
|
||||||
class Mammal(Animal): pass
|
class Mammal(Animal): pass
|
||||||
class Human(Mammal): pass
|
class Human(Mammal): pass
|
||||||
@ -223,7 +246,8 @@ class DocumentTest(unittest.TestCase):
|
|||||||
"""Ensure that the correct subclasses are returned from a query when
|
"""Ensure that the correct subclasses are returned from a query when
|
||||||
using references / generic references
|
using references / generic references
|
||||||
"""
|
"""
|
||||||
class Animal(Document): pass
|
class Animal(Document):
|
||||||
|
meta = {'allow_inheritance': True}
|
||||||
class Fish(Animal): pass
|
class Fish(Animal): pass
|
||||||
class Mammal(Animal): pass
|
class Mammal(Animal): pass
|
||||||
class Human(Mammal): pass
|
class Human(Mammal): pass
|
||||||
@ -302,7 +326,8 @@ class DocumentTest(unittest.TestCase):
|
|||||||
self.Person._get_collection_name())
|
self.Person._get_collection_name())
|
||||||
|
|
||||||
# Ensure that MRO error is not raised
|
# Ensure that MRO error is not raised
|
||||||
class A(Document): pass
|
class A(Document):
|
||||||
|
meta = {'allow_inheritance': True}
|
||||||
class B(A): pass
|
class B(A): pass
|
||||||
class C(B): pass
|
class C(B): pass
|
||||||
|
|
||||||
@ -597,6 +622,7 @@ class DocumentTest(unittest.TestCase):
|
|||||||
'tags',
|
'tags',
|
||||||
('category', '-date')
|
('category', '-date')
|
||||||
],
|
],
|
||||||
|
'allow_inheritance': True
|
||||||
}
|
}
|
||||||
|
|
||||||
BlogPost.drop_collection()
|
BlogPost.drop_collection()
|
||||||
@ -996,6 +1022,8 @@ class DocumentTest(unittest.TestCase):
|
|||||||
username = StringField(primary_key=True)
|
username = StringField(primary_key=True)
|
||||||
name = StringField()
|
name = StringField()
|
||||||
|
|
||||||
|
meta = {'allow_inheritance': True}
|
||||||
|
|
||||||
User.drop_collection()
|
User.drop_collection()
|
||||||
|
|
||||||
self.assertEqual(User._fields['username'].db_field, '_id')
|
self.assertEqual(User._fields['username'].db_field, '_id')
|
||||||
@ -1045,6 +1073,8 @@ class DocumentTest(unittest.TestCase):
|
|||||||
class Place(Document):
|
class Place(Document):
|
||||||
name = StringField()
|
name = StringField()
|
||||||
|
|
||||||
|
meta = {'allow_inheritance': True}
|
||||||
|
|
||||||
class NicePlace(Place):
|
class NicePlace(Place):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ class DynamicDocTest(unittest.TestCase):
|
|||||||
|
|
||||||
class Person(DynamicDocument):
|
class Person(DynamicDocument):
|
||||||
name = StringField()
|
name = StringField()
|
||||||
|
meta = {'allow_inheritance': True}
|
||||||
|
|
||||||
Person.drop_collection()
|
Person.drop_collection()
|
||||||
|
|
||||||
|
@ -20,4 +20,4 @@ class Mixin(object):
|
|||||||
|
|
||||||
|
|
||||||
class Base(Document):
|
class Base(Document):
|
||||||
pass
|
meta = {'allow_inheritance': True}
|
||||||
|
@ -20,6 +20,7 @@ class QuerySetTest(unittest.TestCase):
|
|||||||
class Person(Document):
|
class Person(Document):
|
||||||
name = StringField()
|
name = StringField()
|
||||||
age = IntField()
|
age = IntField()
|
||||||
|
meta = {'allow_inheritance': True}
|
||||||
self.Person = Person
|
self.Person = Person
|
||||||
|
|
||||||
def test_initialisation(self):
|
def test_initialisation(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user