python-peps/pep-0369/index.html

401 lines
29 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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 369 Post import hooks | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0369/">
<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 369 Post import hooks | peps.python.org'>
<meta property="og:description" content="This PEP proposes enhancements for the import machinery to add post import hooks. It is intended primarily to support the wider use of abstract base classes that is expected in Python 3.0.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0369/">
<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="This PEP proposes enhancements for the import machinery to add post import hooks. It is intended primarily to support the wider use of abstract base classes that is expected in Python 3.0.">
<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> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 369</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 369 Post import hooks</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Christian Heimes &lt;christian&#32;&#97;t&#32;python.org&gt;</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Removed from consideration by sponsor or authors">Withdrawn</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">02-Jan-2008</dd>
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
<dd class="field-odd">2.6, 3.0</dd>
<dt class="field-even">Post-History<span class="colon">:</span></dt>
<dd class="field-even">02-Dec-2012</dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#withdrawal-notice">Withdrawal Notice</a></li>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#use-cases">Use cases</a></li>
<li><a class="reference internal" href="#existing-implementations">Existing implementations</a></li>
<li><a class="reference internal" href="#post-import-hook-implementation">Post import hook implementation</a><ul>
<li><a class="reference internal" href="#states">States</a><ul>
<li><a class="reference internal" href="#no-hook-was-registered">No hook was registered</a></li>
<li><a class="reference internal" href="#a-hook-is-registered-and-the-module-is-not-loaded-yet">A hook is registered and the module is not loaded yet</a></li>
<li><a class="reference internal" href="#a-module-is-successfully-loaded">A module is successfully loaded</a></li>
<li><a class="reference internal" href="#a-module-can-t-be-loaded">A module cant be loaded</a></li>
<li><a class="reference internal" href="#a-hook-is-registered-but-the-module-is-already-loaded">A hook is registered but the module is already loaded</a></li>
</ul>
</li>
<li><a class="reference internal" href="#invariants">Invariants</a></li>
<li><a class="reference internal" href="#sample-python-implementation">Sample Python implementation</a></li>
<li><a class="reference internal" href="#c-api">C API</a><ul>
<li><a class="reference internal" href="#new-c-api-functions">New C API functions</a></li>
</ul>
</li>
<li><a class="reference internal" href="#python-api">Python API</a></li>
</ul>
</li>
<li><a class="reference internal" href="#open-issues">Open issues</a></li>
<li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li>
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
<li><a class="reference internal" href="#acknowledgments">Acknowledgments</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
<li><a class="reference internal" href="#references">References</a></li>
</ul>
</details></section>
<section id="withdrawal-notice">
<h2><a class="toc-backref" href="#withdrawal-notice" role="doc-backlink">Withdrawal Notice</a></h2>
<p>This PEP has been withdrawn by its author, as much of the detailed design
is no longer valid following the migration to importlib in Python 3.3.</p>
</section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This PEP proposes enhancements for the import machinery to add
post import hooks. It is intended primarily to support the wider
use of abstract base classes that is expected in Python 3.0.</p>
<p>The PEP originally started as a combined PEP for lazy imports and
post import hooks. After some discussion on the python-dev mailing
list the PEP was parted in two separate PEPs. <a class="footnote-reference brackets" href="#id5" id="id1">[1]</a></p>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<p>Python has no API to hook into the import machinery and execute code
<em>after</em> a module is successfully loaded. The import hooks of <a class="pep reference internal" href="../pep-0302/" title="PEP 302 New Import Hooks">PEP 302</a> are
about finding modules and loading modules but they were not designed to
as post import hooks.</p>
</section>
<section id="use-cases">
<h2><a class="toc-backref" href="#use-cases" role="doc-backlink">Use cases</a></h2>
<p>A use case for a post import hook is mentioned in Alyssa (Nick) Coghlans initial
posting <a class="footnote-reference brackets" href="#id6" id="id2">[2]</a>. about callbacks on module import. It was found during the
development of Python 3.0 and its ABCs. We wanted to register classes
like decimal.Decimal with an ABC but the module should not be imported
on every interpreter startup. Alyssa came up with this example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@imp</span><span class="o">.</span><span class="n">when_imported</span><span class="p">(</span><span class="s1">&#39;decimal&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">register</span><span class="p">(</span><span class="n">decimal</span><span class="p">):</span>
<span class="n">Inexact</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">decimal</span><span class="o">.</span><span class="n">Decimal</span><span class="p">)</span>
</pre></div>
</div>
<p>The function <code class="docutils literal notranslate"><span class="pre">register</span></code> is registered as callback for the module named
decimal. When decimal is imported the function is called with the
module object as argument.</p>
<p>While this particular example isnt necessary in practice, (as
decimal.Decimal will inherit from the appropriate abstract Number base
class in 2.6 and 3.0), it still illustrates the principle.</p>
</section>
<section id="existing-implementations">
<h2><a class="toc-backref" href="#existing-implementations" role="doc-backlink">Existing implementations</a></h2>
<p>PJEs peak.util.imports <a class="footnote-reference brackets" href="#id7" id="id3">[3]</a> implements post load hooks. My
implementation shares a lot with his and its partly based on his ideas.</p>
</section>
<section id="post-import-hook-implementation">
<h2><a class="toc-backref" href="#post-import-hook-implementation" role="doc-backlink">Post import hook implementation</a></h2>
<p>Post import hooks are called after a module has been loaded. The hooks
are callable which take one argument, the module instance. They are
registered by the dotted name of the module, e.g. os or os.path.</p>
<p>The callable are stored in the dict <code class="docutils literal notranslate"><span class="pre">sys.post_import_hooks</span></code> which
is a mapping from names (as string) to a list of callables or None.</p>
<section id="states">
<h3><a class="toc-backref" href="#states" role="doc-backlink">States</a></h3>
<section id="no-hook-was-registered">
<h4><a class="toc-backref" href="#no-hook-was-registered" role="doc-backlink">No hook was registered</a></h4>
<p>sys.post_import_hooks contains no entry for the module</p>
</section>
<section id="a-hook-is-registered-and-the-module-is-not-loaded-yet">
<h4><a class="toc-backref" href="#a-hook-is-registered-and-the-module-is-not-loaded-yet" role="doc-backlink">A hook is registered and the module is not loaded yet</a></h4>
<p>The import hook registry contains an entry
sys.post_import_hooks[“name”] = [hook1]</p>
</section>
<section id="a-module-is-successfully-loaded">
<h4><a class="toc-backref" href="#a-module-is-successfully-loaded" role="doc-backlink">A module is successfully loaded</a></h4>
<p>The import machinery checks if sys.post_import_hooks contains post import
hooks for the newly loaded module. If hooks are found then the hooks are
called in the order they were registered with the module instance as first
argument. The processing of the hooks is stopped when a method raises an
exception. At the end the entry for the module name set to None, even
when an error has occurred.</p>
<p>Additionally the new <code class="docutils literal notranslate"><span class="pre">__notified__</span></code> slot of the module object is set
to <code class="docutils literal notranslate"><span class="pre">True</span></code> in order to prevent infinity recursions when the notification
method is called inside a hook. For object which dont subclass from
<code class="docutils literal notranslate"><span class="pre">PyModule</span></code> a new attribute is added instead.</p>
</section>
<section id="a-module-can-t-be-loaded">
<h4><a class="toc-backref" href="#a-module-can-t-be-loaded" role="doc-backlink">A module cant be loaded</a></h4>
<p>The import hooks are neither called nor removed from the registry. It
may be possible to load the module later.</p>
</section>
<section id="a-hook-is-registered-but-the-module-is-already-loaded">
<h4><a class="toc-backref" href="#a-hook-is-registered-but-the-module-is-already-loaded" role="doc-backlink">A hook is registered but the module is already loaded</a></h4>
<p>The hook is fired immediately.</p>
</section>
</section>
<section id="invariants">
<h3><a class="toc-backref" href="#invariants" role="doc-backlink">Invariants</a></h3>
<p>The import hook system guarantees certain invariants. XXX</p>
</section>
<section id="sample-python-implementation">
<h3><a class="toc-backref" href="#sample-python-implementation" role="doc-backlink">Sample Python implementation</a></h3>
<p>A Python implementation may look like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="k">def</span> <span class="nf">notify</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">module</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ImportError</span><span class="p">(</span><span class="s2">&quot;Module </span><span class="si">%s</span><span class="s2"> has not been imported&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,))</span>
<span class="k">if</span> <span class="n">module</span><span class="o">.</span><span class="n">__notified__</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">module</span><span class="o">.</span><span class="n">__notified__</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="s1">&#39;.&#39;</span> <span class="ow">in</span> <span class="n">name</span><span class="p">:</span>
<span class="n">notify</span><span class="p">(</span><span class="n">name</span><span class="p">[:</span><span class="n">name</span><span class="o">.</span><span class="n">rfind</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">)])</span>
<span class="k">for</span> <span class="n">callback</span> <span class="ow">in</span> <span class="n">post_import_hooks</span><span class="p">[</span><span class="n">name</span><span class="p">]:</span>
<span class="n">callback</span><span class="p">(</span><span class="n">module</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">post_import_hooks</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">XXX</span>
</pre></div>
</div>
</section>
<section id="c-api">
<h3><a class="toc-backref" href="#c-api" role="doc-backlink">C API</a></h3>
<section id="new-c-api-functions">
<h4><a class="toc-backref" href="#new-c-api-functions" role="doc-backlink">New C API functions</a></h4>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">PyObject*</span> <span class="pre">PyImport_GetPostImportHooks(void)</span></code></dt><dd>Returns the dict sys.post_import_hooks or NULL</dd>
<dt><code class="docutils literal notranslate"><span class="pre">PyObject*</span> <span class="pre">PyImport_NotifyLoadedByModule(PyObject</span> <span class="pre">*module)</span></code></dt><dd>Notify the post import system that a module was requested. Returns the
a borrowed reference to the same module object or NULL if an error has
occurred. The function calls only the hooks for the module itself and not
its parents. The function must be called with the import lock acquired.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">PyObject*</span> <span class="pre">PyImport_NotifyLoadedByName(const</span> <span class="pre">char</span> <span class="pre">*name)</span></code></dt><dd><code class="docutils literal notranslate"><span class="pre">PyImport_NotifyLoadedByName(&quot;a.b.c&quot;)</span></code> calls
<code class="docutils literal notranslate"><span class="pre">PyImport_NotifyLoadedByModule()</span></code> for <code class="docutils literal notranslate"><span class="pre">a</span></code>, <code class="docutils literal notranslate"><span class="pre">a.b</span></code> and <code class="docutils literal notranslate"><span class="pre">a.b.c</span></code>
in that particular order. The modules are retrieved from
<code class="docutils literal notranslate"><span class="pre">sys.modules</span></code>. If a module cant be retrieved, an exception is raised
otherwise the a borrowed reference to <code class="docutils literal notranslate"><span class="pre">modname</span></code> is returned.
The hook calls always start with the prime parent module.
The caller of PyImport_NotifyLoadedByName() must hold the import lock!</dd>
<dt><code class="docutils literal notranslate"><span class="pre">PyObject*</span> <span class="pre">PyImport_RegisterPostImportHook(PyObject</span> <span class="pre">*callable,</span> <span class="pre">PyObject</span> <span class="pre">*mod_name)</span></code></dt><dd>Register a new hook <code class="docutils literal notranslate"><span class="pre">callable</span></code> for the module <code class="docutils literal notranslate"><span class="pre">mod_name</span></code></dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">PyModule_GetNotified(PyObject</span> <span class="pre">*module)</span></code></dt><dd>Returns the status of the <code class="docutils literal notranslate"><span class="pre">__notified__</span></code> slot / attribute.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">PyModule_SetNotified(PyObject</span> <span class="pre">*module,</span> <span class="pre">int</span> <span class="pre">status)</span></code></dt><dd>Set the status of the <code class="docutils literal notranslate"><span class="pre">__notified__</span></code> slot / attribute.</dd>
</dl>
<p>The <code class="docutils literal notranslate"><span class="pre">PyImport_NotifyLoadedByModule()</span></code> method is called inside
<code class="docutils literal notranslate"><span class="pre">import_submodule()</span></code>. The import system makes sure that the import lock
is acquired and the hooks for the parent modules are already called.</p>
</section>
</section>
<section id="python-api">
<h3><a class="toc-backref" href="#python-api" role="doc-backlink">Python API</a></h3>
<p>The import hook registry and two new API methods are exposed through the
<code class="docutils literal notranslate"><span class="pre">sys</span></code> and <code class="docutils literal notranslate"><span class="pre">imp</span></code> module.</p>
<dl>
<dt><code class="docutils literal notranslate"><span class="pre">sys.post_import_hooks</span></code></dt><dd>The dict contains the post import hooks:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="s2">&quot;name&quot;</span> <span class="p">:</span> <span class="p">[</span><span class="n">hook1</span><span class="p">,</span> <span class="n">hook2</span><span class="p">],</span> <span class="o">...</span><span class="p">}</span>
</pre></div>
</div>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">imp.register_post_import_hook(hook:</span> <span class="pre">&quot;callable&quot;,</span> <span class="pre">name:</span> <span class="pre">str)</span></code></dt><dd>Register a new hook <em>hook</em> for the module <em>name</em></dd>
<dt><code class="docutils literal notranslate"><span class="pre">imp.notify_module_loaded(module:</span> <span class="pre">&quot;module</span> <span class="pre">instance&quot;)</span> <span class="pre">-&gt;</span> <span class="pre">module</span></code></dt><dd>Notify the system that a module has been loaded. The method is provided
for compatibility with existing lazy / deferred import extensions.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">module.__notified__</span></code></dt><dd>A slot of a module instance. XXX</dd>
</dl>
<p>The when_imported function decorator is also in the imp module,
which is equivalent to:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">when_imported</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">register</span><span class="p">(</span><span class="n">hook</span><span class="p">):</span>
<span class="n">register_post_import_hook</span><span class="p">(</span><span class="n">hook</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
<span class="k">return</span> <span class="n">register</span>
</pre></div>
</div>
<dl class="simple">
<dt>imp.when_imported(name) -&gt; decorator function</dt><dd>for &#64;when_imported(name) def hook(module): pass</dd>
</dl>
</section>
</section>
<section id="open-issues">
<h2><a class="toc-backref" href="#open-issues" role="doc-backlink">Open issues</a></h2>
<p>The when_imported decorator hasnt been written.</p>
<p>The code contains several XXX comments. They are mostly about error
handling in edge cases.</p>
</section>
<section id="backwards-compatibility">
<h2><a class="toc-backref" href="#backwards-compatibility" role="doc-backlink">Backwards Compatibility</a></h2>
<p>The new features and API dont conflict with old import system of Python
and dont cause any backward compatibility issues for most software.
However systems like PEAK and Zope which implement their own lazy import
magic need to follow some rules.</p>
<p>The post import hooks carefully designed to cooperate with existing
deferred and lazy import systems. Its the suggestion of the PEP author
to replace own on-load-hooks with the new hook API. The alternative
lazy or deferred imports will still work but the implementations must
call the <code class="docutils literal notranslate"><span class="pre">imp.notify_module_loaded</span></code> function.</p>
</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 already written and is available in the
<em>py3k-importhook</em> branch. <a class="footnote-reference brackets" href="#id8" id="id4">[4]</a> It still requires some cleanups,
documentation updates and additional unit tests.</p>
</section>
<section id="acknowledgments">
<h2><a class="toc-backref" href="#acknowledgments" role="doc-backlink">Acknowledgments</a></h2>
<p>Alyssa Coghlan, for proof reading and the initial discussion
Phillip J. Eby, for his implementation in PEAK and help with my own implementation</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 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="id5" role="doc-footnote">
<dt class="label" id="id5">[<a href="#id1">1</a>]</dt>
<dd>PEP: Lazy module imports and post import hook
<a class="reference external" href="http://permalink.gmane.org/gmane.comp.python.devel/90949">http://permalink.gmane.org/gmane.comp.python.devel/90949</a></aside>
<aside class="footnote brackets" id="id6" role="doc-footnote">
<dt class="label" id="id6">[<a href="#id2">2</a>]</dt>
<dd>Interest in PEP for callbacks on module import
<a class="reference external" href="http://permalink.gmane.org/gmane.comp.python.python-3000.devel/11126">http://permalink.gmane.org/gmane.comp.python.python-3000.devel/11126</a></aside>
<aside class="footnote brackets" id="id7" role="doc-footnote">
<dt class="label" id="id7">[<a href="#id3">3</a>]</dt>
<dd>peak.utils.imports
<a class="reference external" href="http://svn.eby-sarna.com/Importing/peak/util/imports.py?view=markup">http://svn.eby-sarna.com/Importing/peak/util/imports.py?view=markup</a></aside>
<aside class="footnote brackets" id="id8" role="doc-footnote">
<dt class="label" id="id8">[<a href="#id4">4</a>]</dt>
<dd>py3k-importhook branch
<a class="reference external" href="http://svn.python.org/view/python/branches/py3k-importhook/">http://svn.python.org/view/python/branches/py3k-importhook/</a></aside>
</aside>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0369.rst">https://github.com/python/peps/blob/main/peps/pep-0369.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0369.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="#withdrawal-notice">Withdrawal Notice</a></li>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#use-cases">Use cases</a></li>
<li><a class="reference internal" href="#existing-implementations">Existing implementations</a></li>
<li><a class="reference internal" href="#post-import-hook-implementation">Post import hook implementation</a><ul>
<li><a class="reference internal" href="#states">States</a><ul>
<li><a class="reference internal" href="#no-hook-was-registered">No hook was registered</a></li>
<li><a class="reference internal" href="#a-hook-is-registered-and-the-module-is-not-loaded-yet">A hook is registered and the module is not loaded yet</a></li>
<li><a class="reference internal" href="#a-module-is-successfully-loaded">A module is successfully loaded</a></li>
<li><a class="reference internal" href="#a-module-can-t-be-loaded">A module cant be loaded</a></li>
<li><a class="reference internal" href="#a-hook-is-registered-but-the-module-is-already-loaded">A hook is registered but the module is already loaded</a></li>
</ul>
</li>
<li><a class="reference internal" href="#invariants">Invariants</a></li>
<li><a class="reference internal" href="#sample-python-implementation">Sample Python implementation</a></li>
<li><a class="reference internal" href="#c-api">C API</a><ul>
<li><a class="reference internal" href="#new-c-api-functions">New C API functions</a></li>
</ul>
</li>
<li><a class="reference internal" href="#python-api">Python API</a></li>
</ul>
</li>
<li><a class="reference internal" href="#open-issues">Open issues</a></li>
<li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li>
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
<li><a class="reference internal" href="#acknowledgments">Acknowledgments</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
<li><a class="reference internal" href="#references">References</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0369.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>