|
- <!DOCTYPE html>
-
- <html lang="en" data-content_root="../">
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
- <meta property="og:title" content="contextlib — Utilities for with-statement contexts" />
- <meta property="og:type" content="website" />
- <meta property="og:url" content="https://docs.python.org/3/library/contextlib.html" />
- <meta property="og:site_name" content="Python documentation" />
- <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...." />
- <meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
- <meta property="og:image:alt" content="Python documentation" />
- <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...." />
- <meta property="og:image:width" content="200" />
- <meta property="og:image:height" content="200" />
- <meta name="theme-color" content="#3776ab" />
-
- <title>contextlib — Utilities for with-statement contexts — Python 3.12.3 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
-
- <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=80d5e7a1" />
- <link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=bb723527" />
- <link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=b20cc3f5" />
-
- <script src="../_static/documentation_options.js?v=2c828074"></script>
- <script src="../_static/doctools.js?v=888ff710"></script>
- <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
-
- <script src="../_static/sidebar.js"></script>
-
- <link rel="search" type="application/opensearchdescription+xml"
- title="Search within Python 3.12.3 documentation"
- href="../_static/opensearch.xml"/>
- <link rel="author" title="About these documents" href="../about.html" />
- <link rel="index" title="Index" href="../genindex.html" />
- <link rel="search" title="Search" href="../search.html" />
- <link rel="copyright" title="Copyright" href="../copyright.html" />
- <link rel="next" title="abc — Abstract Base Classes" href="abc.html" />
- <link rel="prev" title="dataclasses — Data Classes" href="dataclasses.html" />
- <link rel="canonical" href="https://docs.python.org/3/library/contextlib.html" />
-
-
-
-
-
- <style>
- @media only screen {
- table.full-width-table {
- width: 100%;
- }
- }
- </style>
- <link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
- <link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
- <script type="text/javascript" src="../_static/copybutton.js"></script>
- <script type="text/javascript" src="../_static/menu.js"></script>
- <script type="text/javascript" src="../_static/search-focus.js"></script>
- <script type="text/javascript" src="../_static/themetoggle.js"></script>
-
- </head>
- <body>
- <div class="mobile-nav">
- <input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
- aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
- <nav class="nav-content" role="navigation">
- <label for="menuToggler" class="toggler__label">
- <span></span>
- </label>
- <span class="nav-items-wrapper">
- <a href="https://www.python.org/" class="nav-logo">
- <img src="../_static/py.svg" alt="Python logo"/>
- </a>
- <span class="version_switcher_placeholder"></span>
- <form role="search" class="search" action="../search.html" method="get">
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
- <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>
- </svg>
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
- <input type="submit" value="Go"/>
- </form>
- </span>
- </nav>
- <div class="menu-wrapper">
- <nav class="menu" role="navigation" aria-label="main navigation">
- <div class="language_switcher_placeholder"></div>
-
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label>
- <div>
- <h3><a href="../contents.html">Table of Contents</a></h3>
- <ul>
- <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>
- <li><a class="reference internal" href="#utilities">Utilities</a></li>
- <li><a class="reference internal" href="#examples-and-recipes">Examples and Recipes</a><ul>
- <li><a class="reference internal" href="#supporting-a-variable-number-of-context-managers">Supporting a variable number of context managers</a></li>
- <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>
- <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>
- <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>
- <li><a class="reference internal" href="#using-a-context-manager-as-a-function-decorator">Using a context manager as a function decorator</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#single-use-reusable-and-reentrant-context-managers">Single use, reusable and reentrant context managers</a><ul>
- <li><a class="reference internal" href="#reentrant-context-managers">Reentrant context managers</a></li>
- <li><a class="reference internal" href="#reusable-context-managers">Reusable context managers</a></li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
-
- </div>
- <div>
- <h4>Previous topic</h4>
- <p class="topless"><a href="dataclasses.html"
- title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">dataclasses</span></code> — Data Classes</a></p>
- </div>
- <div>
- <h4>Next topic</h4>
- <p class="topless"><a href="abc.html"
- title="next chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">abc</span></code> — Abstract Base Classes</a></p>
- </div>
- <div role="note" aria-label="source link">
- <h3>This Page</h3>
- <ul class="this-page-menu">
- <li><a href="../bugs.html">Report a Bug</a></li>
- <li>
- <a href="https://github.com/python/cpython/blob/main/Doc/library/contextlib.rst"
- rel="nofollow">Show Source
- </a>
- </li>
- </ul>
- </div>
- </nav>
- </div>
- </div>
-
-
- <div class="related" role="navigation" aria-label="related navigation">
- <h3>Navigation</h3>
- <ul>
- <li class="right" style="margin-right: 10px">
- <a href="../genindex.html" title="General Index"
- accesskey="I">index</a></li>
- <li class="right" >
- <a href="../py-modindex.html" title="Python Module Index"
- >modules</a> |</li>
- <li class="right" >
- <a href="abc.html" title="abc — Abstract Base Classes"
- accesskey="N">next</a> |</li>
- <li class="right" >
- <a href="dataclasses.html" title="dataclasses — Data Classes"
- accesskey="P">previous</a> |</li>
-
- <li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
- <li><a href="https://www.python.org/">Python</a> »</li>
- <li class="switchers">
- <div class="language_switcher_placeholder"></div>
- <div class="version_switcher_placeholder"></div>
- </li>
- <li>
-
- </li>
- <li id="cpython-language-and-version">
- <a href="../index.html">3.12.3 Documentation</a> »
- </li>
-
- <li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>
- <li class="nav-item nav-item-2"><a href="python.html" accesskey="U">Python Runtime Services</a> »</li>
- <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>
- <li class="right">
-
-
- <div class="inline-search" role="search">
- <form class="inline-search" action="../search.html" method="get">
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
- <input type="submit" value="Go" />
- </form>
- </div>
- |
- </li>
- <li class="right">
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label> |</li>
-
- </ul>
- </div>
-
- <div class="document">
- <div class="documentwrapper">
- <div class="bodywrapper">
- <div class="body" role="main">
-
- <section id="module-contextlib">
- <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>
- <p><strong>Source code:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/3.12/Lib/contextlib.py">Lib/contextlib.py</a></p>
- <hr class="docutils" />
- <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>
- statement. For more information see also <a class="reference internal" href="stdtypes.html#typecontextmanager"><span class="std std-ref">Context Manager Types</span></a> and
- <a class="reference internal" href="../reference/datamodel.html#context-managers"><span class="std std-ref">With Statement Context Managers</span></a>.</p>
- <section id="utilities">
- <h2>Utilities<a class="headerlink" href="#utilities" title="Link to this heading">¶</a></h2>
- <p>Functions and classes provided:</p>
- <dl class="py class">
- <dt class="sig sig-object py" id="contextlib.AbstractContextManager">
- <em class="property"><span class="pre">class</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>
- <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 implement
- <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">object.__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">object.__exit__()</span></code></a>. A default
- implementation for <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">object.__enter__()</span></code></a> is provided which returns
- <code class="docutils literal notranslate"><span class="pre">self</span></code> while <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">object.__exit__()</span></code></a> is an abstract method which by default
- returns <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>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.6.</span></p>
- </div>
- </dd></dl>
-
- <dl class="py class">
- <dt class="sig sig-object py" id="contextlib.AbstractAsyncContextManager">
- <em class="property"><span class="pre">class</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>
- <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 implement
- <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">object.__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">object.__aexit__()</span></code></a>. A default
- implementation for <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">object.__aenter__()</span></code></a> is provided which returns
- <code class="docutils literal notranslate"><span class="pre">self</span></code> while <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">object.__aexit__()</span></code></a> is an abstract method which by default
- returns <code class="docutils literal notranslate"><span class="pre">None</span></code>. See also the definition of
- <a class="reference internal" href="../reference/datamodel.html#async-context-managers"><span class="std std-ref">Asynchronous Context Managers</span></a>.</p>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.7.</span></p>
- </div>
- </dd></dl>
-
- <dl class="py function">
- <dt class="sig sig-object py" id="contextlib.contextmanager">
- <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>
- <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 factory
- function 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 to
- create 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>
- <p>While many objects natively support use in with statements, sometimes a
- resource needs to be managed that isn’t a context manager in its own right,
- and 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>
- <p>An abstract example would be the following to ensure correct resource
- management:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">contextmanager</span>
-
- <span class="nd">@contextmanager</span>
- <span class="k">def</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>
- <span class="c1"># Code to acquire resource, e.g.:</span>
- <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>
- <span class="k">try</span><span class="p">:</span>
- <span class="k">yield</span> <span class="n">resource</span>
- <span class="k">finally</span><span class="p">:</span>
- <span class="c1"># Code to release resource, e.g.:</span>
- <span class="n">release_resource</span><span class="p">(</span><span class="n">resource</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>The function can then be used like this:</p>
- <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>
- <span class="gp">... </span> <span class="c1"># Resource is released at the end of this block,</span>
- <span class="gp">... </span> <span class="c1"># even if code in the block raises an exception</span>
- </pre></div>
- </div>
- <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 when
- called. This iterator must yield exactly one value, which will be bound to
- the 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>
- <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>
- statement is executed. The generator is then resumed after the block is exited.
- If an unhandled exception occurs in the block, it is reraised inside the
- generator at the point where the yield occurred. Thus, you can use a
- <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 trap
- the error (if any), or ensure that some cleanup takes place. If an exception is
- trapped merely in order to log it or to perform some action (rather than to
- suppress it entirely), the generator must reraise that exception. Otherwise the
- generator context manager will indicate to the <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement that
- the exception has been handled, and execution will resume with the statement
- immediately following the <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement.</p>
- <p><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> 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 managers
- it 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.
- When used as a decorator, a new generator instance is implicitly created on
- each function call (this allows the otherwise “one-shot” context managers
- created 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> to meet the requirement that context
- managers support multiple invocations in order to be used as decorators).</p>
- <div class="versionchanged">
- <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>
- </div>
- </dd></dl>
-
- <dl class="py function">
- <dt class="sig sig-object py" id="contextlib.asynccontextmanager">
- <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>
- <dd><blockquote>
- <div><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 an
- <a class="reference internal" href="../reference/datamodel.html#async-context-managers"><span class="std std-ref">asynchronous context manager</span></a>.</p>
- <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 factory
- function 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,
- without 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> 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> methods. It must be applied to an <a class="reference internal" href="../glossary.html#term-asynchronous-generator"><span class="xref std std-term">asynchronous
- generator</span></a> function.</p>
- <p>A simple example:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">asynccontextmanager</span>
-
- <span class="nd">@asynccontextmanager</span>
- <span class="k">async</span> <span class="k">def</span> <span class="nf">get_connection</span><span class="p">():</span>
- <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>
- <span class="k">try</span><span class="p">:</span>
- <span class="k">yield</span> <span class="n">conn</span>
- <span class="k">finally</span><span class="p">:</span>
- <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>
-
- <span class="k">async</span> <span class="k">def</span> <span class="nf">get_all_users</span><span class="p">():</span>
- <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>
- <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>
- </pre></div>
- </div>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.7.</span></p>
- </div>
- <p>Context managers defined with <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> can be used
- either 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>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">time</span>
- <span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">asynccontextmanager</span>
-
- <span class="nd">@asynccontextmanager</span>
- <span class="k">async</span> <span class="k">def</span> <span class="nf">timeit</span><span class="p">():</span>
- <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>
- <span class="k">try</span><span class="p">:</span>
- <span class="k">yield</span>
- <span class="k">finally</span><span class="p">:</span>
- <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>
-
- <span class="nd">@timeit</span><span class="p">()</span>
- <span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
- <span class="c1"># ... async code ...</span>
- </pre></div>
- </div>
- <p>When used as a decorator, a new generator instance is implicitly created on
- each function call. This allows the otherwise “one-shot” context managers
- created by <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> to meet the requirement that context
- managers support multiple invocations in order to be used as decorators.</p>
- </div></blockquote>
- <div class="versionchanged">
- <p><span class="versionmodified changed">Changed in version 3.10: </span>Async context managers created with <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> can
- be used as decorators.</p>
- </div>
- </dd></dl>
-
- <dl class="py function">
- <dt class="sig sig-object py" id="contextlib.closing">
- <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>
- <dd><p>Return a context manager that closes <em>thing</em> upon completion of the block. This
- is basically equivalent to:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">contextmanager</span>
-
- <span class="nd">@contextmanager</span>
- <span class="k">def</span> <span class="nf">closing</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="k">yield</span> <span class="n">thing</span>
- <span class="k">finally</span><span class="p">:</span>
- <span class="n">thing</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>And lets you write code like this:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">closing</span>
- <span class="kn">from</span> <span class="nn">urllib.request</span> <span class="kn">import</span> <span class="n">urlopen</span>
-
- <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>
- <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">page</span><span class="p">:</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>without needing to explicitly close <code class="docutils literal notranslate"><span class="pre">page</span></code>. Even if an error occurs,
- <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>
- <div class="admonition note">
- <p class="admonition-title">Note</p>
- <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,
- which 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.
- As 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’t
- support context managers.
- This example is purely for illustration purposes,
- as <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>
- </div>
- </dd></dl>
-
- <dl class="py function">
- <dt class="sig sig-object py" id="contextlib.aclosing">
- <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>
- <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>
- upon completion of the block. This is basically equivalent to:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">asynccontextmanager</span>
-
- <span class="nd">@asynccontextmanager</span>
- <span class="k">async</span> <span class="k">def</span> <span class="nf">aclosing</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="k">yield</span> <span class="n">thing</span>
- <span class="k">finally</span><span class="p">:</span>
- <span class="k">await</span> <span class="n">thing</span><span class="o">.</span><span class="n">aclose</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>Significantly, <code class="docutils literal notranslate"><span class="pre">aclosing()</span></code> supports deterministic cleanup of async
- generators 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 an
- exception. For example:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">aclosing</span>
-
- <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>
- <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>
- <span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="mi">42</span><span class="p">:</span>
- <span class="k">break</span>
- </pre></div>
- </div>
- <p>This pattern ensures that the generator’s async exit code is executed in
- the same context as its iterations (so that exceptions and context
- variables work as expected, and the exit code isn’t run after the
- lifetime of some task it depends on).</p>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.10.</span></p>
- </div>
- </dd></dl>
-
- <dl class="py function" id="simplifying-support-for-single-optional-context-managers">
- <dt class="sig sig-object py" id="contextlib.nullcontext">
- <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>
- <dd><p>Return a context manager that returns <em>enter_result</em> from <code class="docutils literal notranslate"><span class="pre">__enter__</span></code>, but
- otherwise does nothing. It is intended to be used as a stand-in for an
- optional context manager, for example:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</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>
- <span class="k">if</span> <span class="n">ignore_exceptions</span><span class="p">:</span>
- <span class="c1"># Use suppress to ignore all exceptions.</span>
- <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>
- <span class="k">else</span><span class="p">:</span>
- <span class="c1"># Do not ignore any exceptions, cm has no effect.</span>
- <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>
- <span class="k">with</span> <span class="n">cm</span><span class="p">:</span>
- <span class="c1"># Do something</span>
- </pre></div>
- </div>
- <p>An example using <em>enter_result</em>:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">process_file</span><span class="p">(</span><span class="n">file_or_path</span><span class="p">):</span>
- <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>
- <span class="c1"># If string, open file</span>
- <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>
- <span class="k">else</span><span class="p">:</span>
- <span class="c1"># Caller is responsible for closing file</span>
- <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>
-
- <span class="k">with</span> <span class="n">cm</span> <span class="k">as</span> <span class="n">file</span><span class="p">:</span>
- <span class="c1"># Perform processing on the file</span>
- </pre></div>
- </div>
- <p>It can also be used as a stand-in for
- <a class="reference internal" href="../reference/datamodel.html#async-context-managers"><span class="std std-ref">asynchronous context managers</span></a>:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</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>
- <span class="k">if</span> <span class="ow">not</span> <span class="n">session</span><span class="p">:</span>
- <span class="c1"># If no http session, create it with aiohttp</span>
- <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>
- <span class="k">else</span><span class="p">:</span>
- <span class="c1"># Caller is responsible for closing the session</span>
- <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>
-
- <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>
- <span class="c1"># Send http requests with session</span>
- </pre></div>
- </div>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.7.</span></p>
- </div>
- <div class="versionchanged">
- <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>
- </div>
- </dd></dl>
-
- <dl class="py function">
- <dt class="sig sig-object py" id="contextlib.suppress">
- <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>
- <dd><p>Return a context manager that suppresses any of the specified exceptions
- if they occur in the body of a <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement and then
- resumes execution with the first statement following the end of the
- <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement.</p>
- <p>As with any other mechanism that completely suppresses exceptions, this
- context manager should be used only to cover very specific errors where
- silently continuing with program execution is known to be the right
- thing to do.</p>
- <p>For example:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">suppress</span>
-
- <span class="k">with</span> <span class="n">suppress</span><span class="p">(</span><span class="ne">FileNotFoundError</span><span class="p">):</span>
- <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>
-
- <span class="k">with</span> <span class="n">suppress</span><span class="p">(</span><span class="ne">FileNotFoundError</span><span class="p">):</span>
- <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>
- </pre></div>
- </div>
- <p>This code is equivalent to:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
- <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>
- <span class="k">except</span> <span class="ne">FileNotFoundError</span><span class="p">:</span>
- <span class="k">pass</span>
-
- <span class="k">try</span><span class="p">:</span>
- <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>
- <span class="k">except</span> <span class="ne">FileNotFoundError</span><span class="p">:</span>
- <span class="k">pass</span>
- </pre></div>
- </div>
- <p>This context manager is <a class="reference internal" href="#reentrant-cms"><span class="std std-ref">reentrant</span></a>.</p>
- <p>If the code within the <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> block raises 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>, suppressed exceptions are removed from the
- group. If any exceptions in the group are not suppressed, a group containing them is re-raised.</p>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.4.</span></p>
- </div>
- <div class="versionchanged">
- <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 as
- part of an <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>
- </div>
- </dd></dl>
-
- <dl class="py function">
- <dt class="sig sig-object py" id="contextlib.redirect_stdout">
- <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>
- <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> to
- another file or file-like object.</p>
- <p>This tool adds flexibility to existing functions or classes whose output
- is hardwired to stdout.</p>
- <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>.
- You can capture that output in a string by redirecting the output to an
- <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 the
- <code class="docutils literal notranslate"><span class="pre">__enter__</span></code> method and so is available as the target 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> statement:</p>
- <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>
- <span class="n">help</span><span class="p">(</span><span class="nb">pow</span><span class="p">)</span>
- <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>
- </pre></div>
- </div>
- <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 output
- to a regular file:</p>
- <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>
- <span class="k">with</span> <span class="n">redirect_stdout</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
- <span class="n">help</span><span class="p">(</span><span class="nb">pow</span><span class="p">)</span>
- </pre></div>
- </div>
- <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>
- <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>
- <span class="n">help</span><span class="p">(</span><span class="nb">pow</span><span class="p">)</span>
- </pre></div>
- </div>
- <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 this
- context manager is not suitable for use in library code and most threaded
- applications. It also has no effect on the output of subprocesses.
- However, it is still a useful approach for many utility scripts.</p>
- <p>This context manager is <a class="reference internal" href="#reentrant-cms"><span class="std std-ref">reentrant</span></a>.</p>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.4.</span></p>
- </div>
- </dd></dl>
-
- <dl class="py function">
- <dt class="sig sig-object py" id="contextlib.redirect_stderr">
- <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>
- <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
- <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 file or file-like object.</p>
- <p>This context manager is <a class="reference internal" href="#reentrant-cms"><span class="std std-ref">reentrant</span></a>.</p>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.5.</span></p>
- </div>
- </dd></dl>
-
- <dl class="py function">
- <dt class="sig sig-object py" id="contextlib.chdir">
- <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>
- <dd><p>Non parallel-safe context manager to change the current working directory.
- As this changes a global state, the working directory, it is not suitable
- for use in most threaded or async contexts. It is also not suitable for most
- non-linear code execution, like generators, where the program execution is
- temporarily relinquished – unless explicitly desired, you should not yield
- when this context manager is active.</p>
- <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 current
- working directory upon entering and restores the old one on exit.</p>
- <p>This context manager is <a class="reference internal" href="#reentrant-cms"><span class="std std-ref">reentrant</span></a>.</p>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.11.</span></p>
- </div>
- </dd></dl>
-
- <dl class="py class">
- <dt class="sig sig-object py" id="contextlib.ContextDecorator">
- <em class="property"><span class="pre">class</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>
- <dd><p>A base class that enables a context manager to also be used as a decorator.</p>
- <p>Context managers inheriting from <code class="docutils literal notranslate"><span class="pre">ContextDecorator</span></code> have to implement
- <code class="docutils literal notranslate"><span class="pre">__enter__</span></code> and <code class="docutils literal notranslate"><span class="pre">__exit__</span></code> as normal. <code class="docutils literal notranslate"><span class="pre">__exit__</span></code> retains its optional
- exception handling even when used as a decorator.</p>
- <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 this
- functionality automatically.</p>
- <p>Example of <code class="docutils literal notranslate"><span class="pre">ContextDecorator</span></code>:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">ContextDecorator</span>
-
- <span class="k">class</span> <span class="nc">mycontext</span><span class="p">(</span><span class="n">ContextDecorator</span><span class="p">):</span>
- <span class="k">def</span> <span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'Starting'</span><span class="p">)</span>
- <span class="k">return</span> <span class="bp">self</span>
-
- <span class="k">def</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>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'Finishing'</span><span class="p">)</span>
- <span class="k">return</span> <span class="kc">False</span>
- </pre></div>
- </div>
- <p>The class can then be used like this:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nd">@mycontext</span><span class="p">()</span>
- <span class="gp">... </span><span class="k">def</span> <span class="nf">function</span><span class="p">():</span>
- <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>
- <span class="gp">...</span>
- <span class="gp">>>> </span><span class="n">function</span><span class="p">()</span>
- <span class="go">Starting</span>
- <span class="go">The bit in the middle</span>
- <span class="go">Finishing</span>
-
- <span class="gp">>>> </span><span class="k">with</span> <span class="n">mycontext</span><span class="p">():</span>
- <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>
- <span class="gp">...</span>
- <span class="go">Starting</span>
- <span class="go">The bit in the middle</span>
- <span class="go">Finishing</span>
- </pre></div>
- </div>
- <p>This change is just syntactic sugar for any construct of the following form:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
- <span class="k">with</span> <span class="n">cm</span><span class="p">():</span>
- <span class="c1"># Do stuff</span>
- </pre></div>
- </div>
- <p><code class="docutils literal notranslate"><span class="pre">ContextDecorator</span></code> lets you instead write:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@cm</span><span class="p">()</span>
- <span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
- <span class="c1"># Do stuff</span>
- </pre></div>
- </div>
- <p>It makes it clear that the <code class="docutils literal notranslate"><span class="pre">cm</span></code> applies to the whole function, rather than
- just a piece of it (and saving an indentation level is nice, too).</p>
- <p>Existing context managers that already have a base class can be extended by
- using <code class="docutils literal notranslate"><span class="pre">ContextDecorator</span></code> as a mixin class:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">ContextDecorator</span>
-
- <span class="k">class</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>
- <span class="k">def</span> <span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="k">return</span> <span class="bp">self</span>
-
- <span class="k">def</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>
- <span class="k">return</span> <span class="kc">False</span>
- </pre></div>
- </div>
- <div class="admonition note">
- <p class="admonition-title">Note</p>
- <p>As the decorated function must be able to be called multiple times, the
- underlying 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>
- statements. If this is not the case, then the original construct with the
- explicit <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> statement inside the function should be used.</p>
- </div>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.2.</span></p>
- </div>
- </dd></dl>
-
- <dl class="py class">
- <dt class="sig sig-object py" id="contextlib.AsyncContextDecorator">
- <em class="property"><span class="pre">class</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>
- <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>
- <p>Example of <code class="docutils literal notranslate"><span class="pre">AsyncContextDecorator</span></code>:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">asyncio</span> <span class="kn">import</span> <span class="n">run</span>
- <span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">AsyncContextDecorator</span>
-
- <span class="k">class</span> <span class="nc">mycontext</span><span class="p">(</span><span class="n">AsyncContextDecorator</span><span class="p">):</span>
- <span class="k">async</span> <span class="k">def</span> <span class="fm">__aenter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'Starting'</span><span class="p">)</span>
- <span class="k">return</span> <span class="bp">self</span>
-
- <span class="k">async</span> <span class="k">def</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>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'Finishing'</span><span class="p">)</span>
- <span class="k">return</span> <span class="kc">False</span>
- </pre></div>
- </div>
- <p>The class can then be used like this:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nd">@mycontext</span><span class="p">()</span>
- <span class="gp">... </span><span class="k">async</span> <span class="k">def</span> <span class="nf">function</span><span class="p">():</span>
- <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>
- <span class="gp">...</span>
- <span class="gp">>>> </span><span class="n">run</span><span class="p">(</span><span class="n">function</span><span class="p">())</span>
- <span class="go">Starting</span>
- <span class="go">The bit in the middle</span>
- <span class="go">Finishing</span>
-
- <span class="gp">>>> </span><span class="k">async</span> <span class="k">def</span> <span class="nf">function</span><span class="p">():</span>
- <span class="gp">... </span> <span class="k">async</span> <span class="k">with</span> <span class="n">mycontext</span><span class="p">():</span>
- <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>
- <span class="gp">...</span>
- <span class="gp">>>> </span><span class="n">run</span><span class="p">(</span><span class="n">function</span><span class="p">())</span>
- <span class="go">Starting</span>
- <span class="go">The bit in the middle</span>
- <span class="go">Finishing</span>
- </pre></div>
- </div>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.10.</span></p>
- </div>
- </dd></dl>
-
- <dl class="py class">
- <dt class="sig sig-object py" id="contextlib.ExitStack">
- <em class="property"><span class="pre">class</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>
- <dd><p>A context manager that is designed to make it easy to programmatically
- combine other context managers and cleanup functions, especially those
- that are optional or otherwise driven by input data.</p>
- <p>For example, a set of files may easily be handled in a single with
- statement as follows:</p>
- <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>
- <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>
- <span class="c1"># All opened files will automatically be closed at the end of</span>
- <span class="c1"># the with statement, even if attempts to open files later</span>
- <span class="c1"># in the list raise an exception</span>
- </pre></div>
- </div>
- <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 <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> instance, and
- performs no additional operations.</p>
- <p>Each instance maintains a stack of registered callbacks that are called in
- reverse order when the instance is closed (either explicitly 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). Note that callbacks are <em>not</em>
- invoked implicitly when the context stack instance is garbage collected.</p>
- <p>This stack model is used so that context managers that acquire their
- resources in their <code class="docutils literal notranslate"><span class="pre">__init__</span></code> method (such as file objects) can be
- handled correctly.</p>
- <p>Since registered callbacks are invoked in the reverse order of
- registration, 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>
- statements had been used with the registered set of callbacks. This even
- extends to exception handling - if an inner callback suppresses or replaces
- an exception, then outer callbacks will be passed arguments based on that
- updated state.</p>
- <p>This is a relatively low level API that takes care of the details of
- correctly unwinding the stack of exit callbacks. It provides a suitable
- foundation for higher level context managers that manipulate the exit
- stack in application specific ways.</p>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.3.</span></p>
- </div>
- <dl class="py method">
- <dt class="sig sig-object py" id="contextlib.ExitStack.enter_context">
- <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>
- <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 to
- the callback stack. The return value is the result of the context
- manager’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>
- <p>These context managers may suppress exceptions just as they normally
- would 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>
- <div class="versionchanged">
- <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>
- is not a context manager.</p>
- </div>
- </dd></dl>
-
- <dl class="py method">
- <dt class="sig sig-object py" id="contextlib.ExitStack.push">
- <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>
- <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>
- <p>As <code class="docutils literal notranslate"><span class="pre">__enter__</span></code> is <em>not</em> invoked, this method can be used to cover
- part 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 own
- <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>
- <p>If passed an object that is not a context manager, this method assumes
- it is a callback with the same signature as 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 and adds it directly to the callback stack.</p>
- <p>By returning true values, these callbacks can suppress exceptions the
- same 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>
- <p>The passed in object is returned from the function, allowing this
- method to be used as a function decorator.</p>
- </dd></dl>
-
- <dl class="py method">
- <dt class="sig sig-object py" id="contextlib.ExitStack.callback">
- <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="o"><span class="pre">/</span></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>
- <dd><p>Accepts an arbitrary callback function and arguments and adds it to
- the callback stack.</p>
- <p>Unlike the other methods, callbacks added this way cannot suppress
- exceptions (as they are never passed the exception details).</p>
- <p>The passed in callback is returned from the function, allowing this
- method to be used as a function decorator.</p>
- </dd></dl>
-
- <dl class="py method">
- <dt class="sig sig-object py" id="contextlib.ExitStack.pop_all">
- <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>
- <dd><p>Transfers the callback stack to a fresh <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> instance
- and returns it. No callbacks are invoked by this operation - instead,
- they will now be invoked when the new stack is closed (either
- explicitly 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>
- <p>For example, a group of files can be opened as an “all or nothing”
- operation as follows:</p>
- <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>
- <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>
- <span class="c1"># Hold onto the close method, but don't call it yet.</span>
- <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>
- <span class="c1"># If opening any file fails, all previously opened files will be</span>
- <span class="c1"># closed automatically. If all files are opened successfully,</span>
- <span class="c1"># they will remain open even after the with statement ends.</span>
- <span class="c1"># close_files() can then be invoked explicitly to close them all.</span>
- </pre></div>
- </div>
- </dd></dl>
-
- <dl class="py method">
- <dt class="sig sig-object py" id="contextlib.ExitStack.close">
- <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>
- <dd><p>Immediately unwinds the callback stack, invoking callbacks in the
- reverse order of registration. For any context managers and exit
- callbacks registered, the arguments passed in will indicate that no
- exception occurred.</p>
- </dd></dl>
-
- </dd></dl>
-
- <dl class="py class">
- <dt class="sig sig-object py" id="contextlib.AsyncExitStack">
- <em class="property"><span class="pre">class</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>
- <dd><p>An <a class="reference internal" href="../reference/datamodel.html#async-context-managers"><span class="std std-ref">asynchronous context manager</span></a>, similar
- to <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 and
- asynchronous context managers, as well as having coroutines for
- cleanup logic.</p>
- <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 used
- instead.</p>
- <dl class="py method">
- <dt class="sig sig-object py" id="contextlib.AsyncExitStack.enter_async_context">
- <em class="property"><span class="pre">coroutine</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>
- <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 context
- manager.</p>
- <div class="versionchanged">
- <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>
- is not an asynchronous context manager.</p>
- </div>
- </dd></dl>
-
- <dl class="py method">
- <dt class="sig sig-object py" id="contextlib.AsyncExitStack.push_async_exit">
- <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>
- <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 manager
- or a coroutine function.</p>
- </dd></dl>
-
- <dl class="py method">
- <dt class="sig sig-object py" id="contextlib.AsyncExitStack.push_async_callback">
- <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="o"><span class="pre">/</span></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>
- <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>
- </dd></dl>
-
- <dl class="py method">
- <dt class="sig sig-object py" id="contextlib.AsyncExitStack.aclose">
- <em class="property"><span class="pre">coroutine</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>
- <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>
- </dd></dl>
-
- <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>
- <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>
- <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>
- <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>
- <span class="c1"># All opened connections will automatically be released at the end of</span>
- <span class="c1"># the async with statement, even if attempts to open a connection</span>
- <span class="c1"># later in the list raise an exception.</span>
- </pre></div>
- </div>
- <div class="versionadded">
- <p><span class="versionmodified added">New in version 3.7.</span></p>
- </div>
- </dd></dl>
-
- </section>
- <section id="examples-and-recipes">
- <h2>Examples and Recipes<a class="headerlink" href="#examples-and-recipes" title="Link to this heading">¶</a></h2>
- <p>This section describes some examples and recipes for making effective use of
- the tools provided by <a class="reference internal" href="#module-contextlib" title="contextlib: Utilities for with-statement contexts."><code class="xref py py-mod docutils literal notranslate"><span class="pre">contextlib</span></code></a>.</p>
- <section id="supporting-a-variable-number-of-context-managers">
- <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>
- <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 class
- documentation: supporting a variable number of context managers and other
- cleanup 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 variability
- may come from the number of context managers needed being driven by user
- input (such as opening a user specified collection of files), or from
- some of the context managers being optional:</p>
- <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>
- <span class="k">for</span> <span class="n">resource</span> <span class="ow">in</span> <span class="n">resources</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="n">resource</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">need_special_resource</span><span class="p">():</span>
- <span class="n">special</span> <span class="o">=</span> <span class="n">acquire_special_resource</span><span class="p">()</span>
- <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>
- <span class="c1"># Perform operations that use the acquired resources</span>
- </pre></div>
- </div>
- <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>
- statements to manage arbitrary resources that don’t natively support the
- context management protocol.</p>
- </section>
- <section id="catching-exceptions-from-enter-methods">
- <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>
- <p>It is occasionally desirable to catch exceptions from an <code class="docutils literal notranslate"><span class="pre">__enter__</span></code>
- method implementation, <em>without</em> inadvertently catching exceptions from
- 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 body or the context manager’s <code class="docutils literal notranslate"><span class="pre">__exit__</span></code>
- method. 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 management
- protocol can be separated slightly in order to allow this:</p>
- <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>
- <span class="k">try</span><span class="p">:</span>
- <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>
- <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
- <span class="c1"># handle __enter__ exception</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="k">with</span> <span class="n">stack</span><span class="p">:</span>
- <span class="c1"># Handle normal case</span>
- </pre></div>
- </div>
- <p>Actually needing to do this is likely to indicate that the underlying API
- should be providing a direct resource management interface for use with
- <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 not
- all APIs are well designed in that regard. When a context manager is the
- only 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 it
- easier to handle various situations that can’t be handled directly 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.</p>
- </section>
- <section id="cleaning-up-in-an-enter-implementation">
- <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>
- <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>, this
- method can be useful in cleaning up an already allocated resource if later
- steps 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>
- <p>Here’s an example of doing this for a context manager that accepts resource
- acquisition and release functions, along with an optional validation function,
- and maps them to the context management protocol:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</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>
-
- <span class="k">class</span> <span class="nc">ResourceManager</span><span class="p">(</span><span class="n">AbstractContextManager</span><span class="p">):</span>
-
- <span class="k">def</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>
- <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>
- <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>
- <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>
- <span class="k">def</span> <span class="nf">check_resource_ok</span><span class="p">(</span><span class="n">resource</span><span class="p">):</span>
- <span class="k">return</span> <span class="kc">True</span>
- <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>
-
- <span class="nd">@contextmanager</span>
- <span class="k">def</span> <span class="nf">_cleanup_on_error</span><span class="p">(</span><span class="bp">self</span><span class="p">):</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>
- <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>
- <span class="k">yield</span>
- <span class="c1"># The validation check passed and didn't raise an exception</span>
- <span class="c1"># Accordingly, we want to keep the resource, and pass it</span>
- <span class="c1"># back to our caller</span>
- <span class="n">stack</span><span class="o">.</span><span class="n">pop_all</span><span class="p">()</span>
-
- <span class="k">def</span> <span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <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>
- <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>
- <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>
- <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>
- <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>
- <span class="k">return</span> <span class="n">resource</span>
-
- <span class="k">def</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>
- <span class="c1"># We don't need to duplicate any of our resource release logic</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">release_resource</span><span class="p">()</span>
- </pre></div>
- </div>
- </section>
- <section id="replacing-any-use-of-try-finally-and-flag-variables">
- <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>
- <p>A pattern you will sometimes see is a <code class="docutils literal notranslate"><span class="pre">try-finally</span></code> statement with a flag
- variable to indicate whether or not the body of the <code class="docutils literal notranslate"><span class="pre">finally</span></code> clause should
- be executed. In its simplest form (that can’t already be handled just by
- using an <code class="docutils literal notranslate"><span class="pre">except</span></code> clause instead), it looks something like this:</p>
- <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>
- <span class="k">try</span><span class="p">:</span>
- <span class="n">result</span> <span class="o">=</span> <span class="n">perform_operation</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">result</span><span class="p">:</span>
- <span class="n">cleanup_needed</span> <span class="o">=</span> <span class="kc">False</span>
- <span class="k">finally</span><span class="p">:</span>
- <span class="k">if</span> <span class="n">cleanup_needed</span><span class="p">:</span>
- <span class="n">cleanup_resources</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>As with any <code class="docutils literal notranslate"><span class="pre">try</span></code> statement based code, this can cause problems for
- development and review, because the setup code and the cleanup code can end
- up being separated by arbitrarily long sections of code.</p>
- <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 for
- execution at the end of a <code class="docutils literal notranslate"><span class="pre">with</span></code> statement, and then later decide to skip
- executing that callback:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">ExitStack</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>
- <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>
- <span class="n">result</span> <span class="o">=</span> <span class="n">perform_operation</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">result</span><span class="p">:</span>
- <span class="n">stack</span><span class="o">.</span><span class="n">pop_all</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>This allows the intended cleanup up behaviour to be made explicit up front,
- rather than requiring a separate flag variable.</p>
- <p>If a particular application uses this pattern a lot, it can be simplified
- even further by means of a small helper class:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">ExitStack</span>
-
- <span class="k">class</span> <span class="nc">Callback</span><span class="p">(</span><span class="n">ExitStack</span><span class="p">):</span>
- <span class="k">def</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>
- <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
- <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>
-
- <span class="k">def</span> <span class="nf">cancel</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">pop_all</span><span class="p">()</span>
-
- <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>
- <span class="n">result</span> <span class="o">=</span> <span class="n">perform_operation</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">result</span><span class="p">:</span>
- <span class="n">cb</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>If the resource cleanup isn’t already neatly bundled into a standalone
- function, then it is still possible to use the decorator form of
- <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 in
- advance:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">ExitStack</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>
- <span class="nd">@stack</span><span class="o">.</span><span class="n">callback</span>
- <span class="k">def</span> <span class="nf">cleanup_resources</span><span class="p">():</span>
- <span class="o">...</span>
- <span class="n">result</span> <span class="o">=</span> <span class="n">perform_operation</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">result</span><span class="p">:</span>
- <span class="n">stack</span><span class="o">.</span><span class="n">pop_all</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>Due to the way the decorator protocol works, a callback function
- declared this way cannot take any parameters. Instead, any resources to
- be released must be accessed as closure variables.</p>
- </section>
- <section id="using-a-context-manager-as-a-function-decorator">
- <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>
- <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 in
- both an ordinary <code class="docutils literal notranslate"><span class="pre">with</span></code> statement and also as a function decorator.</p>
- <p>For example, it is sometimes useful to wrap functions or groups of statements
- with a logger that can track the time of entry and time of exit. Rather than
- writing both a function decorator and a context manager for the task,
- inheriting 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 a
- single definition:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">ContextDecorator</span>
- <span class="kn">import</span> <span class="nn">logging</span>
-
- <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>
-
- <span class="k">class</span> <span class="nc">track_entry_and_exit</span><span class="p">(</span><span class="n">ContextDecorator</span><span class="p">):</span>
- <span class="k">def</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>
- <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
-
- <span class="k">def</span> <span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <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>
-
- <span class="k">def</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>
- <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>
- </pre></div>
- </div>
- <p>Instances of this class can be used as both a context manager:</p>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'Some time consuming activity goes here'</span><span class="p">)</span>
- <span class="n">load_widget</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>And also as a function decorator:</p>
- <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>
- <span class="k">def</span> <span class="nf">activity</span><span class="p">():</span>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'Some time consuming activity goes here'</span><span class="p">)</span>
- <span class="n">load_widget</span><span class="p">()</span>
- </pre></div>
- </div>
- <p>Note that there is one additional limitation when using context managers
- as function decorators: there’s no way to access the return value of
- <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 use
- an explicit <code class="docutils literal notranslate"><span class="pre">with</span></code> statement.</p>
- <div class="admonition seealso">
- <p class="admonition-title">See also</p>
- <dl class="simple">
- <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>
- statement.</p>
- </dd>
- </dl>
- </div>
- </section>
- </section>
- <section id="single-use-reusable-and-reentrant-context-managers">
- <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>
- <p>Most context managers are written in a way that means they can only be
- used 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 use
- context managers must be created afresh each time they’re used -
- attempting to use them a second time will trigger an exception or
- otherwise not work correctly.</p>
- <p>This common limitation means that it is generally advisable to create
- context 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> statement
- where they are used (as shown in all of the usage examples above).</p>
- <p>Files are an example of effectively single use context managers, since
- the 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 any
- further IO operations using that file object.</p>
- <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 use
- context managers, and will complain about the underlying generator failing
- to yield if an attempt is made to use them a second time:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">contextmanager</span>
- <span class="gp">>>> </span><span class="nd">@contextmanager</span>
- <span class="gp">... </span><span class="k">def</span> <span class="nf">singleuse</span><span class="p">():</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Before"</span><span class="p">)</span>
- <span class="gp">... </span> <span class="k">yield</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"After"</span><span class="p">)</span>
- <span class="gp">...</span>
- <span class="gp">>>> </span><span class="n">cm</span> <span class="o">=</span> <span class="n">singleuse</span><span class="p">()</span>
- <span class="gp">>>> </span><span class="k">with</span> <span class="n">cm</span><span class="p">:</span>
- <span class="gp">... </span> <span class="k">pass</span>
- <span class="gp">...</span>
- <span class="go">Before</span>
- <span class="go">After</span>
- <span class="gp">>>> </span><span class="k">with</span> <span class="n">cm</span><span class="p">:</span>
- <span class="gp">... </span> <span class="k">pass</span>
- <span class="gp">...</span>
- <span class="gt">Traceback (most recent call last):</span>
- <span class="w"> </span><span class="o">...</span>
- <span class="gr">RuntimeError</span>: <span class="n">generator didn't yield</span>
- </pre></div>
- </div>
- <section id="reentrant-context-managers">
- <span id="reentrant-cms"></span><h3>Reentrant context managers<a class="headerlink" href="#reentrant-context-managers" title="Link to this heading">¶</a></h3>
- <p>More sophisticated context managers may be “reentrant”. These context
- managers 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,
- but 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 already
- using the same context manager.</p>
- <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 are
- <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 very
- simple example of reentrant use:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">redirect_stdout</span>
- <span class="gp">>>> </span><span class="kn">from</span> <span class="nn">io</span> <span class="kn">import</span> <span class="n">StringIO</span>
- <span class="gp">>>> </span><span class="n">stream</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>
- <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>
- <span class="gp">>>> </span><span class="k">with</span> <span class="n">write_to_stream</span><span class="p">:</span>
- <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>
- <span class="gp">... </span> <span class="k">with</span> <span class="n">write_to_stream</span><span class="p">:</span>
- <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>
- <span class="gp">...</span>
- <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>
- <span class="go">This is written directly to stdout</span>
- <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>
- <span class="go">This is written to the stream rather than stdout</span>
- <span class="go">This is also written to the stream</span>
- </pre></div>
- </div>
- <p>Real world examples of reentrancy are more likely to involve multiple
- functions calling each other and hence be far more complicated than this
- example.</p>
- <p>Note also that being reentrant is <em>not</em> the same thing as being thread safe.
- <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 it
- makes 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>
- to a different stream.</p>
- </section>
- <section id="reusable-context-managers">
- <span id="reusable-cms"></span><h3>Reusable context managers<a class="headerlink" href="#reusable-context-managers" title="Link to this heading">¶</a></h3>
- <p>Distinct from both single use and reentrant context managers are “reusable”
- context managers (or, to be completely explicit, “reusable, but not
- reentrant” context managers, since reentrant context managers are also
- reusable). These context managers support being used multiple times, but
- will fail (or otherwise not work correctly) if the specific context manager
- instance has already been used in a containing with statement.</p>
- <p><a class="reference internal" href="threading.html#threading.Lock" title="threading.Lock"><code class="xref py py-class docutils literal notranslate"><span class="pre">threading.Lock</span></code></a> is an example of a reusable, but not reentrant,
- context manager (for a reentrant lock, it is necessary to use
- <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> instead).</p>
- <p>Another example of a reusable, but not reentrant, context manager is
- <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>, as it invokes <em>all</em> currently registered callbacks
- when leaving any with statement, regardless of where those callbacks
- were added:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">ExitStack</span>
- <span class="gp">>>> </span><span class="n">stack</span> <span class="o">=</span> <span class="n">ExitStack</span><span class="p">()</span>
- <span class="gp">>>> </span><span class="k">with</span> <span class="n">stack</span><span class="p">:</span>
- <span class="gp">... </span> <span class="n">stack</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="nb">print</span><span class="p">,</span> <span class="s2">"Callback: from first context"</span><span class="p">)</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Leaving first context"</span><span class="p">)</span>
- <span class="gp">...</span>
- <span class="go">Leaving first context</span>
- <span class="go">Callback: from first context</span>
- <span class="gp">>>> </span><span class="k">with</span> <span class="n">stack</span><span class="p">:</span>
- <span class="gp">... </span> <span class="n">stack</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="nb">print</span><span class="p">,</span> <span class="s2">"Callback: from second context"</span><span class="p">)</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Leaving second context"</span><span class="p">)</span>
- <span class="gp">...</span>
- <span class="go">Leaving second context</span>
- <span class="go">Callback: from second context</span>
- <span class="gp">>>> </span><span class="k">with</span> <span class="n">stack</span><span class="p">:</span>
- <span class="gp">... </span> <span class="n">stack</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="nb">print</span><span class="p">,</span> <span class="s2">"Callback: from outer context"</span><span class="p">)</span>
- <span class="gp">... </span> <span class="k">with</span> <span class="n">stack</span><span class="p">:</span>
- <span class="gp">... </span> <span class="n">stack</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="nb">print</span><span class="p">,</span> <span class="s2">"Callback: from inner context"</span><span class="p">)</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Leaving inner context"</span><span class="p">)</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Leaving outer context"</span><span class="p">)</span>
- <span class="gp">...</span>
- <span class="go">Leaving inner context</span>
- <span class="go">Callback: from inner context</span>
- <span class="go">Callback: from outer context</span>
- <span class="go">Leaving outer context</span>
- </pre></div>
- </div>
- <p>As the output from the example shows, reusing a single stack object across
- multiple with statements works correctly, but attempting to nest them
- will cause the stack to be cleared at the end of the innermost with
- statement, which is unlikely to be desirable behaviour.</p>
- <p>Using separate <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> instances instead of reusing a single
- instance avoids that problem:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">ExitStack</span>
- <span class="gp">>>> </span><span class="k">with</span> <span class="n">ExitStack</span><span class="p">()</span> <span class="k">as</span> <span class="n">outer_stack</span><span class="p">:</span>
- <span class="gp">... </span> <span class="n">outer_stack</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="nb">print</span><span class="p">,</span> <span class="s2">"Callback: from outer context"</span><span class="p">)</span>
- <span class="gp">... </span> <span class="k">with</span> <span class="n">ExitStack</span><span class="p">()</span> <span class="k">as</span> <span class="n">inner_stack</span><span class="p">:</span>
- <span class="gp">... </span> <span class="n">inner_stack</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="nb">print</span><span class="p">,</span> <span class="s2">"Callback: from inner context"</span><span class="p">)</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Leaving inner context"</span><span class="p">)</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Leaving outer context"</span><span class="p">)</span>
- <span class="gp">...</span>
- <span class="go">Leaving inner context</span>
- <span class="go">Callback: from inner context</span>
- <span class="go">Leaving outer context</span>
- <span class="go">Callback: from outer context</span>
- </pre></div>
- </div>
- </section>
- </section>
- </section>
-
-
- <div class="clearer"></div>
- </div>
- </div>
- </div>
- <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
- <div>
- <h3><a href="../contents.html">Table of Contents</a></h3>
- <ul>
- <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>
- <li><a class="reference internal" href="#utilities">Utilities</a></li>
- <li><a class="reference internal" href="#examples-and-recipes">Examples and Recipes</a><ul>
- <li><a class="reference internal" href="#supporting-a-variable-number-of-context-managers">Supporting a variable number of context managers</a></li>
- <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>
- <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>
- <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>
- <li><a class="reference internal" href="#using-a-context-manager-as-a-function-decorator">Using a context manager as a function decorator</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#single-use-reusable-and-reentrant-context-managers">Single use, reusable and reentrant context managers</a><ul>
- <li><a class="reference internal" href="#reentrant-context-managers">Reentrant context managers</a></li>
- <li><a class="reference internal" href="#reusable-context-managers">Reusable context managers</a></li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
-
- </div>
- <div>
- <h4>Previous topic</h4>
- <p class="topless"><a href="dataclasses.html"
- title="previous chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">dataclasses</span></code> — Data Classes</a></p>
- </div>
- <div>
- <h4>Next topic</h4>
- <p class="topless"><a href="abc.html"
- title="next chapter"><code class="xref py py-mod docutils literal notranslate"><span class="pre">abc</span></code> — Abstract Base Classes</a></p>
- </div>
- <div role="note" aria-label="source link">
- <h3>This Page</h3>
- <ul class="this-page-menu">
- <li><a href="../bugs.html">Report a Bug</a></li>
- <li>
- <a href="https://github.com/python/cpython/blob/main/Doc/library/contextlib.rst"
- rel="nofollow">Show Source
- </a>
- </li>
- </ul>
- </div>
- </div>
- <div id="sidebarbutton" title="Collapse sidebar">
- <span>«</span>
- </div>
-
- </div>
- <div class="clearer"></div>
- </div>
- <div class="related" role="navigation" aria-label="related navigation">
- <h3>Navigation</h3>
- <ul>
- <li class="right" style="margin-right: 10px">
- <a href="../genindex.html" title="General Index"
- >index</a></li>
- <li class="right" >
- <a href="../py-modindex.html" title="Python Module Index"
- >modules</a> |</li>
- <li class="right" >
- <a href="abc.html" title="abc — Abstract Base Classes"
- >next</a> |</li>
- <li class="right" >
- <a href="dataclasses.html" title="dataclasses — Data Classes"
- >previous</a> |</li>
-
- <li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
- <li><a href="https://www.python.org/">Python</a> »</li>
- <li class="switchers">
- <div class="language_switcher_placeholder"></div>
- <div class="version_switcher_placeholder"></div>
- </li>
- <li>
-
- </li>
- <li id="cpython-language-and-version">
- <a href="../index.html">3.12.3 Documentation</a> »
- </li>
-
- <li class="nav-item nav-item-1"><a href="index.html" >The Python Standard Library</a> »</li>
- <li class="nav-item nav-item-2"><a href="python.html" >Python Runtime Services</a> »</li>
- <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>
- <li class="right">
-
-
- <div class="inline-search" role="search">
- <form class="inline-search" action="../search.html" method="get">
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
- <input type="submit" value="Go" />
- </form>
- </div>
- |
- </li>
- <li class="right">
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label> |</li>
-
- </ul>
- </div>
- <div class="footer">
- ©
- <a href="../copyright.html">
-
- Copyright
-
- </a>
- 2001-2024, Python Software Foundation.
- <br />
- This page is licensed under the Python Software Foundation License Version 2.
- <br />
- Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
- <br />
-
- See <a href="/license.html">History and License</a> for more information.<br />
-
-
- <br />
-
- The Python Software Foundation is a non-profit corporation.
- <a href="https://www.python.org/psf/donations/">Please donate.</a>
- <br />
- <br />
- Last updated on Apr 09, 2024 (13:47 UTC).
-
- <a href="/bugs.html">Found a bug</a>?
-
- <br />
-
- Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 7.2.6.
- </div>
-
- </body>
- </html>
|