Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>from the <a href="http://docs.python.org/2/reference/datamodel.html#object.__exit__">Data model entry for <code>object.__exit__</code></a></p> <blockquote> <p>If an exception is supplied, and the method wishes to suppress the exception (i.e., prevent it from being propagated), it should return a true value. Otherwise, the exception will be processed normally upon exit from this method.</p> </blockquote> <p>In your <code>__exit__</code> function, you're returning <code>True</code> which will suppress <em>all</em> exceptions. If you change it to return <code>False</code>, the exceptions will continue to be raised as normal (with the only difference being that you guarantee that your <code>__exit__</code> function gets called and you can make sure to clean up after yourself)</p> <p>For example, changing the code to:</p> <pre><code>def __exit__(self, exctype, value, tb): print " __exit__; excptype: '%s'; value: '%s'" % (exctype, value) if exctype is GeneratorExit: return False return True </code></pre> <p>allows you to do the right thing and not suppress the <code>GeneratorExit</code>. Now you <em>only</em> see the attribute error. Maybe the rule of thumb should be the same as with any Exception handling -- <strong>only intercept Exceptions if you know how to handle them</strong>. Having an <code>__exit__</code> return <code>True</code> is on par (maybe slightly worse!) than having a bare except:</p> <pre><code>try: something() except: #Uh-Oh pass </code></pre> <hr> <p>Note that when the <code>AttributeError</code> is raised (and not caught), I believe that causes the reference count on your generator object to drop to 0 which then triggers a <code>GeneratorExit</code> exception within the generator so that it can clean itself up. Using my <code>__exit__</code>, play around with the following two cases and hopefully you'll see what I mean:</p> <pre><code>try: for item in foo(10): print 'Fail - val: %d' % item.val item.not_an_attribute except AttributeError: pass print "Here" #No reference to the generator left. #Should see __exit__ before "Here" </code></pre> <p>and</p> <pre><code>g = foo(10) try: for item in g: print 'Fail - val: %d' % item.val item.not_an_attribute except AttributeError: pass print "Here" b = g #keep a reference to prevent the reference counter from cleaning this up. #Now we see __exit__ *after* "Here" </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload