Added FutureWarning for inherited classes not declaring allow_inheritance
Refs #437
This commit is contained in:
		| @@ -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): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user