Python: decorator/wrapper for try/except statement
<p>I have some blocks of code which need to be wrapped by function.</p>

<pre><code>try:
    if config.DEVELOPMENT == True:
        # do_some_stuff
except:
    logger.info("Config is not set for development")
</code></pre>

<p>Then I'll do again:</p>

<pre><code>try:
    if config.DEVELOPMENT == True:
        # do_some_another_stuff
except:
    logger.info("Config is not set for development")
</code></pre>

<p>So, how can I wrap this "do_some_stuff" and "do_some_another_stuff"?</p>

<p>I'm trying to write function with contextmanager:</p>

<pre><code>@contextmanager
def try_dev_config(name):
    try:
        if name is not None:
            yield
    except Exception as e:
        print "not dev config"

with try_dev_config("config.DEVELOPMENT"):
    # do_some_stuff
</code></pre>

<p>And I got an error:</p>

<blockquote>
  <p>RuntimeError: generator didn't yield</p>
</blockquote>

<p>I am not sure that a context manager is the good method to achieve what you want. The context manager goal is to provide a mecanism to open/instantiate a resource, give access to it (or not) and close/clean it automatically when you no more need it.</p>

<p>IMHO, what you need is a <a href="http://thecodeship.com/patterns/guide-to-python-function-decorators/" rel="nofollow">decorator</a>.
A decorator aims at executing code around a function call. It would force you to put each block of code in a function but I don't think it is so difficult. You can implement it like this:</p>

<pre><code>class Config(object):
    """for demonstration purpose only: used to have a config.DEVELOPMENT value"""
    DEVELOPMENT = True

class Logger(object):
    """for demonstration purpose only: used to have a logger.info method"""
    @staticmethod
    def info(msg):
        print("Logged: {}".format(msg))

def check_dev_config(config, logger):
    def dev_config_checker(func):
        def wrapper(*args, **kwargs):
            try:
                if config.DEVELOPMENT:
                    func(*args, **kwargs)
            except Exception as err:
                logger.info(
                    "Config is not set for developpement: {}".format(err))
        return wrapper
    return dev_config_checker

@check_dev_config(Config, Logger)
def do_stuff_1():
    print("stuff 1 done")

@check_dev_config(Config, Logger)
def do_stuff_2():
    raise Exception("stuff 2 failed")

do_stuff_1()
do_stuff_2()
</code></pre>

<p>This code prints</p>

<pre><code>stuff 1 done
Logged: Config is not set for developpement: stuff 2 failed
</code></pre>

<p>Explanations:</p>

<ul>
<li>The <code>check_dev_config</code> function is actually a decorator generator which accepts the <code>config</code> and the <code>logger</code> as arguments.</li>
<li>It returns the <code>dev_config_checker</code> function which is an actual (and parameterised) decorator, and which accepts a function to decorate as argument.</li>
<li>This decorator returns a <code>wrapper</code> function which will actually run code around the decorated function call. In this function, the decorated function is called inside a <code>try/except</code> structure and only if the <code>config.DEVELOPMENT</code> is evaluated to True. In case of exception, the <code>logger</code> is used to log an information.</li>
<li>Each block of code to decorate is put into a function (<code>do_stuff_1</code>, <code>do_stuff_2</code> and decorated with the <code>check_dev_config</code> decorator generator, giving it the <code>config</code> and the <code>logger</code>.</li>
<li>When decorated functions are called, they are called via their decorator and not directly. As you can see, the <code>do_stuff_2</code> exception has been catched and the a message has been logged.</li>
</ul>

python try-catch wrapper decorator