478 lines
38 KiB
HTML
478 lines
38 KiB
HTML
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="color-scheme" content="light dark">
|
||
<title>PEP 565 – Show DeprecationWarning in __main__ | peps.python.org</title>
|
||
<link rel="shortcut icon" href="../_static/py.png">
|
||
<link rel="canonical" href="https://peps.python.org/pep-0565/">
|
||
<link rel="stylesheet" href="../_static/style.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
|
||
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
|
||
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
|
||
<meta property="og:title" content='PEP 565 – Show DeprecationWarning in __main__ | peps.python.org'>
|
||
<meta property="og:description" content="In Python 2.7 and Python 3.2, the default warning filters were updated to hide DeprecationWarning by default, such that deprecation warnings in development tools that were themselves written in Python (e.g. linters, static analysers, test runners, code ...">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:url" content="https://peps.python.org/pep-0565/">
|
||
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
|
||
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
|
||
<meta property="og:image:alt" content="Python PEPs">
|
||
<meta property="og:image:width" content="200">
|
||
<meta property="og:image:height" content="200">
|
||
<meta name="description" content="In Python 2.7 and Python 3.2, the default warning filters were updated to hide DeprecationWarning by default, such that deprecation warnings in development tools that were themselves written in Python (e.g. linters, static analysers, test runners, code ...">
|
||
<meta name="theme-color" content="#3776ab">
|
||
</head>
|
||
<body>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Following system colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="9"></circle>
|
||
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected dark colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected light colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="5"></circle>
|
||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||
</svg>
|
||
</symbol>
|
||
</svg>
|
||
<script>
|
||
|
||
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
|
||
</script>
|
||
<section id="pep-page-section">
|
||
<header>
|
||
<h1>Python Enhancement Proposals</h1>
|
||
<ul class="breadcrumbs">
|
||
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> » </li>
|
||
<li><a href="../pep-0000/">PEP Index</a> » </li>
|
||
<li>PEP 565</li>
|
||
</ul>
|
||
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
|
||
</button>
|
||
</header>
|
||
<article>
|
||
<section id="pep-content">
|
||
<h1 class="page-title">PEP 565 – Show DeprecationWarning in __main__</h1>
|
||
<dl class="rfc2822 field-list simple">
|
||
<dt class="field-odd">Author<span class="colon">:</span></dt>
|
||
<dd class="field-odd">Alyssa Coghlan <ncoghlan at gmail.com></dd>
|
||
<dt class="field-even">Status<span class="colon">:</span></dt>
|
||
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
|
||
<dt class="field-odd">Type<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
|
||
<dt class="field-even">Created<span class="colon">:</span></dt>
|
||
<dd class="field-even">12-Nov-2017</dd>
|
||
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
|
||
<dd class="field-odd">3.7</dd>
|
||
<dt class="field-even">Post-History<span class="colon">:</span></dt>
|
||
<dd class="field-even">12-Nov-2017, 25-Nov-2017</dd>
|
||
<dt class="field-odd">Resolution<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2017-December/151224.html">Python-Dev message</a></dd>
|
||
</dl>
|
||
<hr class="docutils" />
|
||
<section id="contents">
|
||
<details><summary>Table of Contents</summary><ul class="simple">
|
||
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
||
<li><a class="reference internal" href="#specification">Specification</a><ul>
|
||
<li><a class="reference internal" href="#new-default-warnings-filter-entry">New default warnings filter entry</a></li>
|
||
<li><a class="reference internal" href="#additional-use-case-for-futurewarning">Additional use case for <code class="docutils literal notranslate"><span class="pre">FutureWarning</span></code></a></li>
|
||
<li><a class="reference internal" href="#recommended-filter-settings-for-test-runners">Recommended filter settings for test runners</a></li>
|
||
<li><a class="reference internal" href="#recommended-filter-settings-for-interactive-shells">Recommended filter settings for interactive shells</a></li>
|
||
<li><a class="reference internal" href="#other-documentation-updates">Other documentation updates</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
|
||
<li><a class="reference internal" href="#motivation">Motivation</a></li>
|
||
<li><a class="reference internal" href="#limitations-on-pep-scope">Limitations on PEP Scope</a></li>
|
||
<li><a class="reference internal" href="#references">References</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
</details></section>
|
||
<section id="abstract">
|
||
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
|
||
<p>In Python 2.7 and Python 3.2, the default warning filters were updated to hide
|
||
<code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code> by default, such that deprecation warnings in development
|
||
tools that were themselves written in Python (e.g. linters, static analysers,
|
||
test runners, code generators), as well as any other applications that merely
|
||
happened to be written in Python, wouldn’t be visible to their users unless
|
||
those users explicitly opted in to seeing them.</p>
|
||
<p>However, this change has had the unfortunate side effect of making
|
||
<code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code> markedly less effective at its primary intended purpose:
|
||
providing advance notice of breaking changes in APIs (whether in CPython, the
|
||
standard library, or in third party libraries) to users of those APIs.</p>
|
||
<p>To improve this situation, this PEP proposes a single adjustment to the
|
||
default warnings filter: displaying deprecation warnings attributed to the main
|
||
module by default.</p>
|
||
<p>This change will mean that code entered at the interactive prompt and code in
|
||
single file scripts will revert to reporting these warnings by default, while
|
||
they will continue to be silenced by default for packaged code distributed as
|
||
part of an importable module.</p>
|
||
<p>The PEP also proposes a number of small adjustments to the reference
|
||
interpreter and standard library documentation to help make the warnings
|
||
subsystem more approachable for new Python developers.</p>
|
||
<p>As part of the documentation updates, it will be made clearer that the
|
||
<code class="docutils literal notranslate"><span class="pre">unittest</span></code> test runner displays all warnings by default when executing
|
||
test cases, and that other test runners are advised to follow that example.</p>
|
||
</section>
|
||
<section id="specification">
|
||
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
|
||
<section id="new-default-warnings-filter-entry">
|
||
<h3><a class="toc-backref" href="#new-default-warnings-filter-entry" role="doc-backlink">New default warnings filter entry</a></h3>
|
||
<p>The current set of default warnings filters consists of:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ignore</span><span class="p">::</span><span class="ne">DeprecationWarning</span>
|
||
<span class="n">ignore</span><span class="p">::</span><span class="ne">PendingDeprecationWarning</span>
|
||
<span class="n">ignore</span><span class="p">::</span><span class="ne">ImportWarning</span>
|
||
<span class="n">ignore</span><span class="p">::</span><span class="ne">BytesWarning</span>
|
||
<span class="n">ignore</span><span class="p">::</span><span class="ne">ResourceWarning</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The default <code class="docutils literal notranslate"><span class="pre">unittest</span></code> test runner then uses <code class="docutils literal notranslate"><span class="pre">warnings.catch_warnings()</span></code>
|
||
<code class="docutils literal notranslate"><span class="pre">warnings.simplefilter('default')</span></code> to override the default filters while
|
||
running test cases.</p>
|
||
<p>The change proposed in this PEP is to update the default warning filter list
|
||
to be:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">default</span><span class="p">::</span><span class="ne">DeprecationWarning</span><span class="p">:</span><span class="n">__main__</span>
|
||
<span class="n">ignore</span><span class="p">::</span><span class="ne">DeprecationWarning</span>
|
||
<span class="n">ignore</span><span class="p">::</span><span class="ne">PendingDeprecationWarning</span>
|
||
<span class="n">ignore</span><span class="p">::</span><span class="ne">ImportWarning</span>
|
||
<span class="n">ignore</span><span class="p">::</span><span class="ne">BytesWarning</span>
|
||
<span class="n">ignore</span><span class="p">::</span><span class="ne">ResourceWarning</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This means that in cases where the nominal location of the warning (as
|
||
determined by the <code class="docutils literal notranslate"><span class="pre">stacklevel</span></code> parameter to <code class="docutils literal notranslate"><span class="pre">warnings.warn</span></code>) is in the
|
||
<code class="docutils literal notranslate"><span class="pre">__main__</span></code> module, the first occurrence of each <code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code> will once
|
||
again be reported.</p>
|
||
<p>This change will lead to <code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code> being displayed by default for:</p>
|
||
<ul class="simple">
|
||
<li>code executed directly at the interactive prompt</li>
|
||
<li>code executed directly as part of a single-file script</li>
|
||
</ul>
|
||
<p>While continuing to be hidden by default for:</p>
|
||
<ul class="simple">
|
||
<li>code imported from another module in a <code class="docutils literal notranslate"><span class="pre">zipapp</span></code> archive’s <code class="docutils literal notranslate"><span class="pre">__main__.py</span></code>
|
||
file</li>
|
||
<li>code imported from another module in an executable package’s <code class="docutils literal notranslate"><span class="pre">__main__</span></code>
|
||
submodule</li>
|
||
<li>code imported from an executable script wrapper generated at installation time
|
||
based on a <code class="docutils literal notranslate"><span class="pre">console_scripts</span></code> or <code class="docutils literal notranslate"><span class="pre">gui_scripts</span></code> entry point definition</li>
|
||
</ul>
|
||
<p>This means that tool developers that create an installable or executable
|
||
artifact (such as a <code class="docutils literal notranslate"><span class="pre">zipapp</span></code> archive) for distribution to their users
|
||
shouldn’t see any change from the status quo, while users of more ad hoc
|
||
personal or locally distributed scripts are likely to start seeing relevant
|
||
deprecation warnings again (as they did in Python 2.6 and earlier).</p>
|
||
</section>
|
||
<section id="additional-use-case-for-futurewarning">
|
||
<h3><a class="toc-backref" href="#additional-use-case-for-futurewarning" role="doc-backlink">Additional use case for <code class="docutils literal notranslate"><span class="pre">FutureWarning</span></code></a></h3>
|
||
<p>The standard library documentation will be updated to explicitly recommend the
|
||
use of <code class="docutils literal notranslate"><span class="pre">FutureWarning</span></code> (rather than <code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code>) for backwards
|
||
compatibility warnings that are intended to be seen by <em>users</em> of an
|
||
application. (This will be in addition to the existing use of <code class="docutils literal notranslate"><span class="pre">FutureWarning</span></code>
|
||
to warn about constructs that will remain valid code in the future,
|
||
but will have different semantics).</p>
|
||
<p>This will give the following three distinct categories of backwards
|
||
compatibility warning, with three different intended audiences:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">PendingDeprecationWarning</span></code>: hidden by default for all code.
|
||
The intended audience is Python developers that take an active interest in
|
||
ensuring the future compatibility of their software (e.g. professional
|
||
Python application developers with specific support obligations).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code>: reported by default for code that runs directly in
|
||
the <code class="docutils literal notranslate"><span class="pre">__main__</span></code> module (as such code is considered relatively unlikely to
|
||
have a dedicated test suite), but hidden by default for code in other modules.
|
||
The intended audience is Python developers that are at risk of upgrades to
|
||
their dependencies (including upgrades to Python itself) breaking their
|
||
software (e.g. developers using Python to script environments where someone
|
||
else is in control of the timing of dependency upgrades).</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">FutureWarning</span></code>: reported by default for all code.
|
||
The intended audience is users of applications written in Python, rather than
|
||
other Python developers (e.g. warning about use of a deprecated setting in a
|
||
configuration file format).</li>
|
||
</ul>
|
||
<p>For library and framework authors that want to ensure their API compatibility
|
||
warnings are more reliably seen by their users, the recommendation is to use a
|
||
custom warning class that derives from <code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code> in Python 3.7+,
|
||
and from <code class="docutils literal notranslate"><span class="pre">FutureWarning</span></code> in earlier versions.</p>
|
||
</section>
|
||
<section id="recommended-filter-settings-for-test-runners">
|
||
<h3><a class="toc-backref" href="#recommended-filter-settings-for-test-runners" role="doc-backlink">Recommended filter settings for test runners</a></h3>
|
||
<p>Developers of test runners are advised to implement logic equivalent to the
|
||
following when determining their default warnings filters:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="ow">not</span> <span class="n">sys</span><span class="o">.</span><span class="n">warnoptions</span><span class="p">:</span>
|
||
<span class="n">warnings</span><span class="o">.</span><span class="n">simplefilter</span><span class="p">(</span><span class="s2">"default"</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This effectively enables all warnings by default, as if the <code class="docutils literal notranslate"><span class="pre">-Wd</span></code> command
|
||
line option had been passed.</p>
|
||
<p>Note that actually enabling <code class="docutils literal notranslate"><span class="pre">BytesWarning</span></code> in a test suite still requires
|
||
passing the <code class="docutils literal notranslate"><span class="pre">-b</span></code> option to the interpreter at the command line. For implicit
|
||
bytes conversion and bytes comparison warnings, the warnings filter machinery
|
||
is only used to determine whether they should be printed as warnings or raised
|
||
as exceptions - when the command line flag isn’t set, the interpreter doesn’t
|
||
even emit the warning in the first place.</p>
|
||
</section>
|
||
<section id="recommended-filter-settings-for-interactive-shells">
|
||
<h3><a class="toc-backref" href="#recommended-filter-settings-for-interactive-shells" role="doc-backlink">Recommended filter settings for interactive shells</a></h3>
|
||
<p>Developers of interactive shells are advised to add a filter that enables
|
||
<code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code> in the namespace where user code is entered and executed.</p>
|
||
<p>If that namespace is <code class="docutils literal notranslate"><span class="pre">__main__</span></code> (as it is for the default CPython REPL), then
|
||
no changes are needed beyond those in this PEP.</p>
|
||
<p>Interactive shell implementations which use a namespace other than
|
||
<code class="docutils literal notranslate"><span class="pre">__main__</span></code> will need to add their own filter. For example, IPython uses the
|
||
following command (<a class="footnote-reference brackets" href="#id13" id="id1">[6]</a>) to set up a suitable filter:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">warnings</span><span class="o">.</span><span class="n">filterwarnings</span><span class="p">(</span><span class="s2">"default"</span><span class="p">,</span> <span class="n">category</span><span class="o">=</span><span class="ne">DeprecationWarning</span><span class="p">,</span>
|
||
<span class="n">module</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">user_ns</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"__name__"</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="other-documentation-updates">
|
||
<h3><a class="toc-backref" href="#other-documentation-updates" role="doc-backlink">Other documentation updates</a></h3>
|
||
<p>The current reference documentation for the warnings system is relatively short
|
||
on specific <em>examples</em> of possible settings for the <code class="docutils literal notranslate"><span class="pre">-W</span></code> command line option
|
||
or the <code class="docutils literal notranslate"><span class="pre">PYTHONWARNINGS</span></code> environment variably that achieve particular end
|
||
results.</p>
|
||
<p>The following improvements are proposed as part of the implementation of this
|
||
PEP:</p>
|
||
<ul>
|
||
<li>Explicitly list the following entries under the description of the
|
||
<code class="docutils literal notranslate"><span class="pre">PYTHONWARNINGS</span></code> environment variable:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">PYTHONWARNINGS</span><span class="o">=</span><span class="n">error</span> <span class="c1"># Convert to exceptions</span>
|
||
<span class="n">PYTHONWARNINGS</span><span class="o">=</span><span class="n">always</span> <span class="c1"># Warn every time</span>
|
||
<span class="n">PYTHONWARNINGS</span><span class="o">=</span><span class="n">default</span> <span class="c1"># Warn once per call location</span>
|
||
<span class="n">PYTHONWARNINGS</span><span class="o">=</span><span class="n">module</span> <span class="c1"># Warn once per calling module</span>
|
||
<span class="n">PYTHONWARNINGS</span><span class="o">=</span><span class="n">once</span> <span class="c1"># Warn once per Python process</span>
|
||
<span class="n">PYTHONWARNINGS</span><span class="o">=</span><span class="n">ignore</span> <span class="c1"># Never warn</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li>Explicitly list the corresponding short options
|
||
(<code class="docutils literal notranslate"><span class="pre">-We</span></code>, <code class="docutils literal notranslate"><span class="pre">-Wa</span></code>, <code class="docutils literal notranslate"><span class="pre">-Wd</span></code>, <code class="docutils literal notranslate"><span class="pre">-Wm</span></code>, <code class="docutils literal notranslate"><span class="pre">-Wo</span></code>, <code class="docutils literal notranslate"><span class="pre">-Wi</span></code>) for each of the
|
||
warning actions listed under the <code class="docutils literal notranslate"><span class="pre">-W</span></code> command line switch documentation</li>
|
||
<li>Explicitly list the default filter set in the <code class="docutils literal notranslate"><span class="pre">warnings</span></code> module
|
||
documentation, using the <code class="docutils literal notranslate"><span class="pre">action::category</span></code> and <code class="docutils literal notranslate"><span class="pre">action::category:module</span></code>
|
||
notation</li>
|
||
<li>Explicitly list the following snippet in the <code class="docutils literal notranslate"><span class="pre">warnings.simplefilter</span></code>
|
||
documentation as a recommended approach to turning off all warnings by
|
||
default in a Python application while still allowing them to be turned
|
||
back on via <code class="docutils literal notranslate"><span class="pre">PYTHONWARNINGS</span></code> or the <code class="docutils literal notranslate"><span class="pre">-W</span></code> command line switch:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="ow">not</span> <span class="n">sys</span><span class="o">.</span><span class="n">warnoptions</span><span class="p">:</span>
|
||
<span class="n">warnings</span><span class="o">.</span><span class="n">simplefilter</span><span class="p">(</span><span class="s2">"ignore"</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
<p>None of these are <em>new</em> (they already work in all still supported Python
|
||
versions), but they’re not especially obvious given the current structure
|
||
of the related documentation.</p>
|
||
</section>
|
||
</section>
|
||
<section id="reference-implementation">
|
||
<h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2>
|
||
<p>A reference implementation is available in the PR <a class="footnote-reference brackets" href="#id11" id="id2">[4]</a> linked from the
|
||
related tracker issue for this PEP <a class="footnote-reference brackets" href="#id12" id="id3">[5]</a>.</p>
|
||
<p>As a side-effect of implementing this PEP, the internal warnings filter list
|
||
will start allowing the use of plain strings as part of filter definitions (in
|
||
addition to the existing use of compiled regular expressions). When present,
|
||
the plain strings will be compared for exact matches only. This approach allows
|
||
the new default filter to be added during interpreter startup without requiring
|
||
early access to the <code class="docutils literal notranslate"><span class="pre">re</span></code> module.</p>
|
||
</section>
|
||
<section id="motivation">
|
||
<h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2>
|
||
<p>As discussed in <a class="footnote-reference brackets" href="#id8" id="id4">[1]</a> and mentioned in <a class="footnote-reference brackets" href="#id9" id="id5">[2]</a>, Python 2.7 and Python 3.2 changed
|
||
the default handling of <code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code> such that:</p>
|
||
<ul class="simple">
|
||
<li>the warning was hidden by default during normal code execution</li>
|
||
<li>the <code class="docutils literal notranslate"><span class="pre">unittest</span></code> test runner was updated to re-enable it when running tests</li>
|
||
</ul>
|
||
<p>The intent was to avoid cases of tooling output like the following:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ devtool mycode/
|
||
/usr/lib/python3.6/site-packages/devtool/cli.py:1: DeprecationWarning: 'async' and 'await' will become reserved keywords in Python 3.7
|
||
async = True
|
||
... actual tool output ...
|
||
</pre></div>
|
||
</div>
|
||
<p>Even when <code class="docutils literal notranslate"><span class="pre">devtool</span></code> is a tool specifically for Python programmers, this is not
|
||
a particularly useful warning, as it will be shown on every invocation, even
|
||
though the main helpful step an end user can take is to report a bug to the
|
||
developers of <code class="docutils literal notranslate"><span class="pre">devtool</span></code>.</p>
|
||
<p>The warning is even less helpful for general purpose developer tools that are
|
||
used across more languages than just Python, and almost entirely *un*helpful
|
||
for applications that simply happen to be written in Python, and aren’t
|
||
necessarily intended for a developer audience at all.</p>
|
||
<p>However, this change proved to have unintended consequences for the following
|
||
audiences:</p>
|
||
<ul class="simple">
|
||
<li>anyone using a test runner other than the default one built into <code class="docutils literal notranslate"><span class="pre">unittest</span></code>
|
||
(the request for third party test runners to change their default warnings
|
||
filters was never made explicitly, so many of them still rely on the
|
||
interpreter defaults that are designed to suit deployed applications)</li>
|
||
<li>anyone using the default <code class="docutils literal notranslate"><span class="pre">unittest</span></code> test runner to test their Python code
|
||
in a subprocess (since even <code class="docutils literal notranslate"><span class="pre">unittest</span></code> only adjusts the warnings settings
|
||
in the current process)</li>
|
||
<li>anyone writing Python code at the interactive prompt or as part of a directly
|
||
executed script that didn’t have a Python level test suite at all</li>
|
||
</ul>
|
||
<p>In these cases, <code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code> ended up become almost entirely
|
||
equivalent to <code class="docutils literal notranslate"><span class="pre">PendingDeprecationWarning</span></code>: it was simply never seen at all.</p>
|
||
</section>
|
||
<section id="limitations-on-pep-scope">
|
||
<h2><a class="toc-backref" href="#limitations-on-pep-scope" role="doc-backlink">Limitations on PEP Scope</a></h2>
|
||
<p>This PEP exists specifically to explain both the proposed addition to the
|
||
default warnings filter for 3.7, <em>and</em> to more clearly articulate the rationale
|
||
for the original change to the handling of <code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code> back in Python 2.7
|
||
and 3.2.</p>
|
||
<p>This PEP does not solve all known problems with the current approach to handling
|
||
deprecation warnings. Most notably:</p>
|
||
<ul class="simple">
|
||
<li>The default <code class="docutils literal notranslate"><span class="pre">unittest</span></code> test runner does not currently report deprecation
|
||
warnings emitted at module import time, as the warnings filter override is only
|
||
put in place during test execution, not during test discovery and loading.</li>
|
||
<li>The default <code class="docutils literal notranslate"><span class="pre">unittest</span></code> test runner does not currently report deprecation
|
||
warnings in subprocesses, as the warnings filter override is applied directly
|
||
to the loaded <code class="docutils literal notranslate"><span class="pre">warnings</span></code> module, not to the <code class="docutils literal notranslate"><span class="pre">PYTHONWARNINGS</span></code> environment
|
||
variable.</li>
|
||
<li>The standard library doesn’t provide a straightforward way to opt-in to seeing
|
||
all warnings emitted <em>by</em> a particular dependency prior to upgrading it
|
||
(the third-party <code class="docutils literal notranslate"><span class="pre">warn</span></code> module <a class="footnote-reference brackets" href="#id10" id="id6">[3]</a> does provide this, but enabling it
|
||
involves monkeypatching the standard library’s <code class="docutils literal notranslate"><span class="pre">warnings</span></code> module).</li>
|
||
<li>When software has been factored out into support modules, but those modules
|
||
have little or no automated test coverage, re-enabling deprecation warnings
|
||
by default in <code class="docutils literal notranslate"><span class="pre">__main__</span></code> isn’t likely to help find API compatibility
|
||
problems. Near term, the best currently available answer is to run affected
|
||
applications with <code class="docutils literal notranslate"><span class="pre">PYTHONWARNINGS=default::DeprecationWarning</span></code> or
|
||
<code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">-W</span> <span class="pre">default::DeprecationWarning</span></code> and pay attention to their
|
||
<code class="docutils literal notranslate"><span class="pre">stderr</span></code> output. Longer term, this is really a question for researchers
|
||
working on static analysis of Python code: how to reliably find usage of
|
||
deprecated APIs, and how to infer that an API or parameter is deprecated
|
||
based on <code class="docutils literal notranslate"><span class="pre">warnings.warn</span></code> calls, without actually running either the code
|
||
providing the API or the code accessing it.</li>
|
||
</ul>
|
||
<p>While these are real problems with the status quo, they’re excluded from
|
||
consideration in this PEP because they’re going to require more complex
|
||
solutions than a single additional entry in the default warnings filter,
|
||
and resolving them at least potentially won’t require going through the PEP
|
||
process.</p>
|
||
<p>For anyone interested in pursuing them further, the first two would be
|
||
<code class="docutils literal notranslate"><span class="pre">unittest</span></code> module enhancement requests, the third would be a <code class="docutils literal notranslate"><span class="pre">warnings</span></code>
|
||
module enhancement request, while the last would only require a PEP if
|
||
inferring API deprecations from their contents was deemed to be an intractable
|
||
code analysis problem, and an explicit function and parameter marker syntax in
|
||
annotations was proposed instead.</p>
|
||
<p>The CPython reference implementation will also include the following related
|
||
changes in 3.7:</p>
|
||
<ul class="simple">
|
||
<li>a new <code class="docutils literal notranslate"><span class="pre">-X</span> <span class="pre">dev</span></code> command line option that combines several developer centric
|
||
settings (including <code class="docutils literal notranslate"><span class="pre">-Wd</span></code>) into one command line flag:
|
||
<a class="reference external" href="https://github.com/python/cpython/issues/76224">https://github.com/python/cpython/issues/76224</a></li>
|
||
<li>changing the behaviour in debug builds to show more of the warnings that are
|
||
off by default in regular interpreter builds: <a class="reference external" href="https://github.com/python/cpython/issues/76269">https://github.com/python/cpython/issues/76269</a></li>
|
||
</ul>
|
||
<p>Independently of the proposed changes to the default filters in this PEP,
|
||
issue 32229 <a class="footnote-reference brackets" href="#id14" id="id7">[7]</a> is a proposal to add a <code class="docutils literal notranslate"><span class="pre">warnings.hide_warnings</span></code> API to
|
||
make it simpler for application developers to hide warnings during normal
|
||
operation, while easily making them visible when testing.</p>
|
||
</section>
|
||
<section id="references">
|
||
<h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2>
|
||
<aside class="footnote-list brackets">
|
||
<aside class="footnote brackets" id="id8" role="doc-footnote">
|
||
<dt class="label" id="id8">[<a href="#id4">1</a>]</dt>
|
||
<dd>stdlib-sig thread proposing the original default filter change
|
||
(<a class="reference external" href="https://mail.python.org/pipermail/stdlib-sig/2009-November/000789.html">https://mail.python.org/pipermail/stdlib-sig/2009-November/000789.html</a>)</aside>
|
||
<aside class="footnote brackets" id="id9" role="doc-footnote">
|
||
<dt class="label" id="id9">[<a href="#id5">2</a>]</dt>
|
||
<dd>Python 2.7 notification of the default warnings filter change
|
||
(<a class="reference external" href="https://docs.python.org/3/whatsnew/2.7.html#changes-to-the-handling-of-deprecation-warnings">https://docs.python.org/3/whatsnew/2.7.html#changes-to-the-handling-of-deprecation-warnings</a>)</aside>
|
||
<aside class="footnote brackets" id="id10" role="doc-footnote">
|
||
<dt class="label" id="id10">[<a href="#id6">3</a>]</dt>
|
||
<dd>Emitting warnings based on the location of the warning itself
|
||
(<a class="reference external" href="https://pypi.org/project/warn/">https://pypi.org/project/warn/</a>)</aside>
|
||
<aside class="footnote brackets" id="id11" role="doc-footnote">
|
||
<dt class="label" id="id11">[<a href="#id2">4</a>]</dt>
|
||
<dd>GitHub PR for PEP 565 implementation
|
||
(<a class="reference external" href="https://github.com/python/cpython/pull/4458">https://github.com/python/cpython/pull/4458</a>)</aside>
|
||
<aside class="footnote brackets" id="id12" role="doc-footnote">
|
||
<dt class="label" id="id12">[<a href="#id3">5</a>]</dt>
|
||
<dd>Tracker issue for PEP 565 implementation
|
||
(<a class="reference external" href="https://github.com/python/cpython/issues/76156">https://github.com/python/cpython/issues/76156</a>)</aside>
|
||
<aside class="footnote brackets" id="id13" role="doc-footnote">
|
||
<dt class="label" id="id13">[<a href="#id1">6</a>]</dt>
|
||
<dd>IPython’s <code class="docutils literal notranslate"><span class="pre">DeprecationWarning</span></code> auto-configuration
|
||
(<a class="reference external" href="https://github.com/ipython/ipython/blob/6.2.x/IPython/core/interactiveshell.py#L619">https://github.com/ipython/ipython/blob/6.2.x/IPython/core/interactiveshell.py#L619</a>)</aside>
|
||
<aside class="footnote brackets" id="id14" role="doc-footnote">
|
||
<dt class="label" id="id14">[<a href="#id7">7</a>]</dt>
|
||
<dd><code class="docutils literal notranslate"><span class="pre">warnings.hide_warnings</span></code> API proposal
|
||
(<a class="reference external" href="https://github.com/python/cpython/issues/76410">https://github.com/python/cpython/issues/76410</a>)</aside>
|
||
</aside>
|
||
<ul class="simple">
|
||
<li><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2017-November/150477.html">First python-dev discussion thread</a></li>
|
||
<li><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2017-November/150819.html">Second python-dev discussion thread</a></li>
|
||
</ul>
|
||
</section>
|
||
<section id="copyright">
|
||
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
|
||
<p>This document has been placed in the public domain.</p>
|
||
</section>
|
||
</section>
|
||
<hr class="docutils" />
|
||
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0565.rst">https://github.com/python/peps/blob/main/peps/pep-0565.rst</a></p>
|
||
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0565.rst">2023-10-11 12:05:51 GMT</a></p>
|
||
|
||
</article>
|
||
<nav id="pep-sidebar">
|
||
<h2>Contents</h2>
|
||
<ul>
|
||
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
||
<li><a class="reference internal" href="#specification">Specification</a><ul>
|
||
<li><a class="reference internal" href="#new-default-warnings-filter-entry">New default warnings filter entry</a></li>
|
||
<li><a class="reference internal" href="#additional-use-case-for-futurewarning">Additional use case for <code class="docutils literal notranslate"><span class="pre">FutureWarning</span></code></a></li>
|
||
<li><a class="reference internal" href="#recommended-filter-settings-for-test-runners">Recommended filter settings for test runners</a></li>
|
||
<li><a class="reference internal" href="#recommended-filter-settings-for-interactive-shells">Recommended filter settings for interactive shells</a></li>
|
||
<li><a class="reference internal" href="#other-documentation-updates">Other documentation updates</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
|
||
<li><a class="reference internal" href="#motivation">Motivation</a></li>
|
||
<li><a class="reference internal" href="#limitations-on-pep-scope">Limitations on PEP Scope</a></li>
|
||
<li><a class="reference internal" href="#references">References</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
|
||
<br>
|
||
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0565.rst">Page Source (GitHub)</a>
|
||
</nav>
|
||
</section>
|
||
<script src="../_static/colour_scheme.js"></script>
|
||
<script src="../_static/wrap_tables.js"></script>
|
||
<script src="../_static/sticky_banner.js"></script>
|
||
</body>
|
||
</html> |