How to return the values of functions called with yield in a ContextManager - Python

Viewed 36

I am trying to organize my code by removing a lot of repetitive logic. I felt like this would be a great use case for a context manager.

When making certain updates in the system, 4 things always happen -

  1. We lock the resource to prevent concurrent updates
  2. We wrap our logic in a database transaction
  3. We validate the data making sure the update is permissible
  4. After the function executes we add history rows to the database

I want a wrapper to encapsulate this like below

from contextlib import contextmanager

@contextmanager
def my_manager(resource_id):
    try:
        with lock(resource_id), transaction.atomic():
            validate_data(resource_id)

            resources = yield 

            create_history_objects(resources)
    except LockError:
        raise CustomError

def update(resource_id):
    with my_manager(resource_id):
        _update(resource_id)

def _update(resource_id):
   # do something 
   return resource

Everything works as expected except my ability to access resources in the contextmanager, which are None. The resources are returned from the function that's called during the yield statement.

What is the proper way to access those resources through yield or maybe another utility? Thanks

0 Answers
Related