<p>The same problem–not closing your files–can also show up if your
program opens a large number of files without closing them explicitly.
In that case, you can easily hit the system limit on the number of file
...
...
@@ -129,7 +129,7 @@
<p>Similarly, remember that you must <ttclass="docutils literal">close()</tt> a non-exhausted
generator in order to have its pending <ttclass="docutils literal">finally</tt> or <ttclass="docutils literal">with</tt>
clauses executed immediately:</p>
<divclass="syntax python"><pre><span></span><spanclass="k">def</span><spanclass="nf">mygen</span><spanclass="p">():</span><br/><spanclass="k">with</span><spanclass="n">foo</span><spanclass="p">:</span><br/><spanclass="k">yield</span><spanclass="mi">42</span><br/><br/><spanclass="k">for</span><spanclass="n">x</span><spanclass="ow">in</span><spanclass="n">mygen</span><spanclass="p">():</span><br/><spanclass="k">if</span><spanclass="n">x</span><spanclass="o">==</span><spanclass="mi">42</span><spanclass="p">:</span><br/><spanclass="k">break</span><spanclass="c1"># foo.__exit__ is not run immediately!</span><br/><br/><spanclass="c1"># fixed version:</span><br/><spanclass="n">gen</span><spanclass="o">=</span><spanclass="n">mygen</span><spanclass="p">()</span><br/><spanclass="k">try</span><spanclass="p">:</span><br/><spanclass="k">for</span><spanclass="n">x</span><spanclass="ow">in</span><spanclass="n">gen</span><spanclass="p">:</span><br/><spanclass="k">if</span><spanclass="n">x</span><spanclass="o">==</span><spanclass="mi">42</span><spanclass="p">:</span><br/><spanclass="k">break</span><br/><spanclass="k">finally</span><spanclass="p">:</span><br/><spanclass="n">gen</span><spanclass="o">.</span><spanclass="n">close</span><spanclass="p">()</span><br/></pre></div>
<divclass="syntax python"><pre><spanclass="k">def</span><spanclass="nf">mygen</span><spanclass="p">():</span><br/><spanclass="k">with</span><spanclass="n">foo</span><spanclass="p">:</span><br/><spanclass="k">yield</span><spanclass="mi">42</span><br/><br/><spanclass="k">for</span><spanclass="n">x</span><spanclass="ow">in</span><spanclass="n">mygen</span><spanclass="p">():</span><br/><spanclass="k">if</span><spanclass="n">x</span><spanclass="o">==</span><spanclass="mi">42</span><spanclass="p">:</span><br/><spanclass="k">break</span><spanclass="c"># foo.__exit__ is not run immediately!</span><br/><br/><spanclass="c"># fixed version:</span><br/><spanclass="n">gen</span><spanclass="o">=</span><spanclass="n">mygen</span><spanclass="p">()</span><br/><spanclass="k">try</span><spanclass="p">:</span><br/><spanclass="k">for</span><spanclass="n">x</span><spanclass="ow">in</span><spanclass="n">gen</span><spanclass="p">:</span><br/><spanclass="k">if</span><spanclass="n">x</span><spanclass="o">==</span><spanclass="mi">42</span><spanclass="p">:</span><br/><spanclass="k">break</span><br/><spanclass="k">finally</span><spanclass="p">:</span><br/><spanclass="n">gen</span><spanclass="o">.</span><spanclass="n">close</span><spanclass="p">()</span><br/></pre></div>
<p>More generally, <ttclass="docutils literal">__del__()</tt> methods are not executed as predictively
as on CPython: they run “some time later” in PyPy (or not at all if
the program finishes running in the meantime). See <aclass="reference external"href="http://pypy.readthedocs.org/en/latest/cpython_differences.html#differences-related-to-garbage-collection-strategies">more details