peps/pep-0301/index.html

480 lines
30 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!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 301 Package Index and Metadata for Distutils | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0301/">
<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 301 Package Index and Metadata for Distutils | peps.python.org'>
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0301/">
<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> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 301</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 301 Package Index and Metadata for Distutils</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Richard Jones &lt;richard&#32;&#97;t&#32;python.org&gt;</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">Topic<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="../topic/packaging/">Packaging</a></dd>
<dt class="field-odd">Created<span class="colon">:</span></dt>
<dd class="field-odd">24-Oct-2002</dd>
<dt class="field-even">Python-Version<span class="colon">:</span></dt>
<dd class="field-even">2.3</dd>
<dt class="field-odd">Post-History<span class="colon">:</span></dt>
<dd class="field-odd">08-Nov-2002</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="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#specification">Specification</a><ul>
<li><a class="reference internal" href="#web-interface">Web Interface</a></li>
<li><a class="reference internal" href="#user-roles">User Roles</a></li>
<li><a class="reference internal" href="#index-storage-schema">Index Storage (Schema)</a></li>
<li><a class="reference internal" href="#distutils-register-command">Distutils <em>register</em> Command</a></li>
<li><a class="reference internal" href="#distutils-trove-classification">Distutils Trove Classification</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#rejected-proposals">Rejected Proposals</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
<li><a class="reference internal" href="#acknowledgements">Acknowledgements</a></li>
</ul>
</details></section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This PEP proposes several extensions to the Distutils packaging system
<a class="footnote-reference brackets" href="#id7" id="id1">[1]</a>. These enhancements include a central package index server,
tools for submitting package information to the index and extensions
to the package metadata to include Trove <a class="footnote-reference brackets" href="#id8" id="id2">[2]</a> information.</p>
<p>This PEP does not address issues of package dependency. It also does
not address storage and download of packages as described in <a class="pep reference internal" href="../pep-0243/" title="PEP 243 Module Repository Upload Mechanism">PEP 243</a>.
Nor is it proposing a local database of packages as described
in <a class="pep reference internal" href="../pep-0262/" title="PEP 262 A Database of Installed Python Packages">PEP 262</a>.</p>
<p>Existing package repositories such as the Vaults of Parnassus <a class="footnote-reference brackets" href="#id9" id="id3">[3]</a>,
CPAN <a class="footnote-reference brackets" href="#id10" id="id4">[4]</a> and PAUSE <a class="footnote-reference brackets" href="#id11" id="id5">[5]</a> will be investigated as prior art in this
field.</p>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<p>Python programmers have long needed a simple method of discovering
existing modules and systems available for their use. It is arguable
that the existence of these systems for other languages have been a
significant contribution to their popularity. The existence of the
Catalog-SIG, and the many discussions there indicate that there is a
large population of users who recognise this need.</p>
<p>The introduction of the Distutils packaging system to Python
simplified the process of distributing shareable code, and included
mechanisms for the capture of package metadata, but did little with
the metadata save ship it with the package.</p>
<p>An interface to the index should be hosted in the python.org domain,
giving it an air of legitimacy that existing catalog efforts do not
have.</p>
<p>The interface for submitting information to the catalog should be as
simple as possible - hopefully just a one-line command for most users.</p>
<p>Issues of package dependency are not addressed due to the complexity
of such a system. <a class="pep reference internal" href="../pep-0262/" title="PEP 262 A Database of Installed Python Packages">PEP 262</a> proposes such a system, but as of this
writing the PEP is still unfinished.</p>
<p>Issues of package dissemination (storage on a central server) are
not addressed because they require assumptions about availability of
storage and bandwidth that I am not in a position to make. <a class="pep reference internal" href="../pep-0243/" title="PEP 243 Module Repository Upload Mechanism">PEP 243</a>,
which is still being developed, is tackling these issues and many
more. This proposal is considered compatible with, and adjunct to
the proposal in <a class="pep reference internal" href="../pep-0243/" title="PEP 243 Module Repository Upload Mechanism">PEP 243</a>.</p>
</section>
<section id="specification">
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
<p>The specification takes three parts, the <a class="reference internal" href="#web-interface">web interface</a>, the
<a class="reference internal" href="#distutils-register-command">Distutils register command</a> and the <a class="reference internal" href="#distutils-trove-classification">Distutils Trove
classification</a>.</p>
<section id="web-interface">
<h3><a class="toc-backref" href="#web-interface" role="doc-backlink">Web Interface</a></h3>
<p>A web interface is implemented over a simple store. The interface is
available through the python.org domain, either directly or as
packages.python.org.</p>
<p>The store has columns for all metadata fields. The (name, version)
double is used as a uniqueness key. Additional submissions for an
existing (name, version) will result in an <em>update</em> operation.</p>
<p>The web interface implements the following commands/interfaces:</p>
<dl>
<dt><strong>index</strong></dt><dd>Lists known packages, optionally filtered. An additional HTML page,
<strong>search</strong>, presents a form to the user which is used to customise
the index view. The index will include a browsing interface like
that presented in the Trove interface design section 4.3. The
results will be paginated, sorted alphabetically and only showing
the most recent version. The most recent version information will
be determined using the Distutils LooseVersion class.</dd>
<dt><strong>display</strong></dt><dd>Displays information about the package. All fields are displayed as
plain text. The “url” (or “home_page”) field is hyperlinked.</dd>
<dt><strong>submit</strong></dt><dd>Accepts a POST submission of metadata about a package. The
“name” and “version” fields are mandatory, as they uniquely identify
an entry in the index. <strong>Submit</strong> will automatically determine
whether to create a new entry or update an existing entry. The
metadata is checked for correctness where appropriate - specifically
the Trove discriminators are compared with the allowed set. An
update will update all information about the package based on the
new submitted information.<p>There will also be a submit/edit form that will allow manual
submission and updating for those who do not use Distutils.</p>
</dd>
<dt><strong>submit_pkg_info</strong></dt><dd>Accepts a POST submission of a PKG-INFO file and performs the same
function as the <strong>submit</strong> interface.</dd>
<dt><strong>user</strong></dt><dd>Registers a new user with the index. Requires username, password
and email address. Passwords will be stored in the index database
as SHA hashes. If the username already exists in the database:<ol class="arabic simple">
<li>If valid HTTP Basic authentication is provided, the password and
email address are updated with the submission information, or</li>
<li>If no valid authentication is provided, the user is informed that
the login is already taken.</li>
</ol>
<p>Registration will be a three-step process, involving:</p>
<ol class="arabic simple">
<li>User submission of details via the Distutils <em>register</em> command
or through the web,</li>
<li>Index server sending email to the users email address with a URL
to visit to confirm registration with a random one-time key, and</li>
<li>User visits URL with the key and confirms registration.</li>
</ol>
</dd>
<dt><strong>roles</strong></dt><dd>An interface for changing user Role assignments.</dd>
<dt><strong>password_reset</strong></dt><dd>Using a supplied email address as the key, this resets a users
password and sends an email with the new password to the user.</dd>
</dl>
<p>The <strong>submit</strong> command will require HTTP Basic authentication,
preferably over an HTTPS connection.</p>
<p>The server interface will indicate success or failure of the commands
through a subset of the standard HTTP response codes:</p>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head">Code</th>
<th class="head">Meaning</th>
<th class="head">Register command implications</th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td>200</td>
<td>OK</td>
<td>Everything worked just fine</td>
</tr>
<tr class="row-odd"><td>400</td>
<td>Bad request</td>
<td>Data provided for submission was malformed</td>
</tr>
<tr class="row-even"><td>401</td>
<td>Unauthorised</td>
<td>The username or password supplied were incorrect</td>
</tr>
<tr class="row-odd"><td>403</td>
<td>Forbidden</td>
<td>User does not have permission to update the
package information (not Owner or Maintainer)</td>
</tr>
</tbody>
</table>
</section>
<section id="user-roles">
<h3><a class="toc-backref" href="#user-roles" role="doc-backlink">User Roles</a></h3>
<p>Three user Roles will be assignable to users:</p>
<dl class="simple">
<dt>Owner</dt><dd>Owns a package name, may assign Maintainer Role for that name. The
first user to register information about a package is deemed Owner
of the package name. The Admin user may change this if necessary.
May submit updates for the package name.</dd>
<dt>Maintainer</dt><dd>Can submit and update info for a particular package name.</dd>
<dt>Admin</dt><dd>Can assign Owner Role and edit user details. Not specific to a
package name.</dd>
</dl>
</section>
<section id="index-storage-schema">
<h3><a class="toc-backref" href="#index-storage-schema" role="doc-backlink">Index Storage (Schema)</a></h3>
<p>The index is stored in a set of relational database tables:</p>
<dl class="simple">
<dt><strong>packages</strong></dt><dd>Lists package names and holds package-level metadata (currently
just the stable release version)</dd>
<dt><strong>releases</strong></dt><dd>Each package has an entry in <strong>releases</strong> for each version of the
package that is released. A row holds the bulk of the information
given in the packages PKG-INFO file. There is one row for each
package (<em>name</em>, <em>version</em>).</dd>
<dt><strong>trove_discriminators</strong></dt><dd>Lists the Trove discriminator text and assigns each one a unique
ID.</dd>
<dt><strong>release_discriminators</strong></dt><dd>Each entry maps a package (<em>name</em>, <em>version</em>) to a
<em>discriminator_id</em>. We map to releases instead of packages because
the set of discriminators may change between releases.</dd>
<dt><strong>journals</strong></dt><dd>Holds information about changes to package information in the
index. Changes to the <strong>packages</strong>, <strong>releases</strong>, <strong>roles</strong>,
and <strong>release_discriminators</strong> tables are listed here by
package <em>name</em> and <em>version</em> if the change is release-specific.</dd>
<dt><strong>users</strong></dt><dd>Holds our user database - user name, email address and password.</dd>
<dt><strong>roles</strong></dt><dd>Maps <em>user_name</em> and <em>role_name</em> to a <em>package_name</em>.</dd>
</dl>
<p>An additional table, <strong>rego_otk</strong> holds the One Time Keys generated
during registration and is not interesting in the scope of the index
itself.</p>
</section>
<section id="distutils-register-command">
<h3><a class="toc-backref" href="#distutils-register-command" role="doc-backlink">Distutils <em>register</em> Command</a></h3>
<p>An additional Distutils command, <code class="docutils literal notranslate"><span class="pre">register</span></code>, is implemented which
posts the package metadata to the central index. The <em>register</em>
command automatically handles user registration; the user is presented
with three options:</p>
<ol class="arabic simple">
<li>login and submit package information</li>
<li>register as a new packager</li>
<li>send password reminder email</li>
</ol>
<p>On systems where the <code class="docutils literal notranslate"><span class="pre">$HOME</span></code> environment variable is set, the user
will be prompted at exit to save their username/password to a file
in their <code class="docutils literal notranslate"><span class="pre">$HOME</span></code> directory in the file <code class="docutils literal notranslate"><span class="pre">.pypirc</span></code>.</p>
<p>Notification of changes to a package entry will be sent to all users
who have submitted information about the package. That is, the
original submitter and any subsequent updaters.</p>
<p>The <em>register</em> command will include a <code class="docutils literal notranslate"><span class="pre">--verify</span></code> option which
performs a test submission to the index without actually committing
the data. The index will perform its submission verification checks
as usual and report any errors it would have reported during a normal
submission. This is useful for verifying correctness of Trove
discriminators.</p>
</section>
<section id="distutils-trove-classification">
<h3><a class="toc-backref" href="#distutils-trove-classification" role="doc-backlink">Distutils Trove Classification</a></h3>
<p>The Trove concept of <em>discrimination</em> will be added to the metadata
set available to package authors through the new attribute
“classifiers”. The list of classifiers will be available through the
web, and added to the package like so:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">setup</span><span class="p">(</span>
<span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;roundup&quot;</span><span class="p">,</span>
<span class="n">version</span> <span class="o">=</span> <span class="n">__version__</span><span class="p">,</span>
<span class="n">classifiers</span> <span class="o">=</span> <span class="p">[</span>
<span class="s1">&#39;Development Status :: 4 - Beta&#39;</span><span class="p">,</span>
<span class="s1">&#39;Environment :: Console&#39;</span><span class="p">,</span>
<span class="s1">&#39;Environment :: Web Environment&#39;</span><span class="p">,</span>
<span class="s1">&#39;Intended Audience :: End Users/Desktop&#39;</span><span class="p">,</span>
<span class="s1">&#39;Intended Audience :: Developers&#39;</span><span class="p">,</span>
<span class="s1">&#39;Intended Audience :: System Administrators&#39;</span><span class="p">,</span>
<span class="s1">&#39;License :: OSI Approved :: Python Software Foundation License&#39;</span><span class="p">,</span>
<span class="s1">&#39;Operating System :: MacOS :: MacOS X&#39;</span><span class="p">,</span>
<span class="s1">&#39;Operating System :: Microsoft :: Windows&#39;</span><span class="p">,</span>
<span class="s1">&#39;Operating System :: POSIX&#39;</span><span class="p">,</span>
<span class="s1">&#39;Programming Language :: Python&#39;</span><span class="p">,</span>
<span class="s1">&#39;Topic :: Communications :: Email&#39;</span><span class="p">,</span>
<span class="s1">&#39;Topic :: Office/Business&#39;</span><span class="p">,</span>
<span class="s1">&#39;Topic :: Software Development :: Bug Tracking&#39;</span><span class="p">,</span>
<span class="p">],</span>
<span class="n">url</span> <span class="o">=</span> <span class="s1">&#39;http://sourceforge.net/projects/roundup/&#39;</span><span class="p">,</span>
<span class="o">...</span>
<span class="p">)</span>
</pre></div>
</div>
<p>It was decided that strings would be used for the classification
entries due to the deep nesting that would be involved in a more
formal Python structure.</p>
<p>The original Trove specification that classification namespaces be
separated by slashes (“/”) unfortunately collides with many of the
names having slashes in them (e.g. “OS/2”). The double-colon solution
(” :: “) implemented by SourceForge and FreshMeat gets around this
limitation.</p>
<p>The list of classification values on the module index has been merged
from FreshMeat and SourceForge (with their permission). This list
will be made available both through the web interface and through the
<em>register</em> commands <code class="docutils literal notranslate"><span class="pre">--list-classifiers</span></code> option as a text list
which may then be copied to the <code class="docutils literal notranslate"><span class="pre">setup.py</span></code> file. The <em>register</em>
commands <code class="docutils literal notranslate"><span class="pre">--verify</span></code> option will check classifiers values against
the servers list.</p>
<p>Unfortunately, the addition of the “classifiers” property is not
backwards-compatible. A setup.py file using it will not work under
Python 2.1.3. It is hoped that a bug-fix release of Python 2.2 (most
likely 2.2.3) will relax the argument checking of the setup() command
to allow new keywords, even if theyre not actually used. It is
preferable that a warning be produced, rather than a show-stopping
error. The use of the new keyword should be discouraged in situations
where the package is advertised as being compatible with python
versions earlier than 2.2.3 or 2.3.</p>
<p>In the PKG-INFO, the classifiers list items will appear as individual
<code class="docutils literal notranslate"><span class="pre">Classifier:</span></code> entries:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Name</span><span class="p">:</span> <span class="n">roundup</span>
<span class="n">Version</span><span class="p">:</span> <span class="mf">0.5.2</span>
<span class="n">Classifier</span><span class="p">:</span> <span class="n">Development</span> <span class="n">Status</span> <span class="p">::</span> <span class="mi">4</span> <span class="o">-</span> <span class="n">Beta</span>
<span class="n">Classifier</span><span class="p">:</span> <span class="n">Environment</span> <span class="p">::</span> <span class="n">Console</span> <span class="p">(</span><span class="n">Text</span> <span class="n">Based</span><span class="p">)</span>
<span class="o">.</span>
<span class="o">.</span>
<span class="n">Classifier</span><span class="p">:</span> <span class="n">Topic</span> <span class="p">::</span> <span class="n">Software</span> <span class="n">Development</span> <span class="p">::</span> <span class="n">Bug</span> <span class="n">Tracking</span>
<span class="n">Url</span><span class="p">:</span> <span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">sourceforge</span><span class="o">.</span><span class="n">net</span><span class="o">/</span><span class="n">projects</span><span class="o">/</span><span class="n">roundup</span><span class="o">/</span>
</pre></div>
</div>
</section>
</section>
<section id="implementation">
<h2><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h2>
<p>The server is available at:</p>
<blockquote>
<div><a class="reference external" href="http://www.python.org/pypi">http://www.python.org/pypi</a></div></blockquote>
<p>The code is available from the SourceForge project:</p>
<blockquote>
<div><a class="reference external" href="http://sourceforge.net/projects/pypi/">http://sourceforge.net/projects/pypi/</a></div></blockquote>
<p>The <em>register</em> command has been integrated into Python 2.3.</p>
</section>
<section id="rejected-proposals">
<h2><a class="toc-backref" href="#rejected-proposals" role="doc-backlink">Rejected Proposals</a></h2>
<p>Originally, the index server was to return custom headers (inspired by
<a class="pep reference internal" href="../pep-0243/" title="PEP 243 Module Repository Upload Mechanism">PEP 243</a>):</p>
<dl class="simple">
<dt><strong>X-Pypi-Status</strong></dt><dd>Either “success” or “fail”.</dd>
<dt><strong>X-Pypi-Reason</strong></dt><dd>A description of the reason for failure, or additional information
in the case of a success.</dd>
</dl>
<p>However, it has been pointed out <a class="footnote-reference brackets" href="#id12" id="id6">[6]</a> that this is a bad scheme to
use.</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="id7" role="doc-footnote">
<dt class="label" id="id7">[<a href="#id1">1</a>]</dt>
<dd>Distutils packaging system
(<a class="reference external" href="http://docs.python.org/library/distutils.html">http://docs.python.org/library/distutils.html</a>)</aside>
<aside class="footnote brackets" id="id8" role="doc-footnote">
<dt class="label" id="id8">[<a href="#id2">2</a>]</dt>
<dd>Trove
(<a class="reference external" href="http://www.catb.org/~esr/trove/">http://www.catb.org/~esr/trove/</a>)</aside>
<aside class="footnote brackets" id="id9" role="doc-footnote">
<dt class="label" id="id9">[<a href="#id3">3</a>]</dt>
<dd>Vaults of Parnassus
(<a class="reference external" href="http://www.vex.net/parnassus/">http://www.vex.net/parnassus/</a>)</aside>
<aside class="footnote brackets" id="id10" role="doc-footnote">
<dt class="label" id="id10">[<a href="#id4">4</a>]</dt>
<dd>CPAN
(<a class="reference external" href="http://www.cpan.org/">http://www.cpan.org/</a>)</aside>
<aside class="footnote brackets" id="id11" role="doc-footnote">
<dt class="label" id="id11">[<a href="#id5">5</a>]</dt>
<dd>PAUSE
(<a class="reference external" href="http://pause.cpan.org/">http://pause.cpan.org/</a>)</aside>
<aside class="footnote brackets" id="id12" role="doc-footnote">
<dt class="label" id="id12">[<a href="#id6">6</a>]</dt>
<dd>[PEP243] upload status is bogus
(<a class="reference external" href="https://mail.python.org/pipermail/distutils-sig/2001-March/002262.html">https://mail.python.org/pipermail/distutils-sig/2001-March/002262.html</a>)</aside>
</aside>
</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="acknowledgements">
<h2><a class="toc-backref" href="#acknowledgements" role="doc-backlink">Acknowledgements</a></h2>
<p>Anthony Baxter, Martin v. Loewis and David Goodger for encouragement
and feedback during initial drafting.</p>
<p>A.M. Kuchling for support including hosting the second prototype.</p>
<p>Greg Stein for recommending that the register command interpret the
HTTP response codes rather than custom X-PyPI-* headers.</p>
<p>The many participants of the Distutils and Catalog SIGs for their
ideas over the years.</p>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0301.rst">https://github.com/python/peps/blob/main/peps/pep-0301.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0301.rst">2023-09-09 17:39:29 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="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#specification">Specification</a><ul>
<li><a class="reference internal" href="#web-interface">Web Interface</a></li>
<li><a class="reference internal" href="#user-roles">User Roles</a></li>
<li><a class="reference internal" href="#index-storage-schema">Index Storage (Schema)</a></li>
<li><a class="reference internal" href="#distutils-register-command">Distutils <em>register</em> Command</a></li>
<li><a class="reference internal" href="#distutils-trove-classification">Distutils Trove Classification</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#rejected-proposals">Rejected Proposals</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
<li><a class="reference internal" href="#acknowledgements">Acknowledgements</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0301.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>