Unit of work
Some use cases change several things that must succeed or fail together. A unit of work groups those changes: the service makes them through it, and nothing is stored until commit(). Leaving the with block without committing throws the changes away.
import copy
class UnitOfWork:
def __init__(self, data):
self.data = data
def __enter__(self):
self.work = copy.deepcopy(self.data)
return self
def __exit__(self, *exc_info):
self.work = None
def commit(self):
self.data.update(self.work)
store = {"MUG": 3}
with UnitOfWork(store) as uow:
uow.work["MUG"] = 0
print(store) # no commit, still 3The service never learns whether it is talking to a database transaction or a copied dict. It opens the unit of work, changes things through it, and commits once, as its last step. An exception halfway leaves everything as it was, because nothing was published.
A fake unit of work can also record that commit() was called, so a test can check that the service committed.
Your task
Write InMemoryUnitOfWork(stock), where stock maps sku to quantity: entering with exposes a working copy as .stock, commit() writes the copy back into the original dict and sets committed to True, and leaving without a commit discards the changes. Write transfer(uow, from_sku, to_sku, qty) that moves stock between two skus all or nothing, raising ValueError when from_sku has too little.
The explanation opens here once every check passes.