481 lines
36 KiB
HTML
481 lines
36 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 534 – Improved Errors for Missing Standard Library Modules | peps.python.org</title>
|
||
<link rel="shortcut icon" href="../_static/py.png">
|
||
<link rel="canonical" href="https://peps.python.org/pep-0534/">
|
||
<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 534 – Improved Errors for Missing Standard Library Modules | peps.python.org'>
|
||
<meta property="og:description" content="Python is often being built or distributed without its full standard library. However, there is as of yet no standard, user friendly way of properly informing the user about the failure to import such missing standard library modules.">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:url" content="https://peps.python.org/pep-0534/">
|
||
<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 is often being built or distributed without its full standard library. However, there is as of yet no standard, user friendly way of properly informing the user about the failure to import such missing standard library modules.">
|
||
<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 534</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 534 – Improved Errors for Missing Standard Library Modules</h1>
|
||
<dl class="rfc2822 field-list simple">
|
||
<dt class="field-odd">Author<span class="colon">:</span></dt>
|
||
<dd class="field-odd">Tomáš Orsava <tomas.n at orsava.cz>,
|
||
Petr Viktorin <encukou at gmail.com>,
|
||
Alyssa Coghlan <ncoghlan at gmail.com></dd>
|
||
<dt class="field-even">Status<span class="colon">:</span></dt>
|
||
<dd class="field-even"><abbr title="Inactive draft that may be taken up again at a later time">Deferred</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">05-Sep-2016</dd>
|
||
<dt class="field-odd">Post-History<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><p></p></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="#pep-deferral">PEP Deferral</a></li>
|
||
<li><a class="reference internal" href="#motivation">Motivation</a><ul>
|
||
<li><a class="reference internal" href="#cpython">CPython</a></li>
|
||
<li><a class="reference internal" href="#linux-and-other-distributions">Linux and other distributions</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#specification">Specification</a><ul>
|
||
<li><a class="reference internal" href="#apis-to-list-expected-standard-library-modules">APIs to list expected standard library modules</a></li>
|
||
<li><a class="reference internal" href="#changes-to-the-default-sys-excepthook-implementation">Changes to the default <code class="docutils literal notranslate"><span class="pre">sys.excepthook</span></code> implementation</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#design-discussion">Design Discussion</a><ul>
|
||
<li><a class="reference internal" href="#modifying-sys-excepthook">Modifying <code class="docutils literal notranslate"><span class="pre">sys.excepthook</span></code></a></li>
|
||
<li><a class="reference internal" href="#public-api-to-query-expected-standard-library-module-names">Public API to query expected standard library module names</a></li>
|
||
<li><a class="reference internal" href="#only-including-top-level-module-names">Only including top level module names</a></li>
|
||
<li><a class="reference internal" href="#listing-private-top-level-module-names-as-optional-standard-library-modules">Listing private top level module names as optional standard library modules</a></li>
|
||
<li><a class="reference internal" href="#deeming-packaging-related-modules-to-be-mandatory">Deeming packaging related modules to be mandatory</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#deferred-ideas">Deferred Ideas</a><ul>
|
||
<li><a class="reference internal" href="#platform-dependent-modules">Platform dependent modules</a></li>
|
||
<li><a class="reference internal" href="#emitting-a-warning-when-main-shadows-a-standard-library-module">Emitting a warning when <code class="docutils literal notranslate"><span class="pre">__main__</span></code> shadows a standard library module</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#recommendation-for-downstream-distributors">Recommendation for Downstream Distributors</a></li>
|
||
<li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li>
|
||
<li><a class="reference internal" href="#reference-and-example-implementation">Reference and Example Implementation</a></li>
|
||
<li><a class="reference internal" href="#notes-and-references">Notes and 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>Python is often being built or distributed without its full standard library.
|
||
However, there is as of yet no standard, user friendly way of properly
|
||
informing the user about the failure to import such missing standard library
|
||
modules.</p>
|
||
<p>This PEP proposes a mechanism for identifying expected standard library modules
|
||
and providing more informative error messages to users when attempts to import
|
||
standard library modules fail.</p>
|
||
</section>
|
||
<section id="pep-deferral">
|
||
<h2><a class="toc-backref" href="#pep-deferral" role="doc-backlink">PEP Deferral</a></h2>
|
||
<p>The PEP authors aren’t actively working on this PEP, so if improving these
|
||
error messages is an idea that you’re interested in pursuing, please get in
|
||
touch! (e.g. by posting to the python-dev mailing list).</p>
|
||
<p>The key piece of open work is determining how to get the autoconf and Visual
|
||
Studio build processes to populate the sysconfig metadata file with the lists
|
||
of expected and optional standard library modules.</p>
|
||
</section>
|
||
<section id="motivation">
|
||
<h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2>
|
||
<p>There are several use cases for including only a subset of Python’s standard
|
||
library. However, there is so far no user-friendly mechanism for informing
|
||
the user <em>why</em> a stdlib module is missing and how to remedy the situation
|
||
appropriately.</p>
|
||
<section id="cpython">
|
||
<h3><a class="toc-backref" href="#cpython" role="doc-backlink">CPython</a></h3>
|
||
<p>When one of Python’s standard library modules (such as <code class="docutils literal notranslate"><span class="pre">_sqlite3</span></code>) cannot be
|
||
compiled during a CPython build because of missing dependencies (e.g. SQLite
|
||
header files), the module is simply skipped. If you then install this compiled
|
||
Python and use it to try to import one of the missing modules, Python will fail
|
||
with a <a class="reference external" href="https://docs.python.org/3.7/library/exceptions.html#ModuleNotFoundError">ModuleNotFoundError</a>.</p>
|
||
<p>For example, after deliberately removing <code class="docutils literal notranslate"><span class="pre">sqlite-devel</span></code> from the local
|
||
system:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./python -c "import sqlite3"
|
||
Traceback (most recent call last):
|
||
File "<string>", line 1, in <module>
|
||
File "/home/ncoghlan/devel/cpython/Lib/sqlite3/__init__.py", line 23, in <module>
|
||
from sqlite3.dbapi2 import *
|
||
File "/home/ncoghlan/devel/cpython/Lib/sqlite3/dbapi2.py", line 27, in <module>
|
||
from _sqlite3 import *
|
||
ModuleNotFoundError: No module named '_sqlite3'
|
||
</pre></div>
|
||
</div>
|
||
<p>This can confuse users who may not understand why a cleanly built Python is
|
||
missing standard library modules.</p>
|
||
</section>
|
||
<section id="linux-and-other-distributions">
|
||
<h3><a class="toc-backref" href="#linux-and-other-distributions" role="doc-backlink">Linux and other distributions</a></h3>
|
||
<p>Many Linux and other distributions are already separating out parts of the
|
||
standard library to standalone packages. Among the most commonly excluded
|
||
modules are the <code class="docutils literal notranslate"><span class="pre">tkinter</span></code> module, since it draws in a dependency on the
|
||
graphical environment, <code class="docutils literal notranslate"><span class="pre">idlelib</span></code>, since it depends on <code class="docutils literal notranslate"><span class="pre">tkinter</span></code> (and most
|
||
Linux desktop environments provide their own default code editor), and the
|
||
<code class="docutils literal notranslate"><span class="pre">test</span></code> package, as it only serves to test Python internally and is about as
|
||
big as the rest of the standard library put together.</p>
|
||
<p>The methods of omission of these modules differ. For example, Debian patches
|
||
the file <code class="docutils literal notranslate"><span class="pre">Lib/tkinter/__init__.py</span></code> to envelop the line <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">_tkinter</span></code> in
|
||
a <em>try-except</em> block and upon encountering an <code class="docutils literal notranslate"><span class="pre">ImportError</span></code> it simply adds
|
||
the following to the error message: <code class="docutils literal notranslate"><span class="pre">please</span> <span class="pre">install</span> <span class="pre">the</span> <span class="pre">python3-tk</span> <span class="pre">package</span></code>
|
||
<a class="footnote-reference brackets" href="#debian-patch" id="id1">[1]</a>. Fedora and other distributions simply don’t include the
|
||
omitted modules, potentially leaving users baffled as to where to find them.</p>
|
||
<p>An example from Fedora 29:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ python3 -c "import tkinter"
|
||
Traceback (most recent call last):
|
||
File "<string>", line 1, in <module>
|
||
ModuleNotFoundError: No module named 'tkinter'
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
<section id="specification">
|
||
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
|
||
<section id="apis-to-list-expected-standard-library-modules">
|
||
<h3><a class="toc-backref" href="#apis-to-list-expected-standard-library-modules" role="doc-backlink">APIs to list expected standard library modules</a></h3>
|
||
<p>To allow for easier identification of which module names are <em>expected</em> to be
|
||
resolved in the standard library, the <a class="reference external" href="https://docs.python.org/3/library/sysconfig.html">sysconfig</a> module will be extended
|
||
with two additional functions:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">sysconfig.get_stdlib_modules()</span></code>, which will provide a list of the names of
|
||
all top level Python standard library modules (including private modules)</li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">sysconfig.get_optional_modules()</span></code>, which will list optional public top level
|
||
standard library module names</li>
|
||
</ul>
|
||
<p>The results of <code class="docutils literal notranslate"><span class="pre">sysconfig.get_optional_modules()</span></code> and the existing
|
||
<code class="docutils literal notranslate"><span class="pre">sys.builtin_module_names</span></code> will both be subsets of the full list provided by
|
||
the new <code class="docutils literal notranslate"><span class="pre">sysconfig.get_stdlib_modules()</span></code> function.</p>
|
||
<p>These added lists will be generated during the Python build process and saved in
|
||
the <code class="docutils literal notranslate"><span class="pre">_sysconfigdata-*.py</span></code> file along with other <a class="reference external" href="https://docs.python.org/3/library/sysconfig.html">sysconfig</a> values.</p>
|
||
<p>Possible reasons for modules being in the “optional” list will be:</p>
|
||
<ul class="simple">
|
||
<li>the module relies on an optional build dependency (e.g. <code class="docutils literal notranslate"><span class="pre">_sqlite3</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">tkinter</span></code>, <code class="docutils literal notranslate"><span class="pre">idlelib</span></code>)</li>
|
||
<li>the module is private for other reasons and hence may not be present on all
|
||
implementations (e.g. <code class="docutils literal notranslate"><span class="pre">_freeze_importlib</span></code>, <code class="docutils literal notranslate"><span class="pre">_collections_abc</span></code>)</li>
|
||
<li>the module is platform specific and hence may not be present in all
|
||
installations (e.g. <code class="docutils literal notranslate"><span class="pre">winreg</span></code>)</li>
|
||
<li>the <code class="docutils literal notranslate"><span class="pre">test</span></code> package may also be freely omitted from Python runtime
|
||
installations, as it is intended for use in testing Python implementations,
|
||
not as a runtime library for Python projects to use (the public API offering
|
||
testing utilities is <code class="docutils literal notranslate"><span class="pre">unittest</span></code>)</li>
|
||
</ul>
|
||
<p>(Note: the <code class="docutils literal notranslate"><span class="pre">ensurepip</span></code>, <code class="docutils literal notranslate"><span class="pre">venv</span></code>, and <code class="docutils literal notranslate"><span class="pre">distutils</span></code> modules are all considered
|
||
mandatory modules in this PEP, even though not all redistributors currently
|
||
adhere to that practice)</p>
|
||
</section>
|
||
<section id="changes-to-the-default-sys-excepthook-implementation">
|
||
<h3><a class="toc-backref" href="#changes-to-the-default-sys-excepthook-implementation" role="doc-backlink">Changes to the default <code class="docutils literal notranslate"><span class="pre">sys.excepthook</span></code> implementation</a></h3>
|
||
<p>The default implementation of the <a class="reference external" href="https://docs.python.org/3/library/sys.html#sys.excepthook">sys.excepthook</a> function will then be
|
||
modified to dispense an appropriate message when it detects a failure to
|
||
import a module identified by one of the two new <a class="reference external" href="https://docs.python.org/3/library/sysconfig.html">sysconfig</a> functions as
|
||
belonging to the Python standard library.</p>
|
||
<p>Revised error message for a module that relies on an optional build dependency
|
||
or is otherwise considered optional when Python is installed:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./python -c "import sqlite3"
|
||
Traceback (most recent call last):
|
||
File "<string>", line 1, in <module>
|
||
File "/home/ncoghlan/devel/cpython/Lib/sqlite3/__init__.py", line 23, in <module>
|
||
from sqlite3.dbapi2 import *
|
||
File "/home/ncoghlan/devel/cpython/Lib/sqlite3/dbapi2.py", line 27, in <module>
|
||
from _sqlite3 import *
|
||
ModuleNotFoundError: Optional standard library module '_sqlite3' was not found
|
||
</pre></div>
|
||
</div>
|
||
<p>Revised error message for a submodule of an optional top level package when the
|
||
entire top level package is missing:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./python -c "import test.regrtest"
|
||
Traceback (most recent call last):
|
||
File "<string>", line 1, in <module>
|
||
ModuleNotFoundError: Optional standard library module 'test' was not found
|
||
</pre></div>
|
||
</div>
|
||
<p>Revised error message for a submodule of an optional top level package when the
|
||
top level package is present:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./python -c "import test.regrtest"
|
||
Traceback (most recent call last):
|
||
File "<string>", line 1, in <module>
|
||
ModuleNotFoundError: No submodule named 'test.regrtest' in optional standard library module 'test'
|
||
</pre></div>
|
||
</div>
|
||
<p>Revised error message for a module that is always expected to be available:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./python -c "import ensurepip"
|
||
Traceback (most recent call last):
|
||
File "<string>", line 1, in <module>
|
||
ModuleNotFoundError: Standard library module 'ensurepip' was not found
|
||
</pre></div>
|
||
</div>
|
||
<p>Revised error message for a missing submodule of a standard library package when
|
||
the top level package is present:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./python -c "import encodings.mbcs"
|
||
Traceback (most recent call last):
|
||
File "<string>", line 1, in <module>
|
||
ModuleNotFoundError: No submodule named 'encodings.mbcs' in standard library module 'encodings'
|
||
</pre></div>
|
||
</div>
|
||
<p>These revised error messages make it clear that the missing modules are expected
|
||
to be available from the standard library, but are not available for some reason,
|
||
rather than being an indicator of a missing third party dependency in the current
|
||
environment.</p>
|
||
</section>
|
||
</section>
|
||
<section id="design-discussion">
|
||
<h2><a class="toc-backref" href="#design-discussion" role="doc-backlink">Design Discussion</a></h2>
|
||
<section id="modifying-sys-excepthook">
|
||
<h3><a class="toc-backref" href="#modifying-sys-excepthook" role="doc-backlink">Modifying <code class="docutils literal notranslate"><span class="pre">sys.excepthook</span></code></a></h3>
|
||
<p>The <a class="reference external" href="https://docs.python.org/3/library/sys.html#sys.excepthook">sys.excepthook</a> function gets called when a raised exception is uncaught
|
||
and the program is about to exit or (in an interactive session) the control is
|
||
being returned to the prompt. This makes it a perfect place for customized
|
||
error messages, as it will not influence caught errors and thus not slow down
|
||
normal execution of Python scripts.</p>
|
||
</section>
|
||
<section id="public-api-to-query-expected-standard-library-module-names">
|
||
<h3><a class="toc-backref" href="#public-api-to-query-expected-standard-library-module-names" role="doc-backlink">Public API to query expected standard library module names</a></h3>
|
||
<p>The inclusion of the functions <code class="docutils literal notranslate"><span class="pre">sysconfig.get_stdlib_modules()</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">sysconfig.get_optional_modules()</span></code> will provide a long sought-after
|
||
way of easily listing the names of Python standard library modules
|
||
<a class="footnote-reference brackets" href="#stackoverflow-stdlib" id="id2">[2]</a>, which will (among other benefits) make it easier for
|
||
code analysis, profiling, and error reporting tools to offer runtime
|
||
<code class="docutils literal notranslate"><span class="pre">--ignore-stdlib</span></code> flags.</p>
|
||
</section>
|
||
<section id="only-including-top-level-module-names">
|
||
<h3><a class="toc-backref" href="#only-including-top-level-module-names" role="doc-backlink">Only including top level module names</a></h3>
|
||
<p>This PEP proposes that only top level module and package names be reported by
|
||
the new query APIs. This is sufficient information to generate the proposed
|
||
error messages, reduces the number of required entries by an order of magnitude,
|
||
and simplifies the process of generating the related metadata during the build
|
||
process.</p>
|
||
<p>If this is eventually found to be overly limiting, a new <code class="docutils literal notranslate"><span class="pre">include_submodules</span></code>
|
||
flag could be added to the query APIs. However, this is <em>not</em> part of the initial
|
||
proposal, as the benefits of doing so aren’t currently seen as justifying the
|
||
extra complexity.</p>
|
||
<p>There is one known consequence of this restriction, which is that the new
|
||
default <code class="docutils literal notranslate"><span class="pre">excepthook</span></code> implementation will report incorrect submodules names the
|
||
same way that it reports genuinely missing standard library submodules:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./python -c "import unittest.muck"
|
||
Traceback (most recent call last):
|
||
File "<string>", line 1, in <module>
|
||
ModuleNotFoundError: No submodule named 'unittest.muck' in standard library module 'unittest'
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="listing-private-top-level-module-names-as-optional-standard-library-modules">
|
||
<h3><a class="toc-backref" href="#listing-private-top-level-module-names-as-optional-standard-library-modules" role="doc-backlink">Listing private top level module names as optional standard library modules</a></h3>
|
||
<p>Many of the modules that have an optional external build dependency are written
|
||
as hybrid modules, where there is a shared Python wrapper around an
|
||
implementation dependent interface to the underlying external library. In other
|
||
cases, a private top level module may simply be a CPython implementation detail,
|
||
and other implementations may not provide that module at all.</p>
|
||
<p>To report import errors involving these modules appropriately, the new default
|
||
<code class="docutils literal notranslate"><span class="pre">excepthook</span></code> implementation needs them to be reported by the new query APIs.</p>
|
||
</section>
|
||
<section id="deeming-packaging-related-modules-to-be-mandatory">
|
||
<h3><a class="toc-backref" href="#deeming-packaging-related-modules-to-be-mandatory" role="doc-backlink">Deeming packaging related modules to be mandatory</a></h3>
|
||
<p>Some redistributors aren’t entirely keen on installing the Python specific
|
||
packaging related modules (<code class="docutils literal notranslate"><span class="pre">distutils</span></code>, <code class="docutils literal notranslate"><span class="pre">ensurepip</span></code>, <code class="docutils literal notranslate"><span class="pre">venv</span></code>) by default,
|
||
preferring that developers use their platform specific tooling instead.</p>
|
||
<p>This approach causes interoperability problems for developers working on
|
||
cross-platform projects and educators attempting to write platform independent
|
||
setup instructions, so this PEP takes the view that these modules should be
|
||
considered mandatory, and left out of the list of optional modules.</p>
|
||
</section>
|
||
</section>
|
||
<section id="deferred-ideas">
|
||
<h2><a class="toc-backref" href="#deferred-ideas" role="doc-backlink">Deferred Ideas</a></h2>
|
||
<p>The ideas in this section are concepts that this PEP would potentially help
|
||
enable, but they’re considered out of scope for the initial proposal.</p>
|
||
<section id="platform-dependent-modules">
|
||
<h3><a class="toc-backref" href="#platform-dependent-modules" role="doc-backlink">Platform dependent modules</a></h3>
|
||
<p>Some standard library modules may be missing because they’re only provided on
|
||
particular platforms. For example, the <code class="docutils literal notranslate"><span class="pre">winreg</span></code> module is only available on
|
||
Windows:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ python3 -c "import winreg"
|
||
Traceback (most recent call last):
|
||
File "<string>", line 1, in <module>
|
||
ModuleNotFoundError: No module named 'winreg'
|
||
</pre></div>
|
||
</div>
|
||
<p>In the current proposal, these platform dependent modules will simply be
|
||
included with all the other optional modules rather than attempting to expose
|
||
the platform dependency information in a more structured way.</p>
|
||
<p>However, the platform dependence is at least tracked at the level of “Windows”,
|
||
“Unix”, “Linux”, and “FreeBSD” for the benefit of <a class="reference external" href="https://docs.python.org/3/py-modindex.html">the documentation</a>, so it
|
||
seems plausible that it could potentially be exposed programmatically as well.</p>
|
||
</section>
|
||
<section id="emitting-a-warning-when-main-shadows-a-standard-library-module">
|
||
<h3><a class="toc-backref" href="#emitting-a-warning-when-main-shadows-a-standard-library-module" role="doc-backlink">Emitting a warning when <code class="docutils literal notranslate"><span class="pre">__main__</span></code> shadows a standard library module</a></h3>
|
||
<p>Given the new query APIs, the new default <code class="docutils literal notranslate"><span class="pre">excepthook</span></code> implementation could
|
||
potentially detect when <code class="docutils literal notranslate"><span class="pre">__main__.__file__</span></code> or <code class="docutils literal notranslate"><span class="pre">__main__.__spec__.name</span></code>
|
||
match a standard library module, and emit a suitable warning.</p>
|
||
<p>However, actually doing anything along this lines should review more cases where
|
||
uses actually encounter this problem, and the various options for potentially
|
||
offering more information to assist in debugging the situation, rather than
|
||
needing to be incorporated right now.</p>
|
||
</section>
|
||
</section>
|
||
<section id="recommendation-for-downstream-distributors">
|
||
<h2><a class="toc-backref" href="#recommendation-for-downstream-distributors" role="doc-backlink">Recommendation for Downstream Distributors</a></h2>
|
||
<p>By patching <a class="reference external" href="https://docs.python.org/3.7/library/site.html">site.py</a> <a class="footnote-reference brackets" href="#id4" id="id3">[*]</a> to provide their own implementation of the
|
||
<a class="reference external" href="https://docs.python.org/3/library/sys.html#sys.excepthook">sys.excepthook</a> function, Python distributors can display tailor-made
|
||
error messages for any uncaught exceptions, including informing the user of
|
||
a proper, distro-specific way to install missing standard library modules upon
|
||
encountering a <a class="reference external" href="https://docs.python.org/3.7/library/exceptions.html#ModuleNotFoundError">ModuleNotFoundError</a>.</p>
|
||
<p>Some downstream distributors are already using this method of patching
|
||
<code class="docutils literal notranslate"><span class="pre">sys.excepthook</span></code> to integrate with platform crash reporting mechanisms.</p>
|
||
</section>
|
||
<section id="backwards-compatibility">
|
||
<h2><a class="toc-backref" href="#backwards-compatibility" role="doc-backlink">Backwards Compatibility</a></h2>
|
||
<p>No problems with backwards compatibility are expected. Distributions that are
|
||
already patching Python modules to provide custom handling of missing
|
||
dependencies can continue to do so unhindered.</p>
|
||
</section>
|
||
<section id="reference-and-example-implementation">
|
||
<h2><a class="toc-backref" href="#reference-and-example-implementation" role="doc-backlink">Reference and Example Implementation</a></h2>
|
||
<p>TBD. The finer details will depend on what’s practical given the capabilities
|
||
of the CPython build system (other implementations should then be able to use
|
||
the generated CPython data, rather than having to regenerate it themselves).</p>
|
||
</section>
|
||
<section id="notes-and-references">
|
||
<h2><a class="toc-backref" href="#notes-and-references" role="doc-backlink">Notes and References</a></h2>
|
||
<aside class="footnote-list brackets">
|
||
<aside class="footnote brackets" id="id4" role="doc-footnote">
|
||
<dt class="label" id="id4">[<a href="#id3">*</a>]</dt>
|
||
<dd>Or <a class="reference external" href="https://docs.python.org/3.7/library/site.html">sitecustomize.py</a> for organizations with their own custom
|
||
Python variant.</aside>
|
||
<aside class="footnote brackets" id="debian-patch" role="doc-footnote">
|
||
<dt class="label" id="debian-patch">[<a href="#id1">1</a>]</dt>
|
||
<dd><a class="reference external" href="http://bazaar.launchpad.net/~doko/python/pkg3.5-debian/view/head:/patches/tkinter-import.diff">http://bazaar.launchpad.net/~doko/python/pkg3.5-debian/view/head:/patches/tkinter-import.diff</a></aside>
|
||
<aside class="footnote brackets" id="stackoverflow-stdlib" role="doc-footnote">
|
||
<dt class="label" id="stackoverflow-stdlib">[<a href="#id2">2</a>]</dt>
|
||
<dd><a class="reference external" href="http://stackoverflow.com/questions/6463918/how-can-i-get-a-list-of-all-the-python-standard-library-modules">http://stackoverflow.com/questions/6463918/how-can-i-get-a-list-of-all-the-python-standard-library-modules</a></aside>
|
||
</aside>
|
||
<p>Ideas leading up to this PEP were discussed on the <a class="reference external" href="https://mail.python.org/pipermail/python-dev/2016-July/145534.html">python-dev mailing list</a>
|
||
and subsequently on <a class="reference external" href="https://mail.python.org/pipermail/python-ideas/2016-December/043907.html">python-ideas</a>.</p>
|
||
</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-0534.rst">https://github.com/python/peps/blob/main/peps/pep-0534.rst</a></p>
|
||
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0534.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="#pep-deferral">PEP Deferral</a></li>
|
||
<li><a class="reference internal" href="#motivation">Motivation</a><ul>
|
||
<li><a class="reference internal" href="#cpython">CPython</a></li>
|
||
<li><a class="reference internal" href="#linux-and-other-distributions">Linux and other distributions</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#specification">Specification</a><ul>
|
||
<li><a class="reference internal" href="#apis-to-list-expected-standard-library-modules">APIs to list expected standard library modules</a></li>
|
||
<li><a class="reference internal" href="#changes-to-the-default-sys-excepthook-implementation">Changes to the default <code class="docutils literal notranslate"><span class="pre">sys.excepthook</span></code> implementation</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#design-discussion">Design Discussion</a><ul>
|
||
<li><a class="reference internal" href="#modifying-sys-excepthook">Modifying <code class="docutils literal notranslate"><span class="pre">sys.excepthook</span></code></a></li>
|
||
<li><a class="reference internal" href="#public-api-to-query-expected-standard-library-module-names">Public API to query expected standard library module names</a></li>
|
||
<li><a class="reference internal" href="#only-including-top-level-module-names">Only including top level module names</a></li>
|
||
<li><a class="reference internal" href="#listing-private-top-level-module-names-as-optional-standard-library-modules">Listing private top level module names as optional standard library modules</a></li>
|
||
<li><a class="reference internal" href="#deeming-packaging-related-modules-to-be-mandatory">Deeming packaging related modules to be mandatory</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#deferred-ideas">Deferred Ideas</a><ul>
|
||
<li><a class="reference internal" href="#platform-dependent-modules">Platform dependent modules</a></li>
|
||
<li><a class="reference internal" href="#emitting-a-warning-when-main-shadows-a-standard-library-module">Emitting a warning when <code class="docutils literal notranslate"><span class="pre">__main__</span></code> shadows a standard library module</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#recommendation-for-downstream-distributors">Recommendation for Downstream Distributors</a></li>
|
||
<li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li>
|
||
<li><a class="reference internal" href="#reference-and-example-implementation">Reference and Example Implementation</a></li>
|
||
<li><a class="reference internal" href="#notes-and-references">Notes and 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-0534.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> |