[Python-Dev] PEP 343 and __with__

Phillip J. Eby pje at telecommunity.com
Mon Oct 3 19:02:40 CEST 2005

At 12:37 PM 10/3/2005 -0400, Jason Orendorff wrote:
>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.

Which is why it's proposed to add __enter__/__exit__ to locks, and somewhat 
more controversially, file objects.  (Guido objected on the basis that 
people might reuse the file object, but reusing a closed file object 
results in a sensible error message and so doesn't seem like a problem to me.)

>__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.

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

>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.

Because this multiplies the difficulty of implementing context managers in 
C.  It's easy to define a pair of C methods for __enter__ and __exit__, but 
an iterator requires creating another class in C.  The yield-based syntax 
is just syntax sugar, not the essence of the proposal.

>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.

Considering your argument that locks should be contextmanagers, it would 
seem like a good idea for C implementations to be easy.  :)

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

Since the PEP is accepted and has patches for both its implementation and a 
good part of its documentation, a major change like this would certainly 
need a better rationale.  If your idea was that __with__ would somehow make 
it easier for locks to be context managers, it's based on a flawed 
premise.  All that's required now is to have __enter__ and __exit__ call 
acquire() and release().  At this point, it's simply an open issue as to 
which stdlib objects will be context managers, and which will have helper 
functions or classes to serve as context managers.  The actual API used to 
implement them has little or no bearing on that issue.

More information about the Python-Dev mailing list