Skip to content

Commit

Permalink
apply @brondsem patch, update now resets state.original_document
Browse files Browse the repository at this point in the history
  • Loading branch information
CastixGitHub committed May 14, 2022
1 parent 25c2982 commit b8db156
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 11 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ parsetab_*
.tox
.eggs/
venv/
.\#*
\#*\#
5 changes: 3 additions & 2 deletions ming/odm/mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ def update(self, obj, state, session, **kwargs):
doc = self.collection(state.document, skip_from_bson=True)
ret = session.impl.save(doc, validate=False, state=state)
state.status = state.clean
# Make sure that st.document is never the same as st.original_document
# otherwise mutating one mutates the other.
state.original_document = deepcopy(doc)
return ret

@_with_hooks('delete')
Expand Down Expand Up @@ -183,8 +186,6 @@ def _from_doc(self, doc, options, validate=True):

# Make sure that st.document is never the same as st.original_document
# otherwise mutating one mutates the other.
# There is no need to deepcopy as nested mutable objects are already
# copied by InstrumentedList and InstrumentedObj to instrument them.
st.original_document = deepcopy(doc)

if validate is False:
Expand Down
17 changes: 8 additions & 9 deletions ming/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

log = logging.getLogger(__name__)


def annotate_doc_failure(func):
'''Decorator to wrap a session operation so that any pymongo errors raised
will note the document that caused the failure
Expand All @@ -30,7 +31,7 @@ def wrapper(self, doc, *args, **kwargs):
return update_wrapper(wrapper, func)


class Session(object):
class Session:
_registry = {}
_datastores = {}

Expand Down Expand Up @@ -152,15 +153,13 @@ def _prep_save(self, doc, validate):
return data

@annotate_doc_failure
def save(self, doc, state=None, **kwargs):
# args was meant to be the list of changed fields
# but actually we ended up checking the differences here
def save(self, doc, *args, state=None, **kwargs):
data = self._prep_save(doc, kwargs.pop('validate', True))
if state is not None and state.original_document:
if state is not None:
args = tuple(set((k for k, v in
doc_to_set(state.original_document)
^ doc_to_set(data))))
if not args and state is not None and state.original_document:
args = tuple(set((k for k, v in
doc_to_set(state.original_document)
^ doc_to_set(data))))
if args:
values = dict((arg, data[arg]) for arg in args)
result = self._impl(doc).update(
dict(_id=doc._id), {'$set': values}, **fix_write_concern(kwargs))
Expand Down
17 changes: 17 additions & 0 deletions ming/tests/odm/test_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,23 @@ def test_group(self, pymongo_group):
self.Basic.query.group()
assert pymongo_group.called

def test_multiple_update_flushes(self):
initial_doc = self.Basic()
initial_doc.a = 1
self.session.flush()
self.session.close()

doc_updating = self.Basic.query.get(_id=initial_doc._id)
doc_updating.a = 2
self.session.flush()
doc_updating.a = 1 # back to "initial" value
doc_updating.e = 'foo' # change something else too
self.session.flush()
self.session.close()

doc_after_updates = self.Basic.query.get(_id=doc_updating._id)
assert doc_after_updates.a == 1


class TestRelation(TestCase):
def setUp(self):
Expand Down
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[pylint]
# disabling protected-access because of mongodb _id property
disable = protected-access

[nosetests]
detailed-errors=1

0 comments on commit b8db156

Please sign in to comment.