Skip to content

Commit

Permalink
Reverted EmbeddedDocuments meta handling.
Browse files Browse the repository at this point in the history
You now can turn off inheritance (MongoEngine#119)
  • Loading branch information
rozza committed Sep 7, 2012
1 parent 9963715 commit a2183e3
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 18 deletions.
4 changes: 4 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Changelog
=========

Changes in 0.7.3
================
- Reverted EmbeddedDocuments meta handling - now can turn off inheritance (MongoEngine/mongoengine#119)

Changes in 0.7.2
================
- Update index spec generation so its not destructive (MongoEngine/mongoengine#113)
Expand Down
2 changes: 1 addition & 1 deletion mongoengine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
__all__ = (document.__all__ + fields.__all__ + connection.__all__ +
queryset.__all__ + signals.__all__)

VERSION = (0, 7, 2)
VERSION = (0, 7, 3)


def get_version():
Expand Down
37 changes: 22 additions & 15 deletions mongoengine/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,10 @@ def __new__(cls, name, bases, attrs):

attrs['_is_document'] = attrs.get('_is_document', False)

# EmbeddedDocuments could have meta data for inheritance
if 'meta' in attrs:
attrs['_meta'] = attrs.pop('meta')

# Handle document Fields

# Merge all fields from subclasses
Expand Down Expand Up @@ -571,6 +575,24 @@ def __new__(cls, name, bases, attrs):
superclasses[base._class_name] = base
superclasses.update(base._superclasses)

if hasattr(base, '_meta'):
# Warn if allow_inheritance isn't set and prevent
# inheritance of classes where inheritance is set to False
allow_inheritance = base._meta.get('allow_inheritance',
ALLOW_INHERITANCE)
if (not getattr(base, '_is_base_cls', True)
and allow_inheritance is None):
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
)
elif (allow_inheritance == False and
not base._meta.get('abstract')):
raise ValueError('Document %s may not be subclassed' %
base.__name__)

attrs['_class_name'] = '.'.join(reversed(class_name))
attrs['_superclasses'] = superclasses

Expand Down Expand Up @@ -745,21 +767,6 @@ def __new__(cls, name, bases, attrs):
if hasattr(base, 'meta'):
meta.merge(base.meta)
elif hasattr(base, '_meta'):
# Warn if allow_inheritance isn't set and prevent
# inheritance of classes where inheritance is set to False
allow_inheritance = base._meta.get('allow_inheritance',
ALLOW_INHERITANCE)
if not base._is_base_cls and allow_inheritance is None:
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
)
elif (allow_inheritance == False and
not base._meta.get('abstract')):
raise ValueError('Document %s may not be subclassed' %
base.__name__)
meta.merge(base._meta)

# Set collection in the meta if its callable
Expand Down
8 changes: 8 additions & 0 deletions mongoengine/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ class EmbeddedDocument(BaseDocument):
collection. :class:`~mongoengine.EmbeddedDocument`\ s should be used as
fields on :class:`~mongoengine.Document`\ s through the
:class:`~mongoengine.EmbeddedDocumentField` field type.
A :class:`~mongoengine.EmbeddedDocument` subclass may be itself subclassed,
to create a specialised version of the embedded document that will be
stored in the same collection. To facilitate this behaviour, `_cls` and
`_types` fields are added to documents (hidden though the MongoEngine
interface though). To disable this behaviour and remove the dependence on
the presence of `_cls` and `_types`, set :attr:`allow_inheritance` to
``False`` in the :attr:`meta` dictionary.
"""

# The __metaclass__ attribute is removed by 2to3 when running with Python3
Expand Down
2 changes: 1 addition & 1 deletion python-mongoengine.spec
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
%define srcname mongoengine

Name: python-%{srcname}
Version: 0.7.2
Version: 0.7.3
Release: 1%{?dist}
Summary: A Python Document-Object Mapper for working with MongoDB

Expand Down
26 changes: 25 additions & 1 deletion tests/test_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ class Employee(self.Person):
meta = {'allow_inheritance': False}
self.assertRaises(ValueError, create_employee_class)


def test_allow_inheritance_abstract_document(self):
"""Ensure that abstract documents can set inheritance rules and that
_cls and _types will not be used.
Expand Down Expand Up @@ -366,6 +365,31 @@ class Dog(Animal):

Animal.drop_collection()

def test_allow_inheritance_embedded_document(self):

# Test the same for embedded documents
class Comment(EmbeddedDocument):
content = StringField()
meta = {'allow_inheritance': False}

def create_special_comment():
class SpecialComment(Comment):
pass

self.assertRaises(ValueError, create_special_comment)

comment = Comment(content='test')
self.assertFalse('_cls' in comment.to_mongo())
self.assertFalse('_types' in comment.to_mongo())

class Comment(EmbeddedDocument):
content = StringField()
meta = {'allow_inheritance': True}

comment = Comment(content='test')
self.assertTrue('_cls' in comment.to_mongo())
self.assertTrue('_types' in comment.to_mongo())

def test_document_inheritance(self):
"""Ensure mutliple inheritance of abstract docs works
"""
Expand Down

0 comments on commit a2183e3

Please sign in to comment.