[Python-ideas] Relax __exit__ method to be a generator

Nick Coghlan ncoghlan at gmail.com
Tue Apr 8 05:18:49 CEST 2014


On 6 Apr 2014 21:13, "Devin Jeanpierre" <jeanpierreda at gmail.com> wrote:
>
> On Sun, Apr 6, 2014 at 6:04 PM, Guido van Rossum <guido at python.org> wrote:
> > Well, for new syntax, the bar is pretty high... And we should probably
move
> > to python-ideas.
>
> And Guido's time machine strikes again! ;)

Also relevant to this topic:

http://python-notes.curiousefficiency.org/en/latest/pep_ideas/async_programming.html#additional-asynchronous-syntax

There's a review of what does and doesn't currently work before that last
subsection.

(Short version: I'm currently +0 on syntax that allows asynchronous
transactions and comprehensions, but would need to see some before/after
comparisons with real asyncio code to get me to a +1)

Cheers,
Nick.

P.S. I put the time machine keys back where I found them ;)

>
> -- Devin
>
> > On Sun, Apr 6, 2014 at 4:44 PM, Andrew Svetlov <andrew.svetlov at gmail.com
>
> > wrote:
> >>
> >> Well, this is good point..
> >>
> >> But from my experience try/finally is a common point of errors.
> >> Beginners use "with" properly as:
> >>
> >> with open(filename) as f:
> >>   f.read()
> >>
> >> but switch to try/finally produces very common error.
> >>
> >> Instead of
> >>
> >> f = open(filename)
> >> try:
> >>   f.read()
> >> finally:
> >>   f.close()
> >>
> >> people usually write
> >>
> >> try:
> >>  f = open(filename)
> >>  f.read()
> >> finally:
> >>   f.close()
> >>
> >> I saw it constantly many times. When I wrote an article about the
> >> problem and true solution in my blog I got several emails from my
> >> readers: please, tell me again why I need to move open() out of try
> >> block if it can generate exception on file opening?
> >>
> >> So maybe you would like some other syntax? For example
> >>
> >> with from obj:
> >>    BLOCK
> >>
> >> That form can use magic methods with names different than
> >> __enter__/__exit__ (and get rid of "with (yield from lock)" BTW). And
> >> it's obviously? points on two suspending points: at BLOCK enter and
> >> exit.
> >>
> >> On Mon, Apr 7, 2014 at 2:12 AM, Guido van Rossum <guido at python.org>
wrote:
> >> > I prefer to use a try/finally statement. One of the points of using
> >> > yield-from is that you can always tell where your code may be
suspended
> >> > by
> >> > searching for "yield from". With your proposed change that would no
> >> > longer
> >> > be true -- any with statement would also have to be inspected, and
there
> >> > would no longer be a way to know from the source alone whether it
might
> >> > yield or not (because it would dynamic -- there's no way to be sure
at
> >> > compile time which context manager is being used).
> >> >
> >> >
> >> > On Sun, Apr 6, 2014 at 12:02 PM, Andrew Svetlov
> >> > <andrew.svetlov at gmail.com>
> >> > wrote:
> >> >>
> >> >> Literally it may be generator itself or function that returns
generator
> >> >> object.
> >> >>
> >> >> Now I'm working on postgres library for asyncio
> >> >> (http://aiopg.readthedocs.org/).
> >> >>
> >> >> And I would to use *with statement* for transaction handling like:
> >> >>
> >> >> with (yield from cursor.transaction()):
> >> >>    yield from cursor.execute(sql)
> >> >>
> >> >> The problem is: at exit of *with statement* I need to call `yield
from
> >> >> cursor.execute('COMMIT')` or `yield from
cursor.execute('ROLLBACK')`.
> >> >>
> >> >> I can do it only in __exit__ in *context manager*, but python
> >> >> understand only if __exit__:
> >> >> - returns true value, that suppresses exception from code block
> >> >> - returns None or any false value to propagate exception if any
> >> >> - raises exception itself
> >> >>
> >> >> I propose to add new rule:
> >> >> IF the code object is generator (co_flags & CO_GENERATOR) and
__exit__
> >> >> returns generator object (isinstance(ret, types.GeneratorType))
> >> >> THEN do `yield from ret`.
> >> >>
> >> >> That's work fine if __exit__ itself is a *generator function*
> >> >> (contains `yield` or `yield from` statements): call to *generator
> >> >> function* returns *generator object*.
> >> >>
> >> >> The proposal:
> >> >> 1. Doesn't break any existing code except if user accidentally
> >> >> returns generator object instead of True from __exit__ call (he
should
> >> >> not to do this and I sure this is very rare case).
> >> >> 2. Don't requires new syntax.
> >> >>
> >> >> asyncio itself uses:
> >> >>
> >> >> with (yield from lock):
> >> >>    BLOCK
> >> >>
> >> >> for locking etc but unlocking for asyncio objects doesn't requires
any
> >> >> `yield from`, so __exit__ code is just plain function but not
> >> >> generator.
> >> >>
> >> >> Also I can live with asyncio trick for __enter__:
> >> >> https://code.google.com/p/tulip/source/browse/asyncio/locks.py#156
> >> >> The way is a but annoying but unrolling a value returned by
__enter__
> >> >> if the value is generator object will break existing code, sure.
> >> >>
> >> >> Thoughts?
> >> >>
> >> >>
> >> >> --
> >> >> Thanks,
> >> >> Andrew Svetlov
> >> >> _______________________________________________
> >> >> Python-ideas mailing list
> >> >> Python-ideas at python.org
> >> >> https://mail.python.org/mailman/listinfo/python-ideas
> >> >> Code of Conduct: http://python.org/psf/codeofconduct/
> >> >
> >> >
> >> >
> >> >
> >> > --
> >> > --Guido van Rossum (python.org/~guido)
> >>
> >>
> >>
> >> --
> >> Thanks,
> >> Andrew Svetlov
> >
> >
> >
> >
> > --
> > --Guido van Rossum (python.org/~guido)
> >
> > _______________________________________________
> > Python-ideas mailing list
> > Python-ideas at python.org
> > https://mail.python.org/mailman/listinfo/python-ideas
> > Code of Conduct: http://python.org/psf/codeofconduct/
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140408/f369a8b8/attachment.html>


More information about the Python-ideas mailing list