357 lines
20 KiB
HTML
357 lines
20 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 272 – API for Block Encryption Algorithms v1.0 | peps.python.org</title>
|
|||
|
<link rel="shortcut icon" href="../_static/py.png">
|
|||
|
<link rel="canonical" href="https://peps.python.org/pep-0272/">
|
|||
|
<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 272 – API for Block Encryption Algorithms v1.0 | peps.python.org'>
|
|||
|
<meta property="og:description" content="This document specifies a standard API for secret-key block encryption algorithms such as DES or Rijndael, making it easier to switch between different algorithms and implementations.">
|
|||
|
<meta property="og:type" content="website">
|
|||
|
<meta property="og:url" content="https://peps.python.org/pep-0272/">
|
|||
|
<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 document specifies a standard API for secret-key block encryption algorithms such as DES or Rijndael, making it easier to switch between different algorithms and implementations.">
|
|||
|
<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 272</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 272 – API for Block Encryption Algorithms v1.0</h1>
|
|||
|
<dl class="rfc2822 field-list simple">
|
|||
|
<dt class="field-odd">Author<span class="colon">:</span></dt>
|
|||
|
<dd class="field-odd">A.M. Kuchling <amk at amk.ca></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="Non-normative PEP containing background, guidelines or other information relevant to the Python ecosystem">Informational</abbr></dd>
|
|||
|
<dt class="field-even">Created<span class="colon">:</span></dt>
|
|||
|
<dd class="field-even">18-Sep-2001</dd>
|
|||
|
<dt class="field-odd">Post-History<span class="colon">:</span></dt>
|
|||
|
<dd class="field-odd">17-Apr-2002, 29-May-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="#introduction">Introduction</a></li>
|
|||
|
<li><a class="reference internal" href="#specification">Specification</a></li>
|
|||
|
<li><a class="reference internal" href="#references">References</a></li>
|
|||
|
<li><a class="reference internal" href="#changes">Changes</a></li>
|
|||
|
<li><a class="reference internal" href="#acknowledgements">Acknowledgements</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>This document specifies a standard API for secret-key block
|
|||
|
encryption algorithms such as DES or Rijndael, making it easier to
|
|||
|
switch between different algorithms and implementations.</p>
|
|||
|
</section>
|
|||
|
<section id="introduction">
|
|||
|
<h2><a class="toc-backref" href="#introduction" role="doc-backlink">Introduction</a></h2>
|
|||
|
<p>Encryption algorithms transform their input data (called
|
|||
|
plaintext) in some way that is dependent on a variable key,
|
|||
|
producing ciphertext. The transformation can easily be reversed
|
|||
|
if and only if one knows the key. The key is a sequence of bits
|
|||
|
chosen from some very large space of possible keys. There are two
|
|||
|
classes of encryption algorithms: block ciphers and stream ciphers.</p>
|
|||
|
<p>Block ciphers encrypt multibyte inputs of a fixed size (frequently
|
|||
|
8 or 16 bytes long), and can be operated in various feedback
|
|||
|
modes. The feedback modes supported in this specification are:</p>
|
|||
|
<table class="docutils align-default">
|
|||
|
<thead>
|
|||
|
<tr class="row-odd"><th class="head">Number</th>
|
|||
|
<th class="head">Constant</th>
|
|||
|
<th class="head">Description</th>
|
|||
|
</tr>
|
|||
|
</thead>
|
|||
|
<tbody>
|
|||
|
<tr class="row-even"><td>1</td>
|
|||
|
<td>MODE_ECB</td>
|
|||
|
<td>Electronic Code Book</td>
|
|||
|
</tr>
|
|||
|
<tr class="row-odd"><td>2</td>
|
|||
|
<td>MODE_CBC</td>
|
|||
|
<td>Cipher Block Chaining</td>
|
|||
|
</tr>
|
|||
|
<tr class="row-even"><td>3</td>
|
|||
|
<td>MODE_CFB</td>
|
|||
|
<td>Cipher Feedback</td>
|
|||
|
</tr>
|
|||
|
<tr class="row-odd"><td>5</td>
|
|||
|
<td>MODE_OFB</td>
|
|||
|
<td>Output Feedback</td>
|
|||
|
</tr>
|
|||
|
<tr class="row-even"><td>6</td>
|
|||
|
<td>MODE_CTR</td>
|
|||
|
<td>Counter</td>
|
|||
|
</tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
<p>These modes are to be implemented as described in NIST publication
|
|||
|
SP 800-38A <a class="footnote-reference brackets" href="#id3" id="id1">[1]</a>. Descriptions of the first three feedback modes can
|
|||
|
also be found in Bruce Schneier’s book <em>Applied Cryptography</em> <a class="footnote-reference brackets" href="#id4" id="id2">[2]</a>.</p>
|
|||
|
<p>(The numeric value 4 is reserved for MODE_PGP, a variant of CFB
|
|||
|
described in <span class="target" id="index-0"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2440.html"><strong>RFC 2440</strong></a>: “OpenPGP Message Format”. This mode
|
|||
|
isn’t considered important enough to make it worth requiring it
|
|||
|
for all block encryption ciphers, though supporting it is a nice
|
|||
|
extra feature.)</p>
|
|||
|
<p>In a strict formal sense, stream ciphers encrypt data bit-by-bit;
|
|||
|
practically, stream ciphers work on a character-by-character
|
|||
|
basis. This PEP only aims at specifying an interface for block
|
|||
|
ciphers, though stream ciphers can support the interface described
|
|||
|
here by fixing ‘block_size’ to 1. Feedback modes also don’t make
|
|||
|
sense for stream ciphers, so the only reasonable feedback mode
|
|||
|
would be ECB mode.</p>
|
|||
|
</section>
|
|||
|
<section id="specification">
|
|||
|
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
|
|||
|
<p>Encryption modules can add additional functions, methods, and
|
|||
|
attributes beyond those described in this PEP, but all of the
|
|||
|
features described in this PEP must be present for a module to
|
|||
|
claim compliance with it.</p>
|
|||
|
<p>Secret-key encryption modules should define one function:</p>
|
|||
|
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">new</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">mode</span><span class="p">,</span> <span class="p">[</span><span class="n">IV</span><span class="p">],</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
<p>Returns a ciphering object, using the secret key contained in the
|
|||
|
string ‘key’, and using the feedback mode ‘mode’, which must be
|
|||
|
one of the constants from the table above.</p>
|
|||
|
<p>If ‘mode’ is MODE_CBC or MODE_CFB, ‘IV’ must be provided and must
|
|||
|
be a string of the same length as the block size. Not providing a
|
|||
|
value of ‘IV’ will result in a <code class="docutils literal notranslate"><span class="pre">ValueError</span></code> exception being raised.</p>
|
|||
|
<p>Depending on the algorithm, a module may support additional
|
|||
|
keyword arguments to this function. Some keyword arguments are
|
|||
|
specified by this PEP, and modules are free to add additional
|
|||
|
keyword arguments. If a value isn’t provided for a given keyword,
|
|||
|
a secure default value should be used. For example, if an
|
|||
|
algorithm has a selectable number of rounds between 1 and 16, and
|
|||
|
1-round encryption is insecure and 8-round encryption is believed
|
|||
|
secure, the default value for ‘rounds’ should be 8 or more.
|
|||
|
(Module implementors can choose a very slow but secure value, too,
|
|||
|
such as 16 in this example. This decision is left up to the
|
|||
|
implementor.)</p>
|
|||
|
<p>The following table lists keyword arguments defined by this PEP:</p>
|
|||
|
<table class="docutils align-default">
|
|||
|
<thead>
|
|||
|
<tr class="row-odd"><th class="head">Keyword</th>
|
|||
|
<th class="head">Meaning</th>
|
|||
|
</tr>
|
|||
|
</thead>
|
|||
|
<tbody>
|
|||
|
<tr class="row-even"><td>counter</td>
|
|||
|
<td>Callable object that returns counter blocks
|
|||
|
(see below; CTR mode only)</td>
|
|||
|
</tr>
|
|||
|
<tr class="row-odd"><td>rounds</td>
|
|||
|
<td>Number of rounds of encryption to use</td>
|
|||
|
</tr>
|
|||
|
<tr class="row-even"><td>segment_size</td>
|
|||
|
<td>Size of data and ciphertext segments,
|
|||
|
measured in bits (see below; CFB mode only)</td>
|
|||
|
</tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
<p>The Counter feedback mode requires a sequence of input blocks,
|
|||
|
called counters, that are used to produce the output. When ‘mode’
|
|||
|
is MODE_CTR, the ‘counter’ keyword argument must be provided, and
|
|||
|
its value must be a callable object, such as a function or method.
|
|||
|
Successive calls to this callable object must return a sequence of
|
|||
|
strings that are of the length ‘block_size’ and that never
|
|||
|
repeats. (Appendix B of the NIST publication gives a way to
|
|||
|
generate such a sequence, but that’s beyond the scope of this
|
|||
|
PEP.)</p>
|
|||
|
<p>The CFB mode operates on segments of the plaintext and ciphertext
|
|||
|
that are ‘segment_size’ bits long. Therefore, when using this
|
|||
|
mode, the input and output strings must be a multiple of
|
|||
|
‘segment_size’ bits in length. ‘segment_size’ must be an integer
|
|||
|
between 1 and block_size*8, inclusive. (The factor of 8 comes
|
|||
|
from ‘block_size’ being measured in bytes and not in bits). The
|
|||
|
default value for this parameter should be block_size*8.
|
|||
|
Implementors are allowed to constrain ‘segment_size’ to be a
|
|||
|
multiple of 8 for simplicity, but they’re encouraged to support
|
|||
|
arbitrary values for generality.</p>
|
|||
|
<p>Secret-key encryption modules should define two variables:</p>
|
|||
|
<ul>
|
|||
|
<li>block_size<p>An integer value; the size of the blocks encrypted by this
|
|||
|
module, measured in bytes. For all feedback modes, the length
|
|||
|
of strings passed to the encrypt() and decrypt() must be a
|
|||
|
multiple of the block size.</p>
|
|||
|
</li>
|
|||
|
<li>key_size<p>An integer value; the size of the keys required by this
|
|||
|
module, measured in bytes. If key_size is None, then the
|
|||
|
algorithm accepts variable-length keys. This may mean the
|
|||
|
module accepts keys of any random length, or that there are a
|
|||
|
few different possible lengths, e.g. 16, 24, or 32 bytes. You
|
|||
|
cannot pass a key of length 0 (that is, the null string ‘’) as
|
|||
|
a variable-length key.</p>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<p>Cipher objects should have two attributes:</p>
|
|||
|
<ul>
|
|||
|
<li>block_size<p>An integer value equal to the size of the blocks encrypted by
|
|||
|
this object. For algorithms with a variable block size, this
|
|||
|
value is equal to the block size selected for this object.</p>
|
|||
|
</li>
|
|||
|
<li>IV<p>Contains the initial value which will be used to start a
|
|||
|
cipher feedback mode; it will always be a string exactly one
|
|||
|
block in length. After encrypting or decrypting a string,
|
|||
|
this value is updated to reflect the modified feedback text.
|
|||
|
It is read-only, and cannot be assigned a new value.</p>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<p>Cipher objects require the following methods:</p>
|
|||
|
<ul>
|
|||
|
<li>decrypt(string)<p>Decrypts ‘string’, using the key-dependent data in the object
|
|||
|
and with the appropriate feedback mode. The string’s length
|
|||
|
must be an exact multiple of the algorithm’s block size or, in
|
|||
|
CFB mode, of the segment size. Returns a string containing
|
|||
|
the plaintext.</p>
|
|||
|
</li>
|
|||
|
<li>encrypt(string)<p>Encrypts a non-empty string, using the key-dependent data in
|
|||
|
the object, and with the appropriate feedback mode. The
|
|||
|
string’s length must be an exact multiple of the algorithm’s
|
|||
|
block size or, in CFB mode, of the segment size. Returns a
|
|||
|
string containing the ciphertext.</p>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<p>Here’s an example, using a module named ‘DES’:</p>
|
|||
|
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">DES</span>
|
|||
|
<span class="gp">>>> </span><span class="n">obj</span> <span class="o">=</span> <span class="n">DES</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">'abcdefgh'</span><span class="p">,</span> <span class="n">DES</span><span class="o">.</span><span class="n">MODE_ECB</span><span class="p">)</span>
|
|||
|
<span class="gp">>>> </span><span class="n">plaintext</span> <span class="o">=</span> <span class="s2">"Guido van Rossum is a space alien."</span>
|
|||
|
<span class="gp">>>> </span><span class="nb">len</span><span class="p">(</span><span class="n">plaintext</span><span class="p">)</span>
|
|||
|
<span class="go">34</span>
|
|||
|
<span class="gp">>>> </span><span class="n">obj</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">plaintext</span><span class="p">)</span>
|
|||
|
<span class="go">Traceback (innermost last):</span>
|
|||
|
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n">?</span>
|
|||
|
<span class="gr">ValueError</span>: <span class="n">Strings for DES must be a multiple of 8 in length</span>
|
|||
|
<span class="gp">>>> </span><span class="n">ciphertext</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">encrypt</span><span class="p">(</span><span class="n">plain</span><span class="o">+</span><span class="s1">'XXXXXX'</span><span class="p">)</span> <span class="c1"># Add padding</span>
|
|||
|
<span class="gp">>>> </span><span class="n">ciphertext</span>
|
|||
|
<span class="go">'\021,\343Nq\214DY\337T\342pA\372\255\311s\210\363,\300j\330\250\312\347\342I\3215w\03561\303dgb/\006'</span>
|
|||
|
<span class="gp">>>> </span><span class="n">obj</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">ciphertext</span><span class="p">)</span>
|
|||
|
<span class="go">'Guido van Rossum is a space alien.XXXXXX'</span>
|
|||
|
</pre></div>
|
|||
|
</div>
|
|||
|
</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="id3" role="doc-footnote">
|
|||
|
<dt class="label" id="id3">[<a href="#id1">1</a>]</dt>
|
|||
|
<dd>NIST publication SP 800-38A, “Recommendation for Block Cipher
|
|||
|
Modes of Operation” (<a class="reference external" href="http://csrc.nist.gov/encryption/modes/">http://csrc.nist.gov/encryption/modes/</a>)</aside>
|
|||
|
<aside class="footnote brackets" id="id4" role="doc-footnote">
|
|||
|
<dt class="label" id="id4">[<a href="#id2">2</a>]</dt>
|
|||
|
<dd>Applied Cryptography</aside>
|
|||
|
</aside>
|
|||
|
</section>
|
|||
|
<section id="changes">
|
|||
|
<h2><a class="toc-backref" href="#changes" role="doc-backlink">Changes</a></h2>
|
|||
|
<p>2002-04: Removed references to stream ciphers; retitled PEP;
|
|||
|
prefixed feedback mode constants with <code class="docutils literal notranslate"><span class="pre">MODE_</span></code>; removed PGP feedback
|
|||
|
mode; added CTR and OFB feedback modes; clarified where numbers
|
|||
|
are measured in bytes and where in bits.</p>
|
|||
|
<p>2002-09: Clarified the discussion of key length by using
|
|||
|
“variable-length keys” instead of “arbitrary-length”.</p>
|
|||
|
</section>
|
|||
|
<section id="acknowledgements">
|
|||
|
<h2><a class="toc-backref" href="#acknowledgements" role="doc-backlink">Acknowledgements</a></h2>
|
|||
|
<p>Thanks to the readers of the python-crypto list for their comments on
|
|||
|
this PEP.</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-0272.rst">https://github.com/python/peps/blob/main/peps/pep-0272.rst</a></p>
|
|||
|
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0272.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="#introduction">Introduction</a></li>
|
|||
|
<li><a class="reference internal" href="#specification">Specification</a></li>
|
|||
|
<li><a class="reference internal" href="#references">References</a></li>
|
|||
|
<li><a class="reference internal" href="#changes">Changes</a></li>
|
|||
|
<li><a class="reference internal" href="#acknowledgements">Acknowledgements</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-0272.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>
|