[Python-Dev] PEP 343 and with (original) (raw)

Jason Orendorff jason.orendorff at gmail.com
Mon Oct 3 23:15:26 CEST 2005


Phillip J. Eby writes:

You didn't offer any reasons why this would be useful and/or good.

It makes it dramatically easier to write Python classes that correctly support 'with'. I don't see any simple way to do this under PEP 343; the only sane thing to do is write a separate @contextmanager generator, as all of the examples do.

Consider:

# decimal.py
class Context:
    ...
    def __enter__(self):
        ???
    def __exit__(self, t, v, tb):
        ???

DefaultContext = Context(...)

Kindly implement enter() and exit(). Make sure your implementation is thread-safe (not easy, even though decimal.getcontext/.setcontext are thread-safe!). Also make sure it supports nested 'with DefaultContext:' blocks (I don't mean lexically nested, of course; I mean nested at runtime.)

The answer requires thread-local storage and a separate stack of saved context objects per thread. It seems a little ridiculous to me.

Whereas:

class Context:
    ...
    def __with__(self):
        old = decimal.getcontext()
        decimal.setcontext(self)
        try:
            yield
        finally:
            decimal.setcontext(old)

As for the second proposal, I was thinking we'd have one mental model for context managers (block template generators), rather than two (generators vs. enter/exit methods). Enter/exit seemed superfluous, given the examples in the PEP.

[T]his multiplies the difficulty of implementing context managers in C.

Nonsense.

static PyObject *
lock_with()
{
    return PyContextManager_FromCFunctions(self, lock_acquire,

lock_release); }

There probably ought to be such an API even if my suggestion is in fact garbage (as, admittedly, still seems the most likely thing).

Cheers, -j



More information about the Python-Dev mailing list