diff --git a/docs/changelog.rst b/docs/changelog.rst index 737ec043..6d5f4a55 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,6 +8,7 @@ Development =========== - (Fill this out as you fix issues and develop your features). - EnumField improvements: now `choices` limits the values of an enum to allow +- Missing `._instance` field after deepcopy of EmbeddedField (#2202 Changes in 0.23.1 =========== diff --git a/mongoengine/document.py b/mongoengine/document.py index 9be49368..5f05b485 100644 --- a/mongoengine/document.py +++ b/mongoengine/document.py @@ -101,7 +101,7 @@ class EmbeddedDocument(BaseDocument, metaclass=DocumentMetaclass): def __getstate__(self): data = super().__getstate__() - data["_instance"] = self._instance + data["_instance"] = None return data def __setstate__(self, state): @@ -135,7 +135,7 @@ class Document(BaseDocument, metaclass=TopLevelDocumentMetaclass): create a specialised version of the document that will be stored in the same collection. To facilitate this behaviour a `_cls` field is added to documents (hidden though the MongoEngine interface). - To enable this behaviourset :attr:`allow_inheritance` to ``True`` in the + To enable this behaviour set :attr:`allow_inheritance` to ``True`` in the :attr:`meta` dictionary. A :class:`~mongoengine.Document` may use a **Capped Collection** by diff --git a/tests/document/test_instance.py b/tests/document/test_instance.py index 5d27a6cf..cd8e9b1b 100644 --- a/tests/document/test_instance.py +++ b/tests/document/test_instance.py @@ -3,7 +3,6 @@ import pickle import unittest import uuid import weakref -from copy import deepcopy from datetime import datetime import bson @@ -79,14 +78,6 @@ class TestDocumentInstance(MongoDBTestCase): else: assert field._instance == instance - def test_deepcopy(self): - """Ensure that the _instance attribute on EmbeddedDocument exists after a deepcopy""" - - doc = self.Job() - assert doc._instance is None - copied = deepcopy(doc) - assert copied._instance is None - def test_capped_collection(self): """Ensure that capped collections work properly.""" diff --git a/tests/fields/test_embedded_document_field.py b/tests/fields/test_embedded_document_field.py index 0e9784ff..8aec8515 100644 --- a/tests/fields/test_embedded_document_field.py +++ b/tests/fields/test_embedded_document_field.py @@ -1,4 +1,7 @@ +from copy import deepcopy + import pytest +from bson import ObjectId from mongoengine import ( Document, @@ -9,6 +12,7 @@ from mongoengine import ( InvalidQueryError, ListField, LookUpError, + MapField, StringField, ValidationError, ) @@ -350,3 +354,30 @@ class TestGenericEmbeddedDocumentField(MongoDBTestCase): # Test existing attribute assert Person.objects(settings__base_foo="basefoo").first().id == p.id assert Person.objects(settings__sub_foo="subfoo").first().id == p.id + + def test_deepcopy_set__instance(self): + """Ensure that the _instance attribute on EmbeddedDocument exists after a deepcopy""" + + class Wallet(EmbeddedDocument): + money = IntField() + + class Person(Document): + wallet = EmbeddedDocumentField(Wallet) + wallet_map = MapField(EmbeddedDocumentField(Wallet)) + + # Test on fresh EmbeddedDoc + emb_doc = Wallet(money=1) + assert emb_doc._instance is None + copied_emb_doc = deepcopy(emb_doc) + assert copied_emb_doc._instance is None + + # Test on attached EmbeddedDoc + doc = Person( + id=ObjectId(), wallet=Wallet(money=2), wallet_map={"test": Wallet(money=2)} + ) + assert doc.wallet._instance == doc + copied_emb_doc = deepcopy(doc.wallet) + assert copied_emb_doc._instance == doc + + copied_map_emb_doc = deepcopy(doc.wallet_map) + assert copied_map_emb_doc["test"]._instance == doc