<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<br>
<div class="moz-cite-prefix">On 5/5/2016 10:17 PM, Nick Coghlan
wrote:<br>
</div>
<blockquote
cite="mid:CADiSq7enGfVypP4bSNc5VJL+kfOs6g63OsKTtFeLAzHT6L0v4g@mail.gmail.com"
type="cite">
<pre wrap="">On 6 May 2016 at 05:17, Kyle Lahnakoski <a class="moz-txt-link-rfc2396E" href="mailto:klahnakoski@mozilla.com"><klahnakoski@mozilla.com></a> wrote:
</pre>
<blockquote type="cite">
<pre wrap="">May you provide me with an example of how contextmanager would help with
the indentation?
</pre>
</blockquote>
<pre wrap="">
contextmanager doesn't, ExitStack does (which is in the standard
library for 3.3+, and available via contextlib2 for earlier versions).
</pre>
</blockquote>
<br>
Thank you for the examples, and they do reduce indention when you
have callbacks defined, or dealing with resources. This does not
seem to help in the case of exception handlers. Exception handlers
have access to block scope variables, and have code blocks that do
not require a `def`.<br>
<br>
I should have added different types of exception handlers to my
initial email to distract from the chaining exception. Consider
the exception handler that simply stops trying to process the todo
items:<br>
<pre><code>____def process_todo(todo):
</code><code><code>____</code></code><code><code>____</code>pre_process()
</code><code><code><code>____</code></code></code><code><code><code>____</code></code></code><code><code><code></code></code>for t in todo:
</code><code><code><code><code>____</code></code></code><code><code><code>________exc</code></code></code><code><code><code></code></code></code></code><code><code><code><code></code></code></code><code><code><code></code></code></code>ept Exception, e:
</code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code>break</code>
<code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code>process(t)
</code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code>post_process()
As an alternative to
</code><code>____def process_todo(todo):
</code><code><code>____</code></code><code><code>____</code>pre_process()
</code><code><code><code>____</code></code></code><code><code><code>____</code></code></code><code><code><code></code></code>for t in todo:
</code><code><code><code><code>____________try
</code></code></code></code><code><code><code><code><code><code><code><code>_____</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code>process(t)
</code>____</code></code></code><code><code><code>________exc</code></code></code><code><code><code></code></code></code></code><code><code><code><code></code></code></code><code><code><code></code></code></code>ept Exception, e:
</code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code>break</code>
<code><code><code><code>_</code></code></code><code><code><code>___</code></code></code></code><code><code><code><code>_</code></code></code><code><code><code>___</code></code></code>post_process()
</code>
</pre>
<p>Of course, a couple `try` nested statements make the indentation
worse. For example, we wish to ignore problems in dealing with
todo items, like above, but the todo items are complicated; each
is a dict() of details. Failure to deal with one of the details
is ignored, but the rest of the details are still attempted: </p>
<pre><code>def process_todo(todo):
____pre_process()
____for t in todo:
________except Exception, e:
____________break
________for u, v in t.items():
____________except Exception, e:
________________continue
____________process()
____post_process()
Which is better than what I do now:
def process_todo(todo):
____pre_process()
____for t in todo:
________try:
____________for u, v in t.items():
________________try:
____________________process()
________________except Exception, e:
____________________continue
________except Exception, e:
____________break
____post_process()
</code></pre>
<br>
<code>I have not touched on more complicated except clauses; ones
that have multiple lines, and ones that use, or update
block-scoped variables.<br>
<br>
ExitStack is good for manipulating `with` clauses as first order
objects, but they are limited to what you can do with `with`
statements: Limited to naive exception handling, or simple
chaining. If was to use ExitStack in the example above (using
`continue` and `exit`), maybe I would write something like:<br>
<br>
def process_todo(todo):<br>
____with ExitStack() as stack:<br>
________pre_process()<br>
________for t in todo:<br>
____________stack.enter_context(BreakOnException())<br>
____________for u, v in t.items():<br>
________________stack.enter_context(ContinueOnException())<br>
________________process()<br>
________________stack.pop() # DOES THIS EXIST? IT SHOULD<br>
________post_process() <br>
<br>
</code>
<p><code>This terrible piece of (not working) code assumes it is
even possible to write a `BreakOnException` and
`ContinueOnException`. It also requires a `pop` method, which is
not documented, but really should exist. Without a `pop`
method, I would need another ExitStack instance, and a `with`
statement to hold it.</code></p>
<p><code></code></p>
<p><code></code></p>
<p><code>I hope I have convinced you that ExitStack, and `with`
block magic, does a poor job of covering the use cases for `try`
statements. Maybe I should make examples that use the loop
variables in the `except` clause for more examples?</code></p>
<p><code></code></p>
<p><code>At a high level: The `try/except/finally` is powerful
structure. Realizing that the `try/finally` pair is very common
leads to the creation of `with`. I am proposing the same logic
for `try/catch` pair: They are commonly paired together and
should have an optimized syntax. </code></p>
<p><code></code><code></code></p>
<pre><code>
</code></pre>
</body>
</html>