
import threading
from functools import wraps

threadlocal = threading.local()


class thread_local_router(object):
    """ a decorator that wraps a function in a thread local definition block
    useful for passing variables down the stack w/o.

    Usage:

    @thread_local(DB_FOR_READ_OVERRIDE='foobar')
    def override(request):
        ...

    """

    def __init__(self, **kwargs):
        self.options = kwargs

    def __enter__(self):
        for attr, value in self.options.items():
            setattr(threadlocal, attr, value)

    def __exit__(self, exc_type, exc_value, traceback):
        for attr in self.options.keys():
            delattr(threadlocal, attr)

    def __call__(self, func):

        @wraps(func)
        def inner(*args, **kwargs):
            # the thread_local class is also a context manager
            # which means it will call __enter__ and __exit__
            with self:
                return func(*args, **kwargs)

        return inner