parthtamu/rag-code-assistant
0
1<!DOCTYPE html>2 3<html lang="en" data-content_root="../">4 <head>5 <meta charset="utf-8" />6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />7<meta property="og:title" content="contextlib — Utilities for with-statement contexts" />8<meta property="og:type" content="website" />9<meta property="og:url" content="https://docs.python.org/3/library/contextlib.html" />10<meta property="og:site_name" content="Python documentation" />11<meta property="og:description" content="Source code: Lib/contextlib.py This module provides utilities for common tasks involving the with statement. For more information see also Context Manager Types and With Statement Context Managers...." />12<meta property="og:image:width" content="1146" />13<meta property="og:image:height" content="600" />14<meta property="og:image" content="https://docs.python.org/3.15/_images/social_previews/summary_library_contextlib_237a2b5d.png" />15<meta property="og:image:alt" content="Source code: Lib/contextlib.py This module provides utilities for common tasks involving the with statement. For more information see also Context Manager Types and With Statement Context Managers...." />16<meta name="description" content="Source code: Lib/contextlib.py This module provides utilities for common tasks involving the with statement. For more information see also Context Manager Types and With Statement Context Managers...." />17<meta name="twitter:card" content="summary_large_image" />18<meta name="theme-color" content="#3776ab">19 20 <title>contextlib — Utilities for with-statement contexts — Python 3.15.0a6 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">21 22 <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />23 <link rel="stylesheet" type="text/css" href="../_static/classic.css?v=234b1a7c" />24 <link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=89a2f22a" />25 <link rel="stylesheet" type="text/css" href="../_static/profiling-sampling-visualization.css?v=0c2600ae" />26 <link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />27 28 <script src="../_static/documentation_options.js?v=6b7c9ff5"></script>29 <script src="../_static/doctools.js?v=9bcbadda"></script>30 <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>31 <script src="../_static/profiling-sampling-visualization.js?v=9811ed04"></script>32 33 <script src="../_static/sidebar.js"></script>34 35 <link rel="search" type="application/opensearchdescription+xml"36 title="Search within Python 3.15.0a6 documentation"37 href="../_static/opensearch.xml"/>38 <link rel="author" title="About these documents" href="../about.html" />39 <link rel="index" title="Index" href="../genindex.html" />40 <link rel="search" title="Search" href="../search.html" />41 <link rel="copyright" title="Copyright" href="../copyright.html" />42 <link rel="next" title="abc — Abstract Base Classes" href="abc.html" />43 <link rel="prev" title="dataclasses — Data Classes" href="dataclasses.html" />44 45 46 <script defer file-types="bz2,epub,zip" data-domain="docs.python.org" src="https://analytics.python.org/js/script.file-downloads.outbound-links.js"></script>47 48 <link rel="canonical" href="https://docs.python.org/3/library/contextlib.html">49 50 51 52 53 <style>54 @media only screen {55 table.full-width-table {56 width: 100%;57 }58 }59 </style>60<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">61 <link rel="shortcut icon" type="image/png" href="../_static/py.svg">62 <script type="text/javascript" src="../_static/copybutton.js"></script>63 <script type="text/javascript" src="../_static/menu.js"></script>64 <script type="text/javascript" src="../_static/search-focus.js"></script>65 <script type="text/javascript" src="../_static/themetoggle.js"></script> 66 <script type="text/javascript" src="../_static/rtd_switcher.js"></script>67 <meta name="readthedocs-addons-api-version" content="1">68 69 </head>70<body>71<div class="mobile-nav">72 <input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"73 aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu">74 <nav class="nav-content" role="navigation">75 <label for="menuToggler" class="toggler__label">76 <span></span>77 </label>78 <span class="nav-items-wrapper">79 <a href="https://www.python.org/" class="nav-logo">80 <img src="../_static/py.svg" alt="Python logo">81 </a>82 <span class="version_switcher_placeholder"></span>83 <form role="search" class="search" action="../search.html" method="get">84 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">85 <path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>86 </svg>87 <input placeholder="Quick search" aria-label="Quick search" type="search" name="q">88 <input type="submit" value="Go">89 </form>90 </span>91 </nav>92 <div class="menu-wrapper">93 <nav class="menu" role="navigation" aria-label="main navigation">94 <div class="language_switcher_placeholder"></div>95 96<label class="theme-selector-label">97 Theme98 <select class="theme-selector" oninput="activateTheme(this.value)">99 <option value="auto" selected>Auto</option>100 <option value="light">Light</option>101 <option value="dark">Dark</option>102 </select>103</label>104 <div>105 <h3><a href="../contents.html">Table of Contents</a></h3>106 <ul>107<li><a class="reference internal" href="#"><code class="xref py py-mod docutils literal notranslate"><span class="pre">contextlib</span></code> — Utilities for <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code>-statement contexts</a><ul>108<li><a class="reference internal" href="#utilities">Utilities</a></li>109<li><a class="reference internal" href="#examples-and-recipes">Examples and Recipes</a><ul>110<li><a class="reference internal" href="#supporting-a-variable-number-of-context-managers">Supporting a variable number of context managers</a></li>111<li><a class="reference internal" href="#catching-exceptions-from-enter-methods">Catching exceptions from <code class="docutils literal notranslate"><span class="pre">__enter__</span></code> methods</a></li>112<li><a class="reference internal" href="#cleaning-up-in-an-enter-implementation">Cleaning up in an <code class="docutils literal notranslate"><span class="pre">__enter__</span></code> implementation</a></li>113<li><a class="reference internal" href="#replacing-any-use-of-try-finally-and-flag-variables">Replacing any use of <code class="docutils literal notranslate"><span class="pre">try-finally</span></code> and flag variables</a></li>114<li><a class="reference internal" href="#using-a-context-manager-as-a-function-decorator">Using a context manager as a function decorator</a></li>115</ul>116</li>117<li><a class="reference internal" href="#single-use-reusable-and-reentrant-context-managers">Single use, reusable and reentrant context managers</a><ul>118<li><a class="reference internal" href="#reentrant-context-managers">Reentrant context managers</a></li>119<li><a class="reference internal" href="#reusable-context-managers">Reusable context managers</a></li>120</ul>121</li>122</ul>123</li>124</ul>125 126 </div>127 <div>128 <h4>Previous topic</h4>129 <p class="topless"><a href="dataclasses.html"130 title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">dataclasses</span></code> — Data Classes</a></p>131 </div>132 <div>133 <h4>Next topic</h4>134 <p class="topless"><a href="abc.html"135 title="next chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">abc</span></code> — Abstract Base Classes</a></p>136 </div>137 <script>138 document.addEventListener('DOMContentLoaded', () => {139 const title = document.querySelector('meta[property="og:title"]').content;140 const elements = document.querySelectorAll('.improvepage');141 const pageurl = window.location.href.split('?')[0];142 elements.forEach(element => {143 const url = new URL(element.href.split('?')[0].replace("-nojs", ""));144 url.searchParams.set('pagetitle', title);145 url.searchParams.set('pageurl', pageurl);146 url.searchParams.set('pagesource', "library/contextlib.rst");147 element.href = url.toString();148 });149 });150 </script>151 <div role="note" aria-label="source link">152 <h3>This page</h3>153 <ul class="this-page-menu">154 <li><a href="../bugs.html">Report a bug</a></li>155 <li><a class="improvepage" href="../improve-page-nojs.html">Improve this page</a></li>156 <li>157 <a href="https://github.com/python/cpython/blob/main/Doc/library/contextlib.rst?plain=1"158 rel="nofollow">Show source159 </a>160 </li>161 162 </ul>163 </div>164 </nav>165 </div>166</div>167 168 169 <div class="related" role="navigation" aria-label="Related">170 <h3>Navigation</h3>171 <ul>172 <li class="right" style="margin-right: 10px">173 <a href="../genindex.html" title="General Index"174 accesskey="I">index</a></li>175 <li class="right" >176 <a href="../py-modindex.html" title="Python Module Index"177 >modules</a> |</li>178 <li class="right" >179 <a href="abc.html" title="abc — Abstract Base Classes"180 accesskey="N">next</a> |</li>181 <li class="right" >182 <a href="dataclasses.html" title="dataclasses — Data Classes"183 accesskey="P">previous</a> |</li>184 185 <li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"></li>186 <li><a href="https://www.python.org/">Python</a> »</li>187 <li class="switchers">188 <div class="language_switcher_placeholder"></div>189 <div class="version_switcher_placeholder"></div>190 </li>191 <li>192 193 </li>194 <li id="cpython-language-and-version">195 <a href="../index.html">3.15.0a6 Documentation</a> »196 </li>197 198 <li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>199 <li class="nav-item nav-item-2"><a href="python.html" accesskey="U">Python Runtime Services</a> »</li>200 <li class="nav-item nav-item-this"><a href=""><code class="xref py py-mod docutils literal notranslate"><span class="pre">contextlib</span></code> — Utilities for <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code>-statement contexts</a></li>201 <li class="right">202 203 204 <div class="inline-search" role="search">205 <form class="inline-search" action="../search.html" method="get">206 <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box">207 <input type="submit" value="Go">208 </form>209 </div>210 |211 </li>212 <li class="right">213<label class="theme-selector-label">214 Theme215 <select class="theme-selector" oninput="activateTheme(this.value)">216 <option value="auto" selected>Auto</option>217 <option value="light">Light</option>218 <option value="dark">Dark</option>219 </select>220</label> |</li>221 222 </ul>223 </div> 224 225 <div class="document">226 <div class="documentwrapper">227 <div class="bodywrapper">228 <div class="body" role="main">229 230 <section id="module-contextlib">231<span id="contextlib-utilities-for-with-statement-contexts"></span><h1><code class="xref py py-mod docutils literal notranslate"><span class="pre">contextlib</span></code> — Utilities for <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code>-statement contexts<a class="headerlink" href="#module-contextlib" title="Link to this heading">¶</a></h1>232<p><strong>Source code:</strong> <a class="extlink-source reference external" href="https://github.com/python/cpython/tree/main/Lib/contextlib.py">Lib/contextlib.py</a></p>233<hr class="docutils" />234<p>This module provides utilities for common tasks involving the <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a>235statement. For more information see also <a class="reference internal" href="stdtypes.html#typecontextmanager"><span class="std std-ref">Context Manager Types</span></a> and236<a class="reference internal" href="../reference/datamodel.html#context-managers"><span class="std std-ref">With Statement Context Managers</span></a>.</p>237<section id="utilities">238<h2>Utilities<a class="headerlink" href="#utilities" title="Link to this heading">¶</a></h2>239<p>Functions and classes provided:</p>240<dl class="py class">241<dt class="sig sig-object py" id="contextlib.AbstractContextManager">242<em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">AbstractContextManager</span></span><a class="headerlink" href="#contextlib.AbstractContextManager" title="Link to this definition">¶</a></dt>243<dd><p>An <a class="reference internal" href="../glossary.html#term-abstract-base-class"><span class="xref std std-term">abstract base class</span></a> for classes that implement244<a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> and <a class="reference internal" href="../reference/datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a>. A default245implementation for <code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code> is provided which returns246<code class="docutils literal notranslate"><span class="pre">self</span></code> while <code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code> is an abstract method which by default247returns <code class="docutils literal notranslate"><span class="pre">None</span></code>. See also the definition of <a class="reference internal" href="stdtypes.html#typecontextmanager"><span class="std std-ref">Context Manager Types</span></a>.</p>248<div class="versionadded">249<p><span class="versionmodified added">Added in version 3.6.</span></p>250</div>251</dd></dl>252 253<dl class="py class">254<dt class="sig sig-object py" id="contextlib.AbstractAsyncContextManager">255<em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">AbstractAsyncContextManager</span></span><a class="headerlink" href="#contextlib.AbstractAsyncContextManager" title="Link to this definition">¶</a></dt>256<dd><p>An <a class="reference internal" href="../glossary.html#term-abstract-base-class"><span class="xref std std-term">abstract base class</span></a> for classes that implement257<a class="reference internal" href="../reference/datamodel.html#object.__aenter__" title="object.__aenter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__aenter__()</span></code></a> and <a class="reference internal" href="../reference/datamodel.html#object.__aexit__" title="object.__aexit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__aexit__()</span></code></a>. A default258implementation for <code class="xref py py-meth docutils literal notranslate"><span class="pre">__aenter__()</span></code> is provided which returns259<code class="docutils literal notranslate"><span class="pre">self</span></code> while <code class="xref py py-meth docutils literal notranslate"><span class="pre">__aexit__()</span></code> is an abstract method which by default260returns <code class="docutils literal notranslate"><span class="pre">None</span></code>. See also the definition of261<a class="reference internal" href="../reference/datamodel.html#async-context-managers"><span class="std std-ref">Asynchronous Context Managers</span></a>.</p>262<div class="versionadded">263<p><span class="versionmodified added">Added in version 3.7.</span></p>264</div>265</dd></dl>266 267<dl class="py function">268<dt class="sig sig-object py" id="contextlib.contextmanager">269<span class="sig-prename descclassname"><span class="pre">@</span></span><span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">contextmanager</span></span><a class="headerlink" href="#contextlib.contextmanager" title="Link to this definition">¶</a></dt>270<dd><p>This function is a <a class="reference internal" href="../glossary.html#term-decorator"><span class="xref std std-term">decorator</span></a> that can be used to define a factory271function for <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement context managers, without needing to272create a class or separate <a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> and <a class="reference internal" href="../reference/datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> methods.</p>273<p>While many objects natively support use in with statements, sometimes a274resource needs to be managed that isn’t a context manager in its own right,275and doesn’t implement a <code class="docutils literal notranslate"><span class="pre">close()</span></code> method for use with <code class="docutils literal notranslate"><span class="pre">contextlib.closing</span></code>.</p>276<p>An abstract example would be the following to ensure correct resource277management:</p>278<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">contextmanager</span>279 280<span class="nd">@contextmanager</span>281<span class="k">def</span><span class="w"> </span><span class="nf">managed_resource</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>282 <span class="c1"># Code to acquire resource, e.g.:</span>283 <span class="n">resource</span> <span class="o">=</span> <span class="n">acquire_resource</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">)</span>284 <span class="k">try</span><span class="p">:</span>285 <span class="k">yield</span> <span class="n">resource</span>286 <span class="k">finally</span><span class="p">:</span>287 <span class="c1"># Code to release resource, e.g.:</span>288 <span class="n">release_resource</span><span class="p">(</span><span class="n">resource</span><span class="p">)</span>289</pre></div>290</div>291<p>The function can then be used like this:</p>292<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">with</span> <span class="n">managed_resource</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mi">3600</span><span class="p">)</span> <span class="k">as</span> <span class="n">resource</span><span class="p">:</span>293<span class="gp">... </span> <span class="c1"># Resource is released at the end of this block,</span>294<span class="gp">... </span> <span class="c1"># even if code in the block raises an exception</span>295</pre></div>296</div>297<p>The function being decorated must return a <a class="reference internal" href="../glossary.html#term-generator"><span class="xref std std-term">generator</span></a>-iterator when298called. This iterator must yield exactly one value, which will be bound to299the targets in the <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement’s <code class="xref std std-keyword docutils literal notranslate"><span class="pre">as</span></code> clause, if any.</p>300<p>At the point where the generator yields, the block nested in the <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a>301statement is executed. The generator is then resumed after the block is exited.302If an unhandled exception occurs in the block, it is reraised inside the303generator at the point where the yield occurred. Thus, you can use a304<a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a>…<a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a>…<a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> statement to trap305the error (if any), or ensure that some cleanup takes place. If an exception is306trapped merely in order to log it or to perform some action (rather than to307suppress it entirely), the generator must reraise that exception. Otherwise the308generator context manager will indicate to the <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement that309the exception has been handled, and execution will resume with the statement310immediately following the <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement.</p>311<p><code class="xref py py-func docutils literal notranslate"><span class="pre">contextmanager()</span></code> uses <a class="reference internal" href="#contextlib.ContextDecorator" title="contextlib.ContextDecorator"><code class="xref py py-class docutils literal notranslate"><span class="pre">ContextDecorator</span></code></a> so the context managers312it creates can be used as decorators as well as in <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statements.313When used as a decorator, a new generator instance is implicitly created on314each function call (this allows the otherwise “one-shot” context managers315created by <code class="xref py py-func docutils literal notranslate"><span class="pre">contextmanager()</span></code> to meet the requirement that context316managers support multiple invocations in order to be used as decorators).</p>317<div class="versionchanged">318<p><span class="versionmodified changed">Changed in version 3.2: </span>Use of <a class="reference internal" href="#contextlib.ContextDecorator" title="contextlib.ContextDecorator"><code class="xref py py-class docutils literal notranslate"><span class="pre">ContextDecorator</span></code></a>.</p>319</div>320</dd></dl>321 322<dl class="py function">323<dt class="sig sig-object py" id="contextlib.asynccontextmanager">324<span class="sig-prename descclassname"><span class="pre">@</span></span><span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">asynccontextmanager</span></span><a class="headerlink" href="#contextlib.asynccontextmanager" title="Link to this definition">¶</a></dt>325<dd><p>Similar to <a class="reference internal" href="#contextlib.contextmanager" title="contextlib.contextmanager"><code class="xref py py-func docutils literal notranslate"><span class="pre">contextmanager()</span></code></a>, but creates an326<a class="reference internal" href="../reference/datamodel.html#async-context-managers"><span class="std std-ref">asynchronous context manager</span></a>.</p>327<p>This function is a <a class="reference internal" href="../glossary.html#term-decorator"><span class="xref std std-term">decorator</span></a> that can be used to define a factory328function for <a class="reference internal" href="../reference/compound_stmts.html#async-with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">with</span></code></a> statement asynchronous context managers,329without needing to create a class or separate <a class="reference internal" href="../reference/datamodel.html#object.__aenter__" title="object.__aenter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__aenter__()</span></code></a> and330<a class="reference internal" href="../reference/datamodel.html#object.__aexit__" title="object.__aexit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__aexit__()</span></code></a> methods. It must be applied to an <a class="reference internal" href="../glossary.html#term-asynchronous-generator"><span class="xref std std-term">asynchronous331generator</span></a> function.</p>332<p>A simple example:</p>333<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">asynccontextmanager</span>334 335<span class="nd">@asynccontextmanager</span>336<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_connection</span><span class="p">():</span>337 <span class="n">conn</span> <span class="o">=</span> <span class="k">await</span> <span class="n">acquire_db_connection</span><span class="p">()</span>338 <span class="k">try</span><span class="p">:</span>339 <span class="k">yield</span> <span class="n">conn</span>340 <span class="k">finally</span><span class="p">:</span>341 <span class="k">await</span> <span class="n">release_db_connection</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span>342 343<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_all_users</span><span class="p">():</span>344 <span class="k">async</span> <span class="k">with</span> <span class="n">get_connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>345 <span class="k">return</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s1">'SELECT ...'</span><span class="p">)</span>346</pre></div>347</div>348<div class="versionadded">349<p><span class="versionmodified added">Added in version 3.7.</span></p>350</div>351<p>Context managers defined with <code class="xref py py-func docutils literal notranslate"><span class="pre">asynccontextmanager()</span></code> can be used352either as decorators or with <a class="reference internal" href="../reference/compound_stmts.html#async-with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">with</span></code></a> statements:</p>353<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">time</span>354<span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">asynccontextmanager</span>355 356<span class="nd">@asynccontextmanager</span>357<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">timeit</span><span class="p">():</span>358 <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">monotonic</span><span class="p">()</span>359 <span class="k">try</span><span class="p">:</span>360 <span class="k">yield</span>361 <span class="k">finally</span><span class="p">:</span>362 <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'it took </span><span class="si">{</span><span class="n">time</span><span class="o">.</span><span class="n">monotonic</span><span class="p">()</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">now</span><span class="si">}</span><span class="s1">s to run'</span><span class="p">)</span>363 364<span class="nd">@timeit</span><span class="p">()</span>365<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">main</span><span class="p">():</span>366 <span class="c1"># ... async code ...</span>367</pre></div>368</div>369<p>When used as a decorator, a new generator instance is implicitly created on370each function call. This allows the otherwise “one-shot” context managers371created by <code class="xref py py-func docutils literal notranslate"><span class="pre">asynccontextmanager()</span></code> to meet the requirement that context372managers support multiple invocations in order to be used as decorators.</p>373<div class="versionchanged">374<p><span class="versionmodified changed">Changed in version 3.10: </span>Async context managers created with <code class="xref py py-func docutils literal notranslate"><span class="pre">asynccontextmanager()</span></code> can375be used as decorators.</p>376</div>377</dd></dl>378 379<dl class="py function">380<dt class="sig sig-object py" id="contextlib.closing">381<span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">closing</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">thing</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.closing" title="Link to this definition">¶</a></dt>382<dd><p>Return a context manager that closes <em>thing</em> upon completion of the block. This383is basically equivalent to:</p>384<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">contextmanager</span>385 386<span class="nd">@contextmanager</span>387<span class="k">def</span><span class="w"> </span><span class="nf">closing</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>388 <span class="k">try</span><span class="p">:</span>389 <span class="k">yield</span> <span class="n">thing</span>390 <span class="k">finally</span><span class="p">:</span>391 <span class="n">thing</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>392</pre></div>393</div>394<p>And lets you write code like this:</p>395<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">closing</span>396<span class="kn">from</span><span class="w"> </span><span class="nn">urllib.request</span><span class="w"> </span><span class="kn">import</span> <span class="n">urlopen</span>397 398<span class="k">with</span> <span class="n">closing</span><span class="p">(</span><span class="n">urlopen</span><span class="p">(</span><span class="s1">'https://www.python.org'</span><span class="p">))</span> <span class="k">as</span> <span class="n">page</span><span class="p">:</span>399 <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">page</span><span class="p">:</span>400 <span class="nb">print</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>401</pre></div>402</div>403<p>without needing to explicitly close <code class="docutils literal notranslate"><span class="pre">page</span></code>. Even if an error occurs,404<code class="docutils literal notranslate"><span class="pre">page.close()</span></code> will be called when the <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> block is exited.</p>405<div class="admonition note">406<p class="admonition-title">Note</p>407<p>Most types managing resources support the <a class="reference internal" href="../glossary.html#term-context-manager"><span class="xref std std-term">context manager</span></a> protocol,408which closes <em>thing</em> on leaving the <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement.409As such, <code class="xref py py-func docutils literal notranslate"><span class="pre">closing()</span></code> is most useful for third party types that don’t410support context managers.411This example is purely for illustration purposes,412as <a class="reference internal" href="urllib.request.html#urllib.request.urlopen" title="urllib.request.urlopen"><code class="xref py py-func docutils literal notranslate"><span class="pre">urlopen()</span></code></a> would normally be used in a context manager.</p>413</div>414</dd></dl>415 416<dl class="py function">417<dt class="sig sig-object py" id="contextlib.aclosing">418<span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">aclosing</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">thing</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.aclosing" title="Link to this definition">¶</a></dt>419<dd><p>Return an async context manager that calls the <code class="docutils literal notranslate"><span class="pre">aclose()</span></code> method of <em>thing</em>420upon completion of the block. This is basically equivalent to:</p>421<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">asynccontextmanager</span>422 423<span class="nd">@asynccontextmanager</span>424<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">aclosing</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>425 <span class="k">try</span><span class="p">:</span>426 <span class="k">yield</span> <span class="n">thing</span>427 <span class="k">finally</span><span class="p">:</span>428 <span class="k">await</span> <span class="n">thing</span><span class="o">.</span><span class="n">aclose</span><span class="p">()</span>429</pre></div>430</div>431<p>Significantly, <code class="docutils literal notranslate"><span class="pre">aclosing()</span></code> supports deterministic cleanup of async432generators when they happen to exit early by <a class="reference internal" href="../reference/simple_stmts.html#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a> or an433exception. For example:</p>434<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">aclosing</span>435 436<span class="k">async</span> <span class="k">with</span> <span class="n">aclosing</span><span class="p">(</span><span class="n">my_generator</span><span class="p">())</span> <span class="k">as</span> <span class="n">values</span><span class="p">:</span>437 <span class="k">async</span> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span>438 <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="mi">42</span><span class="p">:</span>439 <span class="k">break</span>440</pre></div>441</div>442<p>This pattern ensures that the generator’s async exit code is executed in443the same context as its iterations (so that exceptions and context444variables work as expected, and the exit code isn’t run after the445lifetime of some task it depends on).</p>446<div class="versionadded">447<p><span class="versionmodified added">Added in version 3.10.</span></p>448</div>449</dd></dl>450 451<dl class="py function" id="simplifying-support-for-single-optional-context-managers">452<dt class="sig sig-object py" id="contextlib.nullcontext">453<span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">nullcontext</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">enter_result</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.nullcontext" title="Link to this definition">¶</a></dt>454<dd><p>Return a context manager that returns <em>enter_result</em> from <a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a>, but455otherwise does nothing. It is intended to be used as a stand-in for an456optional context manager, for example:</p>457<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">myfunction</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">ignore_exceptions</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>458 <span class="k">if</span> <span class="n">ignore_exceptions</span><span class="p">:</span>459 <span class="c1"># Use suppress to ignore all exceptions.</span>460 <span class="n">cm</span> <span class="o">=</span> <span class="n">contextlib</span><span class="o">.</span><span class="n">suppress</span><span class="p">(</span><span class="ne">Exception</span><span class="p">)</span>461 <span class="k">else</span><span class="p">:</span>462 <span class="c1"># Do not ignore any exceptions, cm has no effect.</span>463 <span class="n">cm</span> <span class="o">=</span> <span class="n">contextlib</span><span class="o">.</span><span class="n">nullcontext</span><span class="p">()</span>464 <span class="k">with</span> <span class="n">cm</span><span class="p">:</span>465 <span class="c1"># Do something</span>466</pre></div>467</div>468<p>An example using <em>enter_result</em>:</p>469<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">process_file</span><span class="p">(</span><span class="n">file_or_path</span><span class="p">):</span>470 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file_or_path</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>471 <span class="c1"># If string, open file</span>472 <span class="n">cm</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">file_or_path</span><span class="p">)</span>473 <span class="k">else</span><span class="p">:</span>474 <span class="c1"># Caller is responsible for closing file</span>475 <span class="n">cm</span> <span class="o">=</span> <span class="n">nullcontext</span><span class="p">(</span><span class="n">file_or_path</span><span class="p">)</span>476 477 <span class="k">with</span> <span class="n">cm</span> <span class="k">as</span> <span class="n">file</span><span class="p">:</span>478 <span class="c1"># Perform processing on the file</span>479</pre></div>480</div>481<p>It can also be used as a stand-in for482<a class="reference internal" href="../reference/datamodel.html#async-context-managers"><span class="std std-ref">asynchronous context managers</span></a>:</p>483<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">send_http</span><span class="p">(</span><span class="n">session</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>484 <span class="k">if</span> <span class="ow">not</span> <span class="n">session</span><span class="p">:</span>485 <span class="c1"># If no http session, create it with aiohttp</span>486 <span class="n">cm</span> <span class="o">=</span> <span class="n">aiohttp</span><span class="o">.</span><span class="n">ClientSession</span><span class="p">()</span>487 <span class="k">else</span><span class="p">:</span>488 <span class="c1"># Caller is responsible for closing the session</span>489 <span class="n">cm</span> <span class="o">=</span> <span class="n">nullcontext</span><span class="p">(</span><span class="n">session</span><span class="p">)</span>490 491 <span class="k">async</span> <span class="k">with</span> <span class="n">cm</span> <span class="k">as</span> <span class="n">session</span><span class="p">:</span>492 <span class="c1"># Send http requests with session</span>493</pre></div>494</div>495<div class="versionadded">496<p><span class="versionmodified added">Added in version 3.7.</span></p>497</div>498<div class="versionchanged">499<p><span class="versionmodified changed">Changed in version 3.10: </span><a class="reference internal" href="../glossary.html#term-asynchronous-context-manager"><span class="xref std std-term">asynchronous context manager</span></a> support was added.</p>500</div>501</dd></dl>502 503<dl class="py function">504<dt class="sig sig-object py" id="contextlib.suppress">505<span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">suppress</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">exceptions</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.suppress" title="Link to this definition">¶</a></dt>506<dd><p>Return a context manager that suppresses any of the specified exceptions507if they occur in the body of a <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement and then508resumes execution with the first statement following the end of the509<code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement.</p>510<p>As with any other mechanism that completely suppresses exceptions, this511context manager should be used only to cover very specific errors where512silently continuing with program execution is known to be the right513thing to do.</p>514<p>For example:</p>515<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">suppress</span>516 517<span class="k">with</span> <span class="n">suppress</span><span class="p">(</span><span class="ne">FileNotFoundError</span><span class="p">):</span>518 <span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s1">'somefile.tmp'</span><span class="p">)</span>519 520<span class="k">with</span> <span class="n">suppress</span><span class="p">(</span><span class="ne">FileNotFoundError</span><span class="p">):</span>521 <span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s1">'someotherfile.tmp'</span><span class="p">)</span>522</pre></div>523</div>524<p>This code is equivalent to:</p>525<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>526 <span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s1">'somefile.tmp'</span><span class="p">)</span>527<span class="k">except</span> <span class="ne">FileNotFoundError</span><span class="p">:</span>528 <span class="k">pass</span>529 530<span class="k">try</span><span class="p">:</span>531 <span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s1">'someotherfile.tmp'</span><span class="p">)</span>532<span class="k">except</span> <span class="ne">FileNotFoundError</span><span class="p">:</span>533 <span class="k">pass</span>534</pre></div>535</div>536<p>This context manager is <a class="reference internal" href="#reentrant-cms"><span class="std std-ref">reentrant</span></a>.</p>537<p>If the code within the <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> block raises a538<a class="reference internal" href="exceptions.html#BaseExceptionGroup" title="BaseExceptionGroup"><code class="xref py py-exc docutils literal notranslate"><span class="pre">BaseExceptionGroup</span></code></a>, suppressed exceptions are removed from the539group. Any exceptions of the group which are not suppressed are re-raised in540a new group which is created using the original group’s <a class="reference internal" href="exceptions.html#BaseExceptionGroup.derive" title="BaseExceptionGroup.derive"><code class="xref py py-meth docutils literal notranslate"><span class="pre">derive()</span></code></a>541method.</p>542<div class="versionadded">543<p><span class="versionmodified added">Added in version 3.4.</span></p>544</div>545<div class="versionchanged">546<p><span class="versionmodified changed">Changed in version 3.12: </span><code class="docutils literal notranslate"><span class="pre">suppress</span></code> now supports suppressing exceptions raised as547part of a <a class="reference internal" href="exceptions.html#BaseExceptionGroup" title="BaseExceptionGroup"><code class="xref py py-exc docutils literal notranslate"><span class="pre">BaseExceptionGroup</span></code></a>.</p>548</div>549</dd></dl>550 551<dl class="py function">552<dt class="sig sig-object py" id="contextlib.redirect_stdout">553<span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">redirect_stdout</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">new_target</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.redirect_stdout" title="Link to this definition">¶</a></dt>554<dd><p>Context manager for temporarily redirecting <a class="reference internal" href="sys.html#sys.stdout" title="sys.stdout"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stdout</span></code></a> to555another <a class="reference internal" href="../glossary.html#term-file-object"><span class="xref std std-term">file object</span></a>.</p>556<p>This tool adds flexibility to existing functions or classes whose output557is hardwired to <a class="reference internal" href="sys.html#sys.stdout" title="sys.stdout"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stdout</span></code></a>.</p>558<p>For example, the output of <a class="reference internal" href="functions.html#help" title="help"><code class="xref py py-func docutils literal notranslate"><span class="pre">help()</span></code></a> normally is sent to <em>sys.stdout</em>.559You can capture that output in a string by redirecting the output to an560<a class="reference internal" href="io.html#io.StringIO" title="io.StringIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">io.StringIO</span></code></a> object. The replacement stream is returned from the561<a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> method and so is available as the target of the562<a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement:</p>563<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">redirect_stdout</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">StringIO</span><span class="p">())</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>564 <span class="n">help</span><span class="p">(</span><span class="nb">pow</span><span class="p">)</span>565<span class="n">s</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>566</pre></div>567</div>568<p>To send the output of <a class="reference internal" href="functions.html#help" title="help"><code class="xref py py-func docutils literal notranslate"><span class="pre">help()</span></code></a> to a file on disk, redirect the output569to a regular file:</p>570<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'help.txt'</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>571 <span class="k">with</span> <span class="n">redirect_stdout</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>572 <span class="n">help</span><span class="p">(</span><span class="nb">pow</span><span class="p">)</span>573</pre></div>574</div>575<p>To send the output of <a class="reference internal" href="functions.html#help" title="help"><code class="xref py py-func docutils literal notranslate"><span class="pre">help()</span></code></a> to <em>sys.stderr</em>:</p>576<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">redirect_stdout</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">):</span>577 <span class="n">help</span><span class="p">(</span><span class="nb">pow</span><span class="p">)</span>578</pre></div>579</div>580<p>Note that the global side effect on <a class="reference internal" href="sys.html#sys.stdout" title="sys.stdout"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stdout</span></code></a> means that this581context manager is not suitable for use in library code and most threaded582applications. It also has no effect on the output of subprocesses.583However, it is still a useful approach for many utility scripts.</p>584<p>This context manager is <a class="reference internal" href="#reentrant-cms"><span class="std std-ref">reentrant</span></a>.</p>585<div class="versionadded">586<p><span class="versionmodified added">Added in version 3.4.</span></p>587</div>588</dd></dl>589 590<dl class="py function">591<dt class="sig sig-object py" id="contextlib.redirect_stderr">592<span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">redirect_stderr</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">new_target</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.redirect_stderr" title="Link to this definition">¶</a></dt>593<dd><p>Similar to <a class="reference internal" href="#contextlib.redirect_stdout" title="contextlib.redirect_stdout"><code class="xref py py-func docutils literal notranslate"><span class="pre">redirect_stdout()</span></code></a> but redirecting the global594<a class="reference internal" href="sys.html#sys.stderr" title="sys.stderr"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stderr</span></code></a> to another <a class="reference internal" href="../glossary.html#term-file-object"><span class="xref std std-term">file object</span></a>.</p>595<p>This context manager is <a class="reference internal" href="#reentrant-cms"><span class="std std-ref">reentrant</span></a>.</p>596<div class="versionadded">597<p><span class="versionmodified added">Added in version 3.5.</span></p>598</div>599</dd></dl>600 601<dl class="py function">602<dt class="sig sig-object py" id="contextlib.chdir">603<span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">chdir</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">path</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.chdir" title="Link to this definition">¶</a></dt>604<dd><p>Non parallel-safe context manager to change the current working directory.605As this changes a global state, the working directory, it is not suitable606for use in most threaded or async contexts. It is also not suitable for most607non-linear code execution, like generators, where the program execution is608temporarily relinquished – unless explicitly desired, you should not yield609when this context manager is active.</p>610<p>This is a simple wrapper around <a class="reference internal" href="os.html#os.chdir" title="os.chdir"><code class="xref py py-func docutils literal notranslate"><span class="pre">chdir()</span></code></a>, it changes the current611working directory upon entering and restores the old one on exit.</p>612<p>This context manager is <a class="reference internal" href="#reentrant-cms"><span class="std std-ref">reentrant</span></a>.</p>613<div class="versionadded">614<p><span class="versionmodified added">Added in version 3.11.</span></p>615</div>616</dd></dl>617 618<dl class="py class">619<dt class="sig sig-object py" id="contextlib.ContextDecorator">620<em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">ContextDecorator</span></span><a class="headerlink" href="#contextlib.ContextDecorator" title="Link to this definition">¶</a></dt>621<dd><p>A base class that enables a context manager to also be used as a decorator.</p>622<p>Context managers inheriting from <code class="docutils literal notranslate"><span class="pre">ContextDecorator</span></code> have to implement623<a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> and <a class="reference internal" href="../reference/datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> as normal.624<code class="docutils literal notranslate"><span class="pre">__exit__</span></code> retains its optional625exception handling even when used as a decorator.</p>626<p><code class="docutils literal notranslate"><span class="pre">ContextDecorator</span></code> is used by <a class="reference internal" href="#contextlib.contextmanager" title="contextlib.contextmanager"><code class="xref py py-func docutils literal notranslate"><span class="pre">contextmanager()</span></code></a>, so you get this627functionality automatically.</p>628<p>Example of <code class="docutils literal notranslate"><span class="pre">ContextDecorator</span></code>:</p>629<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">ContextDecorator</span>630 631<span class="k">class</span><span class="w"> </span><span class="nc">mycontext</span><span class="p">(</span><span class="n">ContextDecorator</span><span class="p">):</span>632 <span class="k">def</span><span class="w"> </span><span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>633 <span class="nb">print</span><span class="p">(</span><span class="s1">'Starting'</span><span class="p">)</span>634 <span class="k">return</span> <span class="bp">self</span>635 636 <span class="k">def</span><span class="w"> </span><span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">exc</span><span class="p">):</span>637 <span class="nb">print</span><span class="p">(</span><span class="s1">'Finishing'</span><span class="p">)</span>638 <span class="k">return</span> <span class="kc">False</span>639</pre></div>640</div>641<p>The class can then be used like this:</p>642<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nd">@mycontext</span><span class="p">()</span>643<span class="gp">... </span><span class="k">def</span><span class="w"> </span><span class="nf">function</span><span class="p">():</span>644<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s1">'The bit in the middle'</span><span class="p">)</span>645<span class="gp">...</span>646<span class="gp">>>> </span><span class="n">function</span><span class="p">()</span>647<span class="go">Starting</span>648<span class="go">The bit in the middle</span>649<span class="go">Finishing</span>650 651<span class="gp">>>> </span><span class="k">with</span> <span class="n">mycontext</span><span class="p">():</span>652<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s1">'The bit in the middle'</span><span class="p">)</span>653<span class="gp">...</span>654<span class="go">Starting</span>655<span class="go">The bit in the middle</span>656<span class="go">Finishing</span>657</pre></div>658</div>659<p>This change is just syntactic sugar for any construct of the following form:</p>660<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">f</span><span class="p">():</span>661 <span class="k">with</span> <span class="n">cm</span><span class="p">():</span>662 <span class="c1"># Do stuff</span>663</pre></div>664</div>665<p><code class="docutils literal notranslate"><span class="pre">ContextDecorator</span></code> lets you instead write:</p>666<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@cm</span><span class="p">()</span>667<span class="k">def</span><span class="w"> </span><span class="nf">f</span><span class="p">():</span>668 <span class="c1"># Do stuff</span>669</pre></div>670</div>671<p>It makes it clear that the <code class="docutils literal notranslate"><span class="pre">cm</span></code> applies to the whole function, rather than672just a piece of it (and saving an indentation level is nice, too).</p>673<p>Existing context managers that already have a base class can be extended by674using <code class="docutils literal notranslate"><span class="pre">ContextDecorator</span></code> as a mixin class:</p>675<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">ContextDecorator</span>676 677<span class="k">class</span><span class="w"> </span><span class="nc">mycontext</span><span class="p">(</span><span class="n">ContextBaseClass</span><span class="p">,</span> <span class="n">ContextDecorator</span><span class="p">):</span>678 <span class="k">def</span><span class="w"> </span><span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>679 <span class="k">return</span> <span class="bp">self</span>680 681 <span class="k">def</span><span class="w"> </span><span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">exc</span><span class="p">):</span>682 <span class="k">return</span> <span class="kc">False</span>683</pre></div>684</div>685<div class="admonition note">686<p class="admonition-title">Note</p>687<p>As the decorated function must be able to be called multiple times, the688underlying context manager must support use in multiple <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a>689statements. If this is not the case, then the original construct with the690explicit <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement inside the function should be used.</p>691</div>692<div class="versionadded">693<p><span class="versionmodified added">Added in version 3.2.</span></p>694</div>695</dd></dl>696 697<dl class="py class">698<dt class="sig sig-object py" id="contextlib.AsyncContextDecorator">699<em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">AsyncContextDecorator</span></span><a class="headerlink" href="#contextlib.AsyncContextDecorator" title="Link to this definition">¶</a></dt>700<dd><p>Similar to <a class="reference internal" href="#contextlib.ContextDecorator" title="contextlib.ContextDecorator"><code class="xref py py-class docutils literal notranslate"><span class="pre">ContextDecorator</span></code></a> but only for asynchronous functions.</p>701<p>Example of <code class="docutils literal notranslate"><span class="pre">AsyncContextDecorator</span></code>:</p>702<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">asyncio</span><span class="w"> </span><span class="kn">import</span> <span class="n">run</span>703<span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">AsyncContextDecorator</span>704 705<span class="k">class</span><span class="w"> </span><span class="nc">mycontext</span><span class="p">(</span><span class="n">AsyncContextDecorator</span><span class="p">):</span>706 <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="fm">__aenter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>707 <span class="nb">print</span><span class="p">(</span><span class="s1">'Starting'</span><span class="p">)</span>708 <span class="k">return</span> <span class="bp">self</span>709 710 <span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="fm">__aexit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">exc</span><span class="p">):</span>711 <span class="nb">print</span><span class="p">(</span><span class="s1">'Finishing'</span><span class="p">)</span>712 <span class="k">return</span> <span class="kc">False</span>713</pre></div>714</div>715<p>The class can then be used like this:</p>716<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nd">@mycontext</span><span class="p">()</span>717<span class="gp">... </span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">function</span><span class="p">():</span>718<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s1">'The bit in the middle'</span><span class="p">)</span>719<span class="gp">...</span>720<span class="gp">>>> </span><span class="n">run</span><span class="p">(</span><span class="n">function</span><span class="p">())</span>721<span class="go">Starting</span>722<span class="go">The bit in the middle</span>723<span class="go">Finishing</span>724 725<span class="gp">>>> </span><span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">function</span><span class="p">():</span>726<span class="gp">... </span> <span class="k">async</span> <span class="k">with</span> <span class="n">mycontext</span><span class="p">():</span>727<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s1">'The bit in the middle'</span><span class="p">)</span>728<span class="gp">...</span>729<span class="gp">>>> </span><span class="n">run</span><span class="p">(</span><span class="n">function</span><span class="p">())</span>730<span class="go">Starting</span>731<span class="go">The bit in the middle</span>732<span class="go">Finishing</span>733</pre></div>734</div>735<div class="versionadded">736<p><span class="versionmodified added">Added in version 3.10.</span></p>737</div>738</dd></dl>739 740<dl class="py class">741<dt class="sig sig-object py" id="contextlib.ExitStack">742<em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">ExitStack</span></span><a class="headerlink" href="#contextlib.ExitStack" title="Link to this definition">¶</a></dt>743<dd><p>A context manager that is designed to make it easy to programmatically744combine other context managers and cleanup functions, especially those745that are optional or otherwise driven by input data.</p>746<p>For example, a set of files may easily be handled in a single with747statement as follows:</p>748<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">ExitStack</span><span class="p">()</span> <span class="k">as</span> <span class="n">stack</span><span class="p">:</span>749 <span class="n">files</span> <span class="o">=</span> <span class="p">[</span><span class="n">stack</span><span class="o">.</span><span class="n">enter_context</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">fname</span><span class="p">))</span> <span class="k">for</span> <span class="n">fname</span> <span class="ow">in</span> <span class="n">filenames</span><span class="p">]</span>750 <span class="c1"># All opened files will automatically be closed at the end of</span>751 <span class="c1"># the with statement, even if attempts to open files later</span>752 <span class="c1"># in the list raise an exception</span>753</pre></div>754</div>755<p>The <a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> method returns the <code class="xref py py-class docutils literal notranslate"><span class="pre">ExitStack</span></code> instance, and756performs no additional operations.</p>757<p>Each instance maintains a stack of registered callbacks that are called in758reverse order when the instance is closed (either explicitly or implicitly759at the end of a <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement). Note that callbacks are <em>not</em>760invoked implicitly when the context stack instance is garbage collected.</p>761<p>This stack model is used so that context managers that acquire their762resources in their <code class="docutils literal notranslate"><span class="pre">__init__</span></code> method (such as file objects) can be763handled correctly.</p>764<p>Since registered callbacks are invoked in the reverse order of765registration, this ends up behaving as if multiple nested <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a>766statements had been used with the registered set of callbacks. This even767extends to exception handling - if an inner callback suppresses or replaces768an exception, then outer callbacks will be passed arguments based on that769updated state.</p>770<p>This is a relatively low level API that takes care of the details of771correctly unwinding the stack of exit callbacks. It provides a suitable772foundation for higher level context managers that manipulate the exit773stack in application specific ways.</p>774<div class="versionadded">775<p><span class="versionmodified added">Added in version 3.3.</span></p>776</div>777<dl class="py method">778<dt class="sig sig-object py" id="contextlib.ExitStack.enter_context">779<span class="sig-name descname"><span class="pre">enter_context</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">cm</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.ExitStack.enter_context" title="Link to this definition">¶</a></dt>780<dd><p>Enters a new context manager and adds its <a class="reference internal" href="../reference/datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> method to781the callback stack. The return value is the result of the context782manager’s own <a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> method.</p>783<p>These context managers may suppress exceptions just as they normally784would if used directly as part of a <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement.</p>785<div class="versionchanged">786<p><span class="versionmodified changed">Changed in version 3.11: </span>Raises <a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> instead of <a class="reference internal" href="exceptions.html#AttributeError" title="AttributeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AttributeError</span></code></a> if <em>cm</em>787is not a context manager.</p>788</div>789<div class="versionchanged">790<p><span class="versionmodified changed">Changed in version 3.15: </span>Added support for arbitrary descriptors <code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code> and791<code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code>.</p>792</div>793</dd></dl>794 795<dl class="py method">796<dt class="sig sig-object py" id="contextlib.ExitStack.push">797<span class="sig-name descname"><span class="pre">push</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">exit</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.ExitStack.push" title="Link to this definition">¶</a></dt>798<dd><p>Adds a context manager’s <a class="reference internal" href="../reference/datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> method to the callback stack.</p>799<p>As <code class="docutils literal notranslate"><span class="pre">__enter__</span></code> is <em>not</em> invoked, this method can be used to cover800part of an <a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> implementation with a context manager’s own801<a class="reference internal" href="../reference/datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> method.</p>802<p>If passed an object that is not a context manager, this method assumes803it is a callback with the same signature as a context manager’s804<a class="reference internal" href="../reference/datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> method and adds it directly to the callback stack.</p>805<p>By returning true values, these callbacks can suppress exceptions the806same way context manager <a class="reference internal" href="../reference/datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> methods can.</p>807<p>The passed in object is returned from the function, allowing this808method to be used as a function decorator.</p>809<div class="versionchanged">810<p><span class="versionmodified changed">Changed in version 3.15: </span>Added support for arbitrary descriptors <code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code>.</p>811</div>812</dd></dl>813 814<dl class="py method">815<dt class="sig sig-object py" id="contextlib.ExitStack.callback">816<span class="sig-name descname"><span class="pre">callback</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">callback</span></span></em>, <em class="sig-param"><span class="positional-only-separator o"><abbr title="Positional-only parameter separator (PEP 570)"><span class="pre">/</span></abbr></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">args</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwds</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.ExitStack.callback" title="Link to this definition">¶</a></dt>817<dd><p>Accepts an arbitrary callback function and arguments and adds it to818the callback stack.</p>819<p>Unlike the other methods, callbacks added this way cannot suppress820exceptions (as they are never passed the exception details).</p>821<p>The passed in callback is returned from the function, allowing this822method to be used as a function decorator.</p>823</dd></dl>824 825<dl class="py method">826<dt class="sig sig-object py" id="contextlib.ExitStack.pop_all">827<span class="sig-name descname"><span class="pre">pop_all</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.ExitStack.pop_all" title="Link to this definition">¶</a></dt>828<dd><p>Transfers the callback stack to a fresh <code class="xref py py-class docutils literal notranslate"><span class="pre">ExitStack</span></code> instance829and returns it. No callbacks are invoked by this operation - instead,830they will now be invoked when the new stack is closed (either831explicitly or implicitly at the end of a <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement).</p>832<p>For example, a group of files can be opened as an “all or nothing”833operation as follows:</p>834<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">ExitStack</span><span class="p">()</span> <span class="k">as</span> <span class="n">stack</span><span class="p">:</span>835 <span class="n">files</span> <span class="o">=</span> <span class="p">[</span><span class="n">stack</span><span class="o">.</span><span class="n">enter_context</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">fname</span><span class="p">))</span> <span class="k">for</span> <span class="n">fname</span> <span class="ow">in</span> <span class="n">filenames</span><span class="p">]</span>836 <span class="c1"># Hold onto the close method, but don't call it yet.</span>837 <span class="n">close_files</span> <span class="o">=</span> <span class="n">stack</span><span class="o">.</span><span class="n">pop_all</span><span class="p">()</span><span class="o">.</span><span class="n">close</span>838 <span class="c1"># If opening any file fails, all previously opened files will be</span>839 <span class="c1"># closed automatically. If all files are opened successfully,</span>840 <span class="c1"># they will remain open even after the with statement ends.</span>841 <span class="c1"># close_files() can then be invoked explicitly to close them all.</span>842</pre></div>843</div>844</dd></dl>845 846<dl class="py method">847<dt class="sig sig-object py" id="contextlib.ExitStack.close">848<span class="sig-name descname"><span class="pre">close</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.ExitStack.close" title="Link to this definition">¶</a></dt>849<dd><p>Immediately unwinds the callback stack, invoking callbacks in the850reverse order of registration. For any context managers and exit851callbacks registered, the arguments passed in will indicate that no852exception occurred.</p>853</dd></dl>854 855</dd></dl>856 857<dl class="py class">858<dt class="sig sig-object py" id="contextlib.AsyncExitStack">859<em class="property"><span class="k"><span class="pre">class</span></span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">contextlib.</span></span><span class="sig-name descname"><span class="pre">AsyncExitStack</span></span><a class="headerlink" href="#contextlib.AsyncExitStack" title="Link to this definition">¶</a></dt>860<dd><p>An <a class="reference internal" href="../reference/datamodel.html#async-context-managers"><span class="std std-ref">asynchronous context manager</span></a>, similar861to <a class="reference internal" href="#contextlib.ExitStack" title="contextlib.ExitStack"><code class="xref py py-class docutils literal notranslate"><span class="pre">ExitStack</span></code></a>, that supports combining both synchronous and862asynchronous context managers, as well as having coroutines for863cleanup logic.</p>864<p>The <a class="reference internal" href="#contextlib.ExitStack.close" title="contextlib.ExitStack.close"><code class="xref py py-meth docutils literal notranslate"><span class="pre">close()</span></code></a> method is not implemented; <a class="reference internal" href="#contextlib.AsyncExitStack.aclose" title="contextlib.AsyncExitStack.aclose"><code class="xref py py-meth docutils literal notranslate"><span class="pre">aclose()</span></code></a> must be used865instead.</p>866<dl class="py method">867<dt class="sig sig-object py" id="contextlib.AsyncExitStack.enter_async_context">868<em class="property"><span class="k"><span class="pre">async</span></span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">enter_async_context</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">cm</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.AsyncExitStack.enter_async_context" title="Link to this definition">¶</a></dt>869<dd><p>Similar to <a class="reference internal" href="#contextlib.ExitStack.enter_context" title="contextlib.ExitStack.enter_context"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ExitStack.enter_context()</span></code></a> but expects an asynchronous context870manager.</p>871<div class="versionchanged">872<p><span class="versionmodified changed">Changed in version 3.11: </span>Raises <a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> instead of <a class="reference internal" href="exceptions.html#AttributeError" title="AttributeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AttributeError</span></code></a> if <em>cm</em>873is not an asynchronous context manager.</p>874</div>875<div class="versionchanged">876<p><span class="versionmodified changed">Changed in version 3.15: </span>Added support for arbitrary descriptors <code class="xref py py-meth docutils literal notranslate"><span class="pre">__aenter__()</span></code> and <code class="xref py py-meth docutils literal notranslate"><span class="pre">__aexit__()</span></code>.</p>877</div>878</dd></dl>879 880<dl class="py method">881<dt class="sig sig-object py" id="contextlib.AsyncExitStack.push_async_exit">882<span class="sig-name descname"><span class="pre">push_async_exit</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">exit</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.AsyncExitStack.push_async_exit" title="Link to this definition">¶</a></dt>883<dd><p>Similar to <a class="reference internal" href="#contextlib.ExitStack.push" title="contextlib.ExitStack.push"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ExitStack.push()</span></code></a> but expects either an asynchronous context manager884or a coroutine function.</p>885<div class="versionchanged">886<p><span class="versionmodified changed">Changed in version 3.15: </span>Added support for arbitrary descriptors <code class="xref py py-meth docutils literal notranslate"><span class="pre">__aexit__()</span></code>.</p>887</div>888</dd></dl>889 890<dl class="py method">891<dt class="sig sig-object py" id="contextlib.AsyncExitStack.push_async_callback">892<span class="sig-name descname"><span class="pre">push_async_callback</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">callback</span></span></em>, <em class="sig-param"><span class="positional-only-separator o"><abbr title="Positional-only parameter separator (PEP 570)"><span class="pre">/</span></abbr></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">args</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwds</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.AsyncExitStack.push_async_callback" title="Link to this definition">¶</a></dt>893<dd><p>Similar to <a class="reference internal" href="#contextlib.ExitStack.callback" title="contextlib.ExitStack.callback"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ExitStack.callback()</span></code></a> but expects a coroutine function.</p>894</dd></dl>895 896<dl class="py method">897<dt class="sig sig-object py" id="contextlib.AsyncExitStack.aclose">898<em class="property"><span class="k"><span class="pre">async</span></span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">aclose</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#contextlib.AsyncExitStack.aclose" title="Link to this definition">¶</a></dt>899<dd><p>Similar to <a class="reference internal" href="#contextlib.ExitStack.close" title="contextlib.ExitStack.close"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ExitStack.close()</span></code></a> but properly handles awaitables.</p>900</dd></dl>901 902<p>Continuing the example for <a class="reference internal" href="#contextlib.asynccontextmanager" title="contextlib.asynccontextmanager"><code class="xref py py-func docutils literal notranslate"><span class="pre">asynccontextmanager()</span></code></a>:</p>903<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">with</span> <span class="n">AsyncExitStack</span><span class="p">()</span> <span class="k">as</span> <span class="n">stack</span><span class="p">:</span>904 <span class="n">connections</span> <span class="o">=</span> <span class="p">[</span><span class="k">await</span> <span class="n">stack</span><span class="o">.</span><span class="n">enter_async_context</span><span class="p">(</span><span class="n">get_connection</span><span class="p">())</span>905 <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">)]</span>906 <span class="c1"># All opened connections will automatically be released at the end of</span>907 <span class="c1"># the async with statement, even if attempts to open a connection</span>908 <span class="c1"># later in the list raise an exception.</span>909</pre></div>910</div>911<div class="versionadded">912<p><span class="versionmodified added">Added in version 3.7.</span></p>913</div>914</dd></dl>915 916</section>917<section id="examples-and-recipes">918<h2>Examples and Recipes<a class="headerlink" href="#examples-and-recipes" title="Link to this heading">¶</a></h2>919<p>This section describes some examples and recipes for making effective use of920the tools provided by <code class="xref py py-mod docutils literal notranslate"><span class="pre">contextlib</span></code>.</p>921<section id="supporting-a-variable-number-of-context-managers">922<h3>Supporting a variable number of context managers<a class="headerlink" href="#supporting-a-variable-number-of-context-managers" title="Link to this heading">¶</a></h3>923<p>The primary use case for <a class="reference internal" href="#contextlib.ExitStack" title="contextlib.ExitStack"><code class="xref py py-class docutils literal notranslate"><span class="pre">ExitStack</span></code></a> is the one given in the class924documentation: supporting a variable number of context managers and other925cleanup operations in a single <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement. The variability926may come from the number of context managers needed being driven by user927input (such as opening a user specified collection of files), or from928some of the context managers being optional:</p>929<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">ExitStack</span><span class="p">()</span> <span class="k">as</span> <span class="n">stack</span><span class="p">:</span>930 <span class="k">for</span> <span class="n">resource</span> <span class="ow">in</span> <span class="n">resources</span><span class="p">:</span>931 <span class="n">stack</span><span class="o">.</span><span class="n">enter_context</span><span class="p">(</span><span class="n">resource</span><span class="p">)</span>932 <span class="k">if</span> <span class="n">need_special_resource</span><span class="p">():</span>933 <span class="n">special</span> <span class="o">=</span> <span class="n">acquire_special_resource</span><span class="p">()</span>934 <span class="n">stack</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">release_special_resource</span><span class="p">,</span> <span class="n">special</span><span class="p">)</span>935 <span class="c1"># Perform operations that use the acquired resources</span>936</pre></div>937</div>938<p>As shown, <a class="reference internal" href="#contextlib.ExitStack" title="contextlib.ExitStack"><code class="xref py py-class docutils literal notranslate"><span class="pre">ExitStack</span></code></a> also makes it quite easy to use <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a>939statements to manage arbitrary resources that don’t natively support the940context management protocol.</p>941</section>942<section id="catching-exceptions-from-enter-methods">943<h3>Catching exceptions from <code class="docutils literal notranslate"><span class="pre">__enter__</span></code> methods<a class="headerlink" href="#catching-exceptions-from-enter-methods" title="Link to this heading">¶</a></h3>944<p>It is occasionally desirable to catch exceptions from an <a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a>945method implementation, <em>without</em> inadvertently catching exceptions from946the <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement body or the context manager’s <a class="reference internal" href="../reference/datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a>947method. By using <a class="reference internal" href="#contextlib.ExitStack" title="contextlib.ExitStack"><code class="xref py py-class docutils literal notranslate"><span class="pre">ExitStack</span></code></a> the steps in the context management948protocol can be separated slightly in order to allow this:</p>949<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">stack</span> <span class="o">=</span> <span class="n">ExitStack</span><span class="p">()</span>950<span class="k">try</span><span class="p">:</span>951 <span class="n">x</span> <span class="o">=</span> <span class="n">stack</span><span class="o">.</span><span class="n">enter_context</span><span class="p">(</span><span class="n">cm</span><span class="p">)</span>952<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>953 <span class="c1"># handle __enter__ exception</span>954<span class="k">else</span><span class="p">:</span>955 <span class="k">with</span> <span class="n">stack</span><span class="p">:</span>956 <span class="c1"># Handle normal case</span>957</pre></div>958</div>959<p>Actually needing to do this is likely to indicate that the underlying API960should be providing a direct resource management interface for use with961<a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a>/<a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a>/<a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> statements, but not962all APIs are well designed in that regard. When a context manager is the963only resource management API provided, then <a class="reference internal" href="#contextlib.ExitStack" title="contextlib.ExitStack"><code class="xref py py-class docutils literal notranslate"><span class="pre">ExitStack</span></code></a> can make it964easier to handle various situations that can’t be handled directly in a965<a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement.</p>966</section>967<section id="cleaning-up-in-an-enter-implementation">968<h3>Cleaning up in an <code class="docutils literal notranslate"><span class="pre">__enter__</span></code> implementation<a class="headerlink" href="#cleaning-up-in-an-enter-implementation" title="Link to this heading">¶</a></h3>969<p>As noted in the documentation of <a class="reference internal" href="#contextlib.ExitStack.push" title="contextlib.ExitStack.push"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ExitStack.push()</span></code></a>, this970method can be useful in cleaning up an already allocated resource if later971steps in the <a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> implementation fail.</p>972<p>Here’s an example of doing this for a context manager that accepts resource973acquisition and release functions, along with an optional validation function,974and maps them to the context management protocol:</p>975<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">contextmanager</span><span class="p">,</span> <span class="n">AbstractContextManager</span><span class="p">,</span> <span class="n">ExitStack</span>976 977<span class="k">class</span><span class="w"> </span><span class="nc">ResourceManager</span><span class="p">(</span><span class="n">AbstractContextManager</span><span class="p">):</span>978 979 <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">acquire_resource</span><span class="p">,</span> <span class="n">release_resource</span><span class="p">,</span> <span class="n">check_resource_ok</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>980 <span class="bp">self</span><span class="o">.</span><span class="n">acquire_resource</span> <span class="o">=</span> <span class="n">acquire_resource</span>981 <span class="bp">self</span><span class="o">.</span><span class="n">release_resource</span> <span class="o">=</span> <span class="n">release_resource</span>982 <span class="k">if</span> <span class="n">check_resource_ok</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>983 <span class="k">def</span><span class="w"> </span><span class="nf">check_resource_ok</span><span class="p">(</span><span class="n">resource</span><span class="p">):</span>984 <span class="k">return</span> <span class="kc">True</span>985 <span class="bp">self</span><span class="o">.</span><span class="n">check_resource_ok</span> <span class="o">=</span> <span class="n">check_resource_ok</span>986 987 <span class="nd">@contextmanager</span>988 <span class="k">def</span><span class="w"> </span><span class="nf">_cleanup_on_error</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>989 <span class="k">with</span> <span class="n">ExitStack</span><span class="p">()</span> <span class="k">as</span> <span class="n">stack</span><span class="p">:</span>990 <span class="n">stack</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>991 <span class="k">yield</span>992 <span class="c1"># The validation check passed and didn't raise an exception</span>993 <span class="c1"># Accordingly, we want to keep the resource, and pass it</span>994 <span class="c1"># back to our caller</span>995 <span class="n">stack</span><span class="o">.</span><span class="n">pop_all</span><span class="p">()</span>996 997 <span class="k">def</span><span class="w"> </span><span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>998 <span class="n">resource</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">acquire_resource</span><span class="p">()</span>999 <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cleanup_on_error</span><span class="p">():</span>1000 <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">check_resource_ok</span><span class="p">(</span><span class="n">resource</span><span class="p">):</span>1001 <span class="n">msg</span> <span class="o">=</span> <span class="s2">"Failed validation for </span><span class="si">{!r}</span><span class="s2">"</span>1002 <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">resource</span><span class="p">))</span>1003 <span class="k">return</span> <span class="n">resource</span>1004 1005 <span class="k">def</span><span class="w"> </span><span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">exc_details</span><span class="p">):</span>1006 <span class="c1"># We don't need to duplicate any of our resource release logic</span>1007 <span class="bp">self</span><span class="o">.</span><span class="n">release_resource</span><span class="p">()</span>1008</pre></div>1009</div>1010</section>1011<section id="replacing-any-use-of-try-finally-and-flag-variables">1012<h3>Replacing any use of <code class="docutils literal notranslate"><span class="pre">try-finally</span></code> and flag variables<a class="headerlink" href="#replacing-any-use-of-try-finally-and-flag-variables" title="Link to this heading">¶</a></h3>1013<p>A pattern you will sometimes see is a <code class="docutils literal notranslate"><span class="pre">try-finally</span></code> statement with a flag1014variable to indicate whether or not the body of the <code class="docutils literal notranslate"><span class="pre">finally</span></code> clause should1015be executed. In its simplest form (that can’t already be handled just by1016using an <code class="docutils literal notranslate"><span class="pre">except</span></code> clause instead), it looks something like this:</p>1017<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">cleanup_needed</span> <span class="o">=</span> <span class="kc">True</span>1018<span class="k">try</span><span class="p">:</span>1019 <span class="n">result</span> <span class="o">=</span> <span class="n">perform_operation</span><span class="p">()</span>1020 <span class="k">if</span> <span class="n">result</span><span class="p">:</span>1021 <span class="n">cleanup_needed</span> <span class="o">=</span> <span class="kc">False</span>1022<span class="k">finally</span><span class="p">:</span>1023 <span class="k">if</span> <span class="n">cleanup_needed</span><span class="p">:</span>1024 <span class="n">cleanup_resources</span><span class="p">()</span>1025</pre></div>1026</div>1027<p>As with any <code class="docutils literal notranslate"><span class="pre">try</span></code> statement based code, this can cause problems for1028development and review, because the setup code and the cleanup code can end1029up being separated by arbitrarily long sections of code.</p>1030<p><a class="reference internal" href="#contextlib.ExitStack" title="contextlib.ExitStack"><code class="xref py py-class docutils literal notranslate"><span class="pre">ExitStack</span></code></a> makes it possible to instead register a callback for1031execution at the end of a <code class="docutils literal notranslate"><span class="pre">with</span></code> statement, and then later decide to skip1032executing that callback:</p>1033<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">ExitStack</span>1034 1035<span class="k">with</span> <span class="n">ExitStack</span><span class="p">()</span> <span class="k">as</span> <span class="n">stack</span><span class="p">:</span>1036 <span class="n">stack</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">cleanup_resources</span><span class="p">)</span>1037 <span class="n">result</span> <span class="o">=</span> <span class="n">perform_operation</span><span class="p">()</span>1038 <span class="k">if</span> <span class="n">result</span><span class="p">:</span>1039 <span class="n">stack</span><span class="o">.</span><span class="n">pop_all</span><span class="p">()</span>1040</pre></div>1041</div>1042<p>This allows the intended cleanup behaviour to be made explicit up front,1043rather than requiring a separate flag variable.</p>1044<p>If a particular application uses this pattern a lot, it can be simplified1045even further by means of a small helper class:</p>1046<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">ExitStack</span>1047 1048<span class="k">class</span><span class="w"> </span><span class="nc">Callback</span><span class="p">(</span><span class="n">ExitStack</span><span class="p">):</span>1049 <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">):</span>1050 <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>1051 <span class="bp">self</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">callback</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwds</span><span class="p">)</span>1052 1053 <span class="k">def</span><span class="w"> </span><span class="nf">cancel</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>1054 <span class="bp">self</span><span class="o">.</span><span class="n">pop_all</span><span class="p">()</span>1055 1056<span class="k">with</span> <span class="n">Callback</span><span class="p">(</span><span class="n">cleanup_resources</span><span class="p">)</span> <span class="k">as</span> <span class="n">cb</span><span class="p">:</span>1057 <span class="n">result</span> <span class="o">=</span> <span class="n">perform_operation</span><span class="p">()</span>1058 <span class="k">if</span> <span class="n">result</span><span class="p">:</span>1059 <span class="n">cb</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span>1060</pre></div>1061</div>1062<p>If the resource cleanup isn’t already neatly bundled into a standalone1063function, then it is still possible to use the decorator form of1064<a class="reference internal" href="#contextlib.ExitStack.callback" title="contextlib.ExitStack.callback"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ExitStack.callback()</span></code></a> to declare the resource cleanup in1065advance:</p>1066<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">ExitStack</span>1067 1068<span class="k">with</span> <span class="n">ExitStack</span><span class="p">()</span> <span class="k">as</span> <span class="n">stack</span><span class="p">:</span>1069 <span class="nd">@stack</span><span class="o">.</span><span class="n">callback</span>1070 <span class="k">def</span><span class="w"> </span><span class="nf">cleanup_resources</span><span class="p">():</span>1071 <span class="o">...</span>1072 <span class="n">result</span> <span class="o">=</span> <span class="n">perform_operation</span><span class="p">()</span>1073 <span class="k">if</span> <span class="n">result</span><span class="p">:</span>1074 <span class="n">stack</span><span class="o">.</span><span class="n">pop_all</span><span class="p">()</span>1075</pre></div>1076</div>1077<p>Due to the way the decorator protocol works, a callback function1078declared this way cannot take any parameters. Instead, any resources to1079be released must be accessed as closure variables.</p>1080</section>1081<section id="using-a-context-manager-as-a-function-decorator">1082<h3>Using a context manager as a function decorator<a class="headerlink" href="#using-a-context-manager-as-a-function-decorator" title="Link to this heading">¶</a></h3>1083<p><a class="reference internal" href="#contextlib.ContextDecorator" title="contextlib.ContextDecorator"><code class="xref py py-class docutils literal notranslate"><span class="pre">ContextDecorator</span></code></a> makes it possible to use a context manager in1084both an ordinary <code class="docutils literal notranslate"><span class="pre">with</span></code> statement and also as a function decorator.</p>1085<p>For example, it is sometimes useful to wrap functions or groups of statements1086with a logger that can track the time of entry and time of exit. Rather than1087writing both a function decorator and a context manager for the task,1088inheriting from <a class="reference internal" href="#contextlib.ContextDecorator" title="contextlib.ContextDecorator"><code class="xref py py-class docutils literal notranslate"><span class="pre">ContextDecorator</span></code></a> provides both capabilities in a1089single definition:</p>1090<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">ContextDecorator</span>1091<span class="kn">import</span><span class="w"> </span><span class="nn">logging</span>1092 1093<span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>1094 1095<span class="k">class</span><span class="w"> </span><span class="nc">track_entry_and_exit</span><span class="p">(</span><span class="n">ContextDecorator</span><span class="p">):</span>1096 <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>1097 <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>1098 1099 <span class="k">def</span><span class="w"> </span><span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>1100 <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">'Entering: </span><span class="si">%s</span><span class="s1">'</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>1101 1102 <span class="k">def</span><span class="w"> </span><span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc</span><span class="p">,</span> <span class="n">exc_tb</span><span class="p">):</span>1103 <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">'Exiting: </span><span class="si">%s</span><span class="s1">'</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>1104</pre></div>1105</div>1106<p>Instances of this class can be used as both a context manager:</p>1107<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">track_entry_and_exit</span><span class="p">(</span><span class="s1">'widget loader'</span><span class="p">):</span>1108 <span class="nb">print</span><span class="p">(</span><span class="s1">'Some time consuming activity goes here'</span><span class="p">)</span>1109 <span class="n">load_widget</span><span class="p">()</span>1110</pre></div>1111</div>1112<p>And also as a function decorator:</p>1113<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@track_entry_and_exit</span><span class="p">(</span><span class="s1">'widget loader'</span><span class="p">)</span>1114<span class="k">def</span><span class="w"> </span><span class="nf">activity</span><span class="p">():</span>1115 <span class="nb">print</span><span class="p">(</span><span class="s1">'Some time consuming activity goes here'</span><span class="p">)</span>1116 <span class="n">load_widget</span><span class="p">()</span>1117</pre></div>1118</div>1119<p>Note that there is one additional limitation when using context managers1120as function decorators: there’s no way to access the return value of1121<a class="reference internal" href="../reference/datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a>. If that value is needed, then it is still necessary to use1122an explicit <code class="docutils literal notranslate"><span class="pre">with</span></code> statement.</p>1123<div class="admonition seealso">1124<p class="admonition-title">See also</p>1125<dl class="simple">1126<dt><span class="target" id="index-0"></span><a class="pep reference external" href="https://peps.python.org/pep-0343/"><strong>PEP 343</strong></a> - The “with” statement</dt><dd><p>The specification, background, and examples for the Python <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a>1127statement.</p>1128</dd>1129</dl>1130</div>1131</section>1132</section>1133<section id="single-use-reusable-and-reentrant-context-managers">1134<span id="single-use-reusable-and-reentrant-cms"></span><h2>Single use, reusable and reentrant context managers<a class="headerlink" href="#single-use-reusable-and-reentrant-context-managers" title="Link to this heading">¶</a></h2>1135<p>Most context managers are written in a way that means they can only be1136used effectively in a <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement once. These single use1137context managers must be created afresh each time they’re used -1138attempting to use them a second time will trigger an exception or1139otherwise not work correctly.</p>1140<p>This common limitation means that it is generally advisable to create1141context managers directly in the header of the <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement1142where they are used (as shown in all of the usage examples above).</p>1143<p>Files are an example of effectively single use context managers, since1144the first <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement will close the file, preventing any1145further IO operations using that file object.</p>1146<p>Context managers created using <a class="reference internal" href="#contextlib.contextmanager" title="contextlib.contextmanager"><code class="xref py py-func docutils literal notranslate"><span class="pre">contextmanager()</span></code></a> are also single use1147context managers, and will complain about the underlying generator failing1148to yield if an attempt is made to use them a second time:</p>1149<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">contextmanager</span>1150<span class="gp">>>> </span><span class="nd">@contextmanager</span>1151<span class="gp">... </span><span class="k">def</span><span class="w"> </span><span class="nf">singleuse</span><span class="p">():</span>1152<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Before"</span><span class="p">)</span>1153<span class="gp">... </span> <span class="k">yield</span>1154<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"After"</span><span class="p">)</span>1155<span class="gp">...</span>1156<span class="gp">>>> </span><span class="n">cm</span> <span class="o">=</span> <span class="n">singleuse</span><span class="p">()</span>1157<span class="gp">>>> </span><span class="k">with</span> <span class="n">cm</span><span class="p">:</span>1158<span class="gp">... </span> <span class="k">pass</span>1159<span class="gp">...</span>1160<span class="go">Before</span>1161<span class="go">After</span>1162<span class="gp">>>> </span><span class="k">with</span> <span class="n">cm</span><span class="p">:</span>1163<span class="gp">... </span> <span class="k">pass</span>1164<span class="gp">...</span>1165<span class="gt">Traceback (most recent call last):</span>1166<span class="w"> </span><span class="o">...</span>1167<span class="gr">RuntimeError</span>: <span class="n">generator didn't yield</span>1168</pre></div>1169</div>1170<section id="reentrant-context-managers">1171<span id="reentrant-cms"></span><h3>Reentrant context managers<a class="headerlink" href="#reentrant-context-managers" title="Link to this heading">¶</a></h3>1172<p>More sophisticated context managers may be “reentrant”. These context1173managers can not only be used in multiple <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statements,1174but may also be used <em>inside</em> a <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement that is already1175using the same context manager.</p>1176<p><a class="reference internal" href="threading.html#threading.RLock" title="threading.RLock"><code class="xref py py-class docutils literal notranslate"><span class="pre">threading.RLock</span></code></a> is an example of a reentrant context manager, as are1177<a class="reference internal" href="#contextlib.suppress" title="contextlib.suppress"><code class="xref py py-func docutils literal notranslate"><span class="pre">suppress()</span></code></a>, <a class="reference internal" href="#contextlib.redirect_stdout" title="contextlib.redirect_stdout"><code class="xref py py-func docutils literal notranslate"><span class="pre">redirect_stdout()</span></code></a>, and <a class="reference internal" href="#contextlib.chdir" title="contextlib.chdir"><code class="xref py py-func docutils literal notranslate"><span class="pre">chdir()</span></code></a>. Here’s a very1178simple example of reentrant use:</p>1179<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span><span class="w"> </span><span class="nn">contextlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">redirect_stdout</span>1180<span class="gp">>>> </span><span class="kn">from</span><span class="w"> </span><span class="nn">io</span><span class="w"> </span><span class="kn">import</span> <span class="n">StringIO</span>1181<span class="gp">>>> </span><span class="n">stream</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>1182<span class="gp">>>> </span><span class="n">write_to_stream</span> <span class="o">=</span> <span class="n">redirect_stdout</span><span class="p">(</span><span class="n">stream</span><span class="p">)</span>1183<span class="gp">>>> </span><span class="k">with</span> <span class="n">write_to_stream</span><span class="p">:</span>1184<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"This is written to the stream rather than stdout"</span><span class="p">)</span>1185<span class="gp">... </span> <span class="k">with</span> <span class="n">write_to_stream</span><span class="p">:</span>1186<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"This is also written to the stream"</span><span class="p">)</span>1187<span class="gp">...</span>1188<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="s2">"This is written directly to stdout"</span><span class="p">)</span>1189<span class="go">This is written directly to stdout</span>1190<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">stream</span><span class="o">.</span><span class="n">getvalue</span><span class="p">())</span>1191<span class="go">This is written to the stream rather than stdout</span>1192<span class="go">This is also written to the stream</span>1193</pre></div>1194</div>1195<p>Real world examples of reentrancy are more likely to involve multiple1196functions calling each other and hence be far more complicated than this1197example.</p>1198<p>Note also that being reentrant is <em>not</em> the same thing as being thread safe.1199<a class="reference internal" href="#contextlib.redirect_stdout" title="contextlib.redirect_stdout"><code class="xref py py-func docutils literal notranslate"><span class="pre">redirect_stdout()</span></code></a>, for example, is definitely not thread safe, as it1200makes a global modification to the system state by binding <a class="reference internal" href="sys.html#sys.stdout" title="sys.stdout"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stdout</span></code></a>