[Python-Dev] PEP 343 and __with__
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