Fixed MRO issue in base.py MongoEngine/mongoengine#95

This commit is contained in:
Ross Lawley 2012-08-24 08:54:54 +01:00
parent 03beb6852a
commit f594ece32a
2 changed files with 12 additions and 13 deletions

View File

@ -498,7 +498,7 @@ class DocumentMetaclass(type):
""" """
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs):
bases = cls._get_bases(bases) flattened_bases = cls._get_bases(bases)
super_new = super(DocumentMetaclass, cls).__new__ super_new = super(DocumentMetaclass, cls).__new__
# If a base class just call super # If a base class just call super
@ -512,7 +512,7 @@ class DocumentMetaclass(type):
# Merge all fields from subclasses # Merge all fields from subclasses
doc_fields = {} doc_fields = {}
for base in bases[::-1]: for base in flattened_bases[::-1]:
if hasattr(base, '_fields'): if hasattr(base, '_fields'):
doc_fields.update(base._fields) doc_fields.update(base._fields)
@ -561,7 +561,7 @@ class DocumentMetaclass(type):
# #
superclasses = {} superclasses = {}
class_name = [name] class_name = [name]
for base in bases: for base in flattened_bases:
if (not getattr(base, '_is_base_cls', True) and if (not getattr(base, '_is_base_cls', True) and
not getattr(base, '_meta', {}).get('abstract', True)): not getattr(base, '_meta', {}).get('abstract', True)):
# Collate heirarchy for _cls and _types # Collate heirarchy for _cls and _types
@ -614,7 +614,7 @@ class DocumentMetaclass(type):
module = attrs.get('__module__') module = attrs.get('__module__')
for exc in exceptions_to_merge: for exc in exceptions_to_merge:
name = exc.__name__ name = exc.__name__
parents = tuple(getattr(base, name) for base in bases parents = tuple(getattr(base, name) for base in flattened_bases
if hasattr(base, name)) or (exc,) if hasattr(base, name)) or (exc,)
# Create new exception and set to new_class # Create new exception and set to new_class
exception = type(name, parents, {'__module__': module}) exception = type(name, parents, {'__module__': module})
@ -676,8 +676,7 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
""" """
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs):
flattened_bases = cls._get_bases(bases)
bases = cls._get_bases(bases)
super_new = super(TopLevelDocumentMetaclass, cls).__new__ super_new = super(TopLevelDocumentMetaclass, cls).__new__
# Set default _meta data if base class, otherwise get user defined meta # Set default _meta data if base class, otherwise get user defined meta
@ -718,7 +717,7 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
del(attrs['meta']) del(attrs['meta'])
# Find the parent document class # Find the parent document class
parent_doc_cls = [b for b in bases parent_doc_cls = [b for b in flattened_bases
if b.__class__ == TopLevelDocumentMetaclass] if b.__class__ == TopLevelDocumentMetaclass]
parent_doc_cls = None if not parent_doc_cls else parent_doc_cls[0] parent_doc_cls = None if not parent_doc_cls else parent_doc_cls[0]
@ -741,7 +740,7 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
# Merge base class metas. # Merge base class metas.
# Uses a special MetaDict that handles various merging rules # Uses a special MetaDict that handles various merging rules
meta = MetaDict() meta = MetaDict()
for base in bases[::-1]: for base in flattened_bases[::-1]:
# Add any mixin metadata from plain objects # Add any mixin metadata from plain objects
if hasattr(base, 'meta'): if hasattr(base, 'meta'):
meta.merge(base.meta) meta.merge(base.meta)
@ -775,7 +774,7 @@ class TopLevelDocumentMetaclass(DocumentMetaclass):
# Only simple classes (direct subclasses of Document) # Only simple classes (direct subclasses of Document)
# may set allow_inheritance to False # may set allow_inheritance to False
simple_class = all([b._meta.get('abstract') simple_class = all([b._meta.get('abstract')
for b in bases if hasattr(b, '_meta')]) for b in flattened_bases if hasattr(b, '_meta')])
if (not simple_class and meta['allow_inheritance'] == False and if (not simple_class and meta['allow_inheritance'] == False and
not meta['abstract']): not meta['abstract']):
raise ValueError('Only direct subclasses of Document may set ' raise ValueError('Only direct subclasses of Document may set '

View File

@ -373,18 +373,18 @@ class DocumentTest(unittest.TestCase):
'allow_inheritance': True, 'allow_inheritance': True,
'abstract': True, 'abstract': True,
} }
class DateUpdatedDocument(Document): class DateUpdatedDocument(Document):
meta = { meta = {
'allow_inheritance': True, 'allow_inheritance': True,
'abstract': True, 'abstract': True,
} }
def create_my_document(): try:
class MyDocument(DateCreatedDocument, DateUpdatedDocument): class MyDocument(DateCreatedDocument, DateUpdatedDocument):
pass pass
except:
create_my_document() self.assertTrue(False, "Couldn't create MyDocument class")
def test_how_to_turn_off_inheritance(self): def test_how_to_turn_off_inheritance(self):
"""Demonstrates migrating from allow_inheritance = True to False. """Demonstrates migrating from allow_inheritance = True to False.