How do I know when I can/should use `with` keyword?
<p>In C#, when an object implements <code>IDisposable</code>, <code>using</code> should be used to guarantee that resources will be cleaned if an exception is thrown. For instance, instead of:</p>

<pre class="lang-cs prettyprint-override"><code>var connection = new SqlConnection(...);
...
connection.Close();
</code></pre>

<p>one needs to write:</p>

<pre class="lang-cs prettyprint-override"><code>using (var connection = new SqlConnection(...))
{
    ...
}
</code></pre>

<p>Therefore, just by looking at the signature of the class, I know exactly whether or not I should initialize the object inside a <code>using</code>.</p>

<p>In Python 3, a similar construct is <code>with</code>. Similarly to C#, it ensures that the resources will be cleaned up automatically when exiting the <code>with</code> context, even if a error is raised.</p>

<p>However, I'm not sure how should I determine whether <code>with</code> should be used or not for a specific class. For instance, <a href="http://initd.org/psycopg/docs/usage.html" rel="nofollow">an example from <code>psycopg</code></a> doesn't use <code>with</code>, which may mean that:</p>

<ul>
<li>I shouldn't either, or:</li>
<li>The example is written for Python 2, or:</li>
<li>The authors of the documentation were unaware of <code>with</code> syntax, or:</li>
<li>The authors decided not to handle exceptional cases for the sake of simplicity.</li>
</ul>

<p>In general, how should I determine whether <code>with</code> should be used when initializing an instance of a specific class (assuming that documentation says nothing on the subject, and that I have access to source code)?</p>

<h3>Regarding when you <em>should</em> use it:</h3>

<p>No one forces you to use the <code>with</code> statement, it's just syntactic sugar that's there to make your life easier. If you use it or not is totally up to you but, it is generally recommended to do so. (We're forgetful and <code>with ...</code> looks ways better than explicit initialize resource/finalize recourse calls).</p>

<h3>When you <em>can</em> use it:</h3>

<p>When you <em>can</em> use it boils down to examining if it defines the context manager protocol. This could be as simple as trying to use <code>with</code> and seeing that it fails :-)</p>

<p>If you dynamically need to check if an object <em>is</em> a context manager, you have two options.</p>

<p>First, wait for the stable release of <code>Python 3.6</code> which defines an <code>ABC</code> for context managers, <code>ContextManager</code>, which can be used in <code>issubclass/isinstance</code> checks:</p>

<pre><code>&gt;&gt;&gt; from typing import ContextManager
&gt;&gt;&gt; class foo:
...     def __enter__(self): pass
...     def __exit__(self): pass
... 
&gt;&gt;&gt; isinstance(foo(), ContextManager)
True
&gt;&gt;&gt; class foo2: pass
... 
&gt;&gt;&gt; isinstance(foo2(), ContextManager)
False
</code></pre>

<p>Or, create your own little function to check for it:</p>

<pre><code>def iscontext(inst):
    cls = type(inst)
    return (any("__enter__" in vars(a) for a in cls.__mro__) and
            any("__exit__" in vars(a) for a in cls.__mro__))
</code></pre>

<p>As a final note, the <code>with</code> statement is present in <code>Python 2</code> and in <code>3</code>, the use case you saw probably just wasn't aware of it :-).</p>

python python-3.x with-statement