[Python-ideas] Relax __exit__ method to be a generator
Guido van Rossum
guido at python.org
Mon Apr 7 03:04:55 CEST 2014
Well, for new syntax, the bar is pretty high... And we should probably move
to python-ideas.
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)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140406/2e93193e/attachment-0001.html>
More information about the Python-ideas
mailing list