Fix index creation error that was swallowed by hasattr under python2 (#1688)

This commit is contained in:
Bastien Gérard 2018-08-29 23:04:18 +02:00
parent 9ad959a478
commit b4860de34d
2 changed files with 27 additions and 5 deletions

View File

@ -133,7 +133,12 @@ class DeReference(object):
""" """
object_map = {} object_map = {}
for collection, dbrefs in self.reference_map.iteritems(): for collection, dbrefs in self.reference_map.iteritems():
if hasattr(collection, 'objects'): # We have a document class for the refs
# we use getattr instead of hasattr because as hasattr swallows any exception under python2
# so it could hide nasty things without raising exceptions (cfr bug #1688))
ref_document_cls_exists = (getattr(collection, 'objects', None) is not None)
if ref_document_cls_exists:
col_name = collection._get_collection_name() col_name = collection._get_collection_name()
refs = [dbref for dbref in dbrefs refs = [dbref for dbref in dbrefs
if (col_name, dbref) not in object_map] if (col_name, dbref) not in object_map]

View File

@ -8,9 +8,12 @@ import weakref
from datetime import datetime from datetime import datetime
from bson import DBRef, ObjectId from bson import DBRef, ObjectId
from pymongo.errors import DuplicateKeyError
from tests import fixtures from tests import fixtures
from tests.fixtures import (PickleEmbedded, PickleTest, PickleSignalsTest, from tests.fixtures import (PickleEmbedded, PickleTest, PickleSignalsTest,
PickleDynamicEmbedded, PickleDynamicTest) PickleDynamicEmbedded, PickleDynamicTest)
from tests.utils import MongoDBTestCase
from mongoengine import * from mongoengine import *
from mongoengine.base import get_document, _document_registry from mongoengine.base import get_document, _document_registry
@ -30,12 +33,9 @@ TEST_IMAGE_PATH = os.path.join(os.path.dirname(__file__),
__all__ = ("InstanceTest",) __all__ = ("InstanceTest",)
class InstanceTest(unittest.TestCase): class InstanceTest(MongoDBTestCase):
def setUp(self): def setUp(self):
connect(db='mongoenginetest')
self.db = get_db()
class Job(EmbeddedDocument): class Job(EmbeddedDocument):
name = StringField() name = StringField()
years = IntField() years = IntField()
@ -3248,6 +3248,23 @@ class InstanceTest(unittest.TestCase):
blog.reload() blog.reload()
self.assertEqual(blog.tags, [["value1", 123]]) self.assertEqual(blog.tags, [["value1", 123]])
def test_accessing_objects_with_indexes_error(self):
insert_result = self.db.company.insert_many([{'name': 'Foo'},
{'name': 'Foo'}]) # Force 2 doc with same name
REF_OID = insert_result.inserted_ids[0]
self.db.user.insert_one({'company': REF_OID}) # Force 2 doc with same name
class Company(Document):
name = StringField(unique=True)
class User(Document):
company = ReferenceField(Company)
# Ensure index creation exception aren't swallowed (#1688)
with self.assertRaises(DuplicateKeyError):
User.objects().select_related()
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()