[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