[Python-Dev] PEP 343 and __with__

Jason Orendorff jason.orendorff at gmail.com
Mon Oct 3 18:37:22 CEST 2005

I'm -1 on PEP 343.  It seems ...complex.  And even with all the
complexity, I *still* won't be able to type

    with self.lock: ...

which I submit is perfectly reasonable, clean, and clear.  Instead I
have to type

    with locking(self.lock): ...

where locking() is apparently either a new builtin, a standard library
function, or some 6-line contextmanager I have to write myself.

So I have two suggestions.

1.  I didn't find any suggestion of a __with__() method in the
archives.  So I feel I should suggest it.  It would work just like

    class RLock:
        def __with__(self):

__with__() always returns a new context manager object.  Just as with
iterators, a context manager object has "cm.__with__() is cm".

The 'with' statement would call __with__(), of course.

Optionally, the type constructor could magically apply @contextmanager
to __with__() if it's a generator, which is the usual case.  It looks
like it already does similar magic with __new__().  Perhaps this is
too cute though.

2.  More radical:  Let's get rid of __enter__() and __exit__().  The
only example in PEP 343 that uses them is Example 4, which exists only
to show that "there's more than one way to do it". It all seems fishy
to me.  Why not get rid of them and use only __with__()?  In this
scenario, Python would expect __with__() to return a coroutine (not to
say "iterator") that yields exactly once.

Then the "@contextmanager" decorator wouldn't be needed on __with__(),
and neither would any type constructor magic.

The only drawback I see is that context manager methods implemented in
C will work differently from those implemented in Python.  Since C
doesn't have coroutines, I imagine there would have to be enter() and
exit() slots.  Maybe this is a major design concern; I don't know.

My apologies if this is redundant or unwelcome at this date.


More information about the Python-Dev mailing list