On Thu, Mar 1, 2012 at 6:29 AM, Arnaud Delobelle <arnodel@gmail.com> wrote:
On 29 February 2012 17:49, Craig Yoshioka <craigyk@me.com> wrote:
I've tried classes, decorators, and passing the conditional using 'as', as suggested by Michael, so I disagree that with is not suitable here since I have yet to find a better alternative. If you want I can give pretty concrete examples in the ways they aren't as good. Furthermore, I think it could be argued that it makes more sense to be able to safely skip the with body without the user of the with statement having to manually catch the exception themselves....
From PEP 343:
But the final blow came when I read Raymond Chen's rant about flow-control macros[1]. Raymond argues convincingly that hiding flow control in macros makes your code inscrutable, and I find that his argument applies to Python as well as to C.
So it is explicitly stated that the with statement should not be capable of controlling the flow.
Indeed. Craig, if you want to pursue this to the extent of writing up a full PEP, I suggest starting with the idea I briefly wrote up a while ago [1]. Instead of changing the semantics of __enter__, add a new optional method __entered__ to the protocol that executes inside the with statement's implicit try/except block. That is (glossing over the complexities in the real with statement expansion), something roughly like: _exit = cm.__exit__ _entered = getattr(cm, "__entered__", None) _var = cm.__enter__() try: if _entered is not None: _var = _entered(_var) VAR = _var # if 'as' clause is present # with statement body finally: _exit(*sys.exc_info()) Then CM's would be free to skip directly from __entered__ to __exit__ by raising a custom exception. GeneratorContextManagers could similarly be updated to handle the case where the underlying generator doesn't yield. However, that last point highlights why I no longer like the idea: it makes it *really* easy to accidentally create CM's that, instead of throwing an exception if you try to reuse them inappropriately, will instead silently skip the with statement body. The additional expressiveness provided by such a construct is minimal, but the additional risk of incorrectly silencing errors is quite high - that's not a good trade-off for the overall language design. [1] http://readthedocs.org/docs/ncoghlan_devs-python-notes/en/latest/pep_ideas/s... Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia