exec and locals

Dan Sommers dan at tombstonezero.net
Wed Feb 26 22:47:34 EST 2014


On Thu, 27 Feb 2014 00:25:45 +0000, Steven D'Aprano wrote:

> By the way, if anyone cares what my actual use-case is, I have a
> function that needs to work under Python 2.4 through 3.4, and it uses
> a with statement. With statements are not available in 2.4 (or 2.5,
> unless you give a from __future__ import). So after messing about for
> a while with circular imports and dependency injections, I eventually
> settled on some code that works something like this:

> def factory():
>     blah blah blah
>     try:
>         exec("""def inner():
>                     with something:
>                         return something
>                 """, globals(), mylocals)
>         inner = mylocals['inner']
>     except SyntaxError:
>         def inner():
>             # manually operate the context manager
>             call context manager __enter__
>             try:
>                 try:
>                     return something
>                 except:  # Yes, a bare except. Catch EVERYTHING.
>                     blah blah blah
>             finally:
>                     call context manager __exit__
>     blah blah blah
>     return inner

So why not something simpler?

def factory():

    def inner():
        '''Manually operate the context manager in order to maintain
            compatibility with Python 2.4 through 3.4.'''
        call context manager __enter__
        try:
            try:
                return something
            except:  # Yes, a bare except. Catch EVERYTHING.
                blah blah blah
        finally:
                call context manager __exit__
    blah blah blah
    return inner

I claim that the less unnecessary code you write, the fewer bugs you
will have.

Does my code misbehave under any of your target versions?



More information about the Python-list mailing list