mirror of https://github.com/python/peps
477 lines
37 KiB
HTML
477 lines
37 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: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="Python Enhancement Proposals (PEPs)">
|
||
<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> |