CINXE.COM

PEP 100 – Python Unicode Integration | peps.python.org

<!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 100 – Python Unicode Integration | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0100/"> <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 100 – Python Unicode Integration | peps.python.org'> <meta property="og:description" content="The idea of this proposal is to add native Unicode 3.0 support to Python in a way that makes use of Unicode strings as simple as possible without introducing too many pitfalls along the way."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0100/"> <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="The idea of this proposal is to add native Unicode 3.0 support to Python in a way that makes use of Unicode strings as simple as possible without introducing too many pitfalls along the way."> <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 100</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 100 – Python Unicode Integration</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Marc-André Lemburg &lt;mal&#32;&#97;t&#32;lemburg.com&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">Created<span class="colon">:</span></dt> <dd class="field-even">10-Mar-2000</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">2.0</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even"><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="#historical-note">Historical Note</a></li> <li><a class="reference internal" href="#introduction">Introduction</a></li> <li><a class="reference internal" href="#conventions">Conventions</a></li> <li><a class="reference internal" href="#general-remarks">General Remarks</a></li> <li><a class="reference internal" href="#unicode-default-encoding">Unicode Default Encoding</a></li> <li><a class="reference internal" href="#unicode-constructors">Unicode Constructors</a></li> <li><a class="reference internal" href="#unicode-type-object">Unicode Type Object</a></li> <li><a class="reference internal" href="#unicode-output">Unicode Output</a></li> <li><a class="reference internal" href="#unicode-ordinals">Unicode Ordinals</a></li> <li><a class="reference internal" href="#comparison-hash-value">Comparison &amp; Hash Value</a></li> <li><a class="reference internal" href="#coercion">Coercion</a></li> <li><a class="reference internal" href="#exceptions">Exceptions</a></li> <li><a class="reference internal" href="#codecs-coder-decoders-lookup">Codecs (Coder/Decoders) Lookup</a></li> <li><a class="reference internal" href="#standard-codecs">Standard Codecs</a></li> <li><a class="reference internal" href="#codecs-interface-definition">Codecs Interface Definition</a></li> <li><a class="reference internal" href="#whitespace">Whitespace</a></li> <li><a class="reference internal" href="#case-conversion">Case Conversion</a></li> <li><a class="reference internal" href="#line-breaks">Line Breaks</a></li> <li><a class="reference internal" href="#unicode-character-properties">Unicode Character Properties</a></li> <li><a class="reference internal" href="#private-code-point-areas">Private Code Point Areas</a></li> <li><a class="reference internal" href="#internal-format">Internal Format</a></li> <li><a class="reference internal" href="#buffer-interface">Buffer Interface</a></li> <li><a class="reference internal" href="#pickle-marshalling">Pickle/Marshalling</a></li> <li><a class="reference internal" href="#regular-expressions">Regular Expressions</a></li> <li><a class="reference internal" href="#formatting-markers">Formatting Markers</a></li> <li><a class="reference internal" href="#internal-argument-parsing">Internal Argument Parsing</a></li> <li><a class="reference internal" href="#file-stream-output">File/Stream Output</a></li> <li><a class="reference internal" href="#file-stream-input">File/Stream Input</a></li> <li><a class="reference internal" href="#unicode-methods-attributes">Unicode Methods &amp; Attributes</a></li> <li><a class="reference internal" href="#code-base">Code Base</a></li> <li><a class="reference internal" href="#test-cases">Test Cases</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#history-of-this-proposal">History of this Proposal</a><ul> <li><a class="reference internal" href="#id1">1.7</a></li> <li><a class="reference internal" href="#id2">1.6</a></li> <li><a class="reference internal" href="#id3">1.5</a></li> <li><a class="reference internal" href="#id4">1.4</a></li> <li><a class="reference internal" href="#id5">1.3</a></li> <li><a class="reference internal" href="#id6">1.2</a></li> <li><a class="reference internal" href="#id7">1.1</a></li> <li><a class="reference internal" href="#id8">1.0</a></li> <li><a class="reference internal" href="#id9">0.9</a></li> <li><a class="reference internal" href="#id10">0.8</a></li> <li><a class="reference internal" href="#id11">0.7</a></li> <li><a class="reference internal" href="#id12">0.6</a></li> <li><a class="reference internal" href="#id13">0.5</a></li> <li><a class="reference internal" href="#id14">0.4</a></li> <li><a class="reference internal" href="#id15">0.3</a></li> <li><a class="reference internal" href="#id16">0.2</a></li> <li><a class="reference internal" href="#id17">0.1</a></li> </ul> </li> </ul> </details></section> <section id="historical-note"> <h2><a class="toc-backref" href="#historical-note" role="doc-backlink">Historical Note</a></h2> <p>This document was first written by Marc-Andre in the pre-PEP days, and was originally distributed as Misc/unicode.txt in Python distributions up to and included Python 2.1. The last revision of the proposal in that location was labeled version 1.7 (CVS revision 3.10). Because the document clearly serves the purpose of an informational PEP in the post-PEP era, it has been moved here and reformatted to comply with PEP guidelines. Future revisions will be made to this document, while Misc/unicode.txt will contain a pointer to this PEP.</p> <p>-Barry Warsaw, PEP editor</p> </section> <section id="introduction"> <h2><a class="toc-backref" href="#introduction" role="doc-backlink">Introduction</a></h2> <p>The idea of this proposal is to add native Unicode 3.0 support to Python in a way that makes use of Unicode strings as simple as possible without introducing too many pitfalls along the way.</p> <p>Since this goal is not easy to achieve – strings being one of the most fundamental objects in Python – we expect this proposal to undergo some significant refinements.</p> <p>Note that the current version of this proposal is still a bit unsorted due to the many different aspects of the Unicode-Python integration.</p> <p>The latest version of this document is always available at: <a class="reference external" href="http://starship.python.net/~lemburg/unicode-proposal.txt">http://starship.python.net/~lemburg/unicode-proposal.txt</a></p> <p>Older versions are available as: <a class="reference external" href="http://starship.python.net/~lemburg/unicode-proposal-X.X.txt">http://starship.python.net/~lemburg/unicode-proposal-X.X.txt</a></p> <p>[ed. note: new revisions should be made to this PEP document, while the historical record previous to version 1.7 should be retrieved from MAL’s url, or Misc/unicode.txt]</p> </section> <section id="conventions"> <h2><a class="toc-backref" href="#conventions" role="doc-backlink">Conventions</a></h2> <ul class="simple"> <li>In examples we use u = Unicode object and s = Python string</li> <li>‘XXX’ markings indicate points of discussion (PODs)</li> </ul> </section> <section id="general-remarks"> <h2><a class="toc-backref" href="#general-remarks" role="doc-backlink">General Remarks</a></h2> <ul class="simple"> <li>Unicode encoding names should be lower case on output and case-insensitive on input (they will be converted to lower case by all APIs taking an encoding name as input).</li> <li>Encoding names should follow the name conventions as used by the Unicode Consortium: spaces are converted to hyphens, e.g. ‘utf 16’ is written as ‘utf-16’.</li> <li>Codec modules should use the same names, but with hyphens converted to underscores, e.g. <code class="docutils literal notranslate"><span class="pre">utf_8</span></code>, <code class="docutils literal notranslate"><span class="pre">utf_16</span></code>, <code class="docutils literal notranslate"><span class="pre">iso_8859_1</span></code>.</li> </ul> </section> <section id="unicode-default-encoding"> <h2><a class="toc-backref" href="#unicode-default-encoding" role="doc-backlink">Unicode Default Encoding</a></h2> <p>The Unicode implementation has to make some assumption about the encoding of 8-bit strings passed to it for coercion and about the encoding to as default for conversion of Unicode to strings when no specific encoding is given. This encoding is called &lt;default encoding&gt; throughout this text.</p> <p>For this, the implementation maintains a global which can be set in the site.py Python startup script. Subsequent changes are not possible. The &lt;default encoding&gt; can be set and queried using the two sys module APIs:</p> <dl> <dt><code class="docutils literal notranslate"><span class="pre">sys.setdefaultencoding(encoding)</span></code></dt><dd>Sets the &lt;default encoding&gt; used by the Unicode implementation. encoding has to be an encoding which is supported by the Python installation, otherwise, a LookupError is raised.<p>Note: This API is only available in site.py! It is removed from the sys module by site.py after usage.</p> </dd> <dt><code class="docutils literal notranslate"><span class="pre">sys.getdefaultencoding()</span></code></dt><dd>Returns the current &lt;default encoding&gt;.</dd> </dl> <p>If not otherwise defined or set, the &lt;default encoding&gt; defaults to ‘ascii’. This encoding is also the startup default of Python (and in effect before site.py is executed).</p> <p>Note that the default site.py startup module contains disabled optional code which can set the &lt;default encoding&gt; according to the encoding defined by the current locale. The locale module is used to extract the encoding from the locale default settings defined by the OS environment (see locale.py). If the encoding cannot be determined, is unknown or unsupported, the code defaults to setting the &lt;default encoding&gt; to ‘ascii’. To enable this code, edit the site.py file or place the appropriate code into the sitecustomize.py module of your Python installation.</p> </section> <section id="unicode-constructors"> <h2><a class="toc-backref" href="#unicode-constructors" role="doc-backlink">Unicode Constructors</a></h2> <p>Python should provide a built-in constructor for Unicode strings which is available through <code class="docutils literal notranslate"><span class="pre">__builtins__</span></code>:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unicode</span><span class="p">(</span><span class="n">encoded_string</span><span class="p">[,</span><span class="n">encoding</span><span class="o">=&lt;</span><span class="n">default</span> <span class="n">encoding</span><span class="o">&gt;</span><span class="p">][,</span><span class="n">errors</span><span class="o">=</span><span class="s2">&quot;strict&quot;</span><span class="p">])</span> <span class="n">u</span> <span class="o">=</span> <span class="sa">u</span><span class="s1">&#39;&lt;unicode-escape encoded Python string&gt;&#39;</span> <span class="n">u</span> <span class="o">=</span> <span class="n">ur</span><span class="s1">&#39;&lt;raw-unicode-escape encoded Python string&gt;&#39;</span> </pre></div> </div> <p>With the ‘unicode-escape’ encoding being defined as:</p> <ul class="simple"> <li>all non-escape characters represent themselves as Unicode ordinal (e.g. ‘a’ -&gt; U+0061).</li> <li>all existing defined Python escape sequences are interpreted as Unicode ordinals; note that <code class="docutils literal notranslate"><span class="pre">\xXXXX</span></code> can represent all Unicode ordinals, and <code class="docutils literal notranslate"><span class="pre">\OOO</span></code> (octal) can represent Unicode ordinals up to U+01FF.</li> <li>a new escape sequence, <code class="docutils literal notranslate"><span class="pre">\uXXXX</span></code>, represents U+XXXX; it is a syntax error to have fewer than 4 digits after <code class="docutils literal notranslate"><span class="pre">\u</span></code>.</li> </ul> <p>For an explanation of possible values for errors see the Codec section below.</p> <p>Examples:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="sa">u</span><span class="s1">&#39;abc&#39;</span> <span class="o">-&gt;</span> <span class="n">U</span><span class="o">+</span><span class="mi">0061</span> <span class="n">U</span><span class="o">+</span><span class="mi">0062</span> <span class="n">U</span><span class="o">+</span><span class="mi">0063</span> <span class="sa">u</span><span class="s1">&#39;</span><span class="se">\u1234</span><span class="s1">&#39;</span> <span class="o">-&gt;</span> <span class="n">U</span><span class="o">+</span><span class="mi">1234</span> <span class="sa">u</span><span class="s1">&#39;abc</span><span class="se">\u1234\n</span><span class="s1">&#39;</span> <span class="o">-&gt;</span> <span class="n">U</span><span class="o">+</span><span class="mi">0061</span> <span class="n">U</span><span class="o">+</span><span class="mi">0062</span> <span class="n">U</span><span class="o">+</span><span class="mi">0063</span> <span class="n">U</span><span class="o">+</span><span class="mi">1234</span> <span class="n">U</span><span class="o">+</span><span class="mi">005</span><span class="n">c</span> </pre></div> </div> <p>The ‘raw-unicode-escape’ encoding is defined as follows:</p> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">\uXXXX</span></code> sequence represent the U+XXXX Unicode character if and only if the number of leading backslashes is odd</li> <li>all other characters represent themselves as Unicode ordinal (e.g. ‘b’ -&gt; U+0062)</li> </ul> <p>Note that you should provide some hint to the encoding you used to write your programs as pragma line in one the first few comment lines of the source file (e.g. ‘# source file encoding: latin-1’). If you only use 7-bit ASCII then everything is fine and no such notice is needed, but if you include Latin-1 characters not defined in ASCII, it may well be worthwhile including a hint since people in other countries will want to be able to read your source strings too.</p> </section> <section id="unicode-type-object"> <h2><a class="toc-backref" href="#unicode-type-object" role="doc-backlink">Unicode Type Object</a></h2> <p>Unicode objects should have the type UnicodeType with type name ‘unicode’, made available through the standard types module.</p> </section> <section id="unicode-output"> <h2><a class="toc-backref" href="#unicode-output" role="doc-backlink">Unicode Output</a></h2> <p>Unicode objects have a method .encode([encoding=&lt;default encoding&gt;]) which returns a Python string encoding the Unicode string using the given scheme (see Codecs).</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">u</span> <span class="o">:=</span> <span class="nb">print</span> <span class="n">u</span><span class="o">.</span><span class="n">encode</span><span class="p">()</span> <span class="c1"># using the &lt;default encoding&gt;</span> <span class="nb">str</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">:=</span> <span class="n">u</span><span class="o">.</span><span class="n">encode</span><span class="p">()</span> <span class="c1"># using the &lt;default encoding&gt;</span> <span class="nb">repr</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">:=</span> <span class="s2">&quot;u</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">repr</span><span class="p">(</span><span class="n">u</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;unicode-escape&#39;</span><span class="p">))</span> </pre></div> </div> <p>Also see Internal Argument Parsing and Buffer Interface for details on how other APIs written in C will treat Unicode objects.</p> </section> <section id="unicode-ordinals"> <h2><a class="toc-backref" href="#unicode-ordinals" role="doc-backlink">Unicode Ordinals</a></h2> <p>Since Unicode 3.0 has a 32-bit ordinal character set, the implementation should provide 32-bit aware ordinal conversion APIs:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">ord</span><span class="p">(</span><span class="n">u</span><span class="p">[:</span><span class="mi">1</span><span class="p">])</span> <span class="p">(</span><span class="n">this</span> <span class="ow">is</span> <span class="n">the</span> <span class="n">standard</span> <span class="nb">ord</span><span class="p">()</span> <span class="n">extended</span> <span class="n">to</span> <span class="n">work</span> <span class="k">with</span> <span class="n">Unicode</span> <span class="n">objects</span><span class="p">)</span> <span class="o">--&gt;</span> <span class="n">Unicode</span> <span class="n">ordinal</span> <span class="n">number</span> <span class="p">(</span><span class="mi">32</span><span class="o">-</span><span class="n">bit</span><span class="p">)</span> <span class="n">unichr</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">--&gt;</span> <span class="n">Unicode</span> <span class="nb">object</span> <span class="k">for</span> <span class="n">character</span> <span class="n">i</span> <span class="p">(</span><span class="n">provided</span> <span class="n">it</span> <span class="ow">is</span> <span class="mi">32</span><span class="o">-</span><span class="n">bit</span><span class="p">);</span> <span class="ne">ValueError</span> <span class="n">otherwise</span> </pre></div> </div> <p>Both APIs should go into <code class="docutils literal notranslate"><span class="pre">__builtins__</span></code> just like their string counterparts <code class="docutils literal notranslate"><span class="pre">ord()</span></code> and <code class="docutils literal notranslate"><span class="pre">chr()</span></code>.</p> <p>Note that Unicode provides space for private encodings. Usage of these can cause different output representations on different machines. This problem is not a Python or Unicode problem, but a machine setup and maintenance one.</p> </section> <section id="comparison-hash-value"> <h2><a class="toc-backref" href="#comparison-hash-value" role="doc-backlink">Comparison &amp; Hash Value</a></h2> <p>Unicode objects should compare equal to other objects after these other objects have been coerced to Unicode. For strings this means that they are interpreted as Unicode string using the &lt;default encoding&gt;.</p> <p>Unicode objects should return the same hash value as their ASCII equivalent strings. Unicode strings holding non-ASCII values are not guaranteed to return the same hash values as the default encoded equivalent string representation.</p> <p>When compared using <code class="docutils literal notranslate"><span class="pre">cmp()</span></code> (or <code class="docutils literal notranslate"><span class="pre">PyObject_Compare()</span></code>) the implementation should mask <code class="docutils literal notranslate"><span class="pre">TypeErrors</span></code> raised during the conversion to remain in synch with the string behavior. All other errors such as <code class="docutils literal notranslate"><span class="pre">ValueErrors</span></code> raised during coercion of strings to Unicode should not be masked and passed through to the user.</p> <p>In containment tests (‘a’ in u’abc’ and u’a’ in ‘abc’) both sides should be coerced to Unicode before applying the test. Errors occurring during coercion (e.g. None in u’abc’) should not be masked.</p> </section> <section id="coercion"> <h2><a class="toc-backref" href="#coercion" role="doc-backlink">Coercion</a></h2> <p>Using Python strings and Unicode objects to form new objects should always coerce to the more precise format, i.e. Unicode objects.</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">+</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">u</span> <span class="o">+</span> <span class="n">unicode</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="n">s</span> <span class="o">+</span> <span class="n">u</span> <span class="o">:=</span> <span class="n">unicode</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">+</span> <span class="n">u</span> </pre></div> </div> <p>All string methods should delegate the call to an equivalent Unicode object method call by converting all involved strings to Unicode and then applying the arguments to the Unicode method of the same name, e.g.</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">string</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">s</span><span class="p">,</span><span class="n">u</span><span class="p">),</span><span class="n">sep</span><span class="p">)</span> <span class="o">:=</span> <span class="p">(</span><span class="n">s</span> <span class="o">+</span> <span class="n">sep</span><span class="p">)</span> <span class="o">+</span> <span class="n">u</span> <span class="n">sep</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">s</span><span class="p">,</span><span class="n">u</span><span class="p">))</span> <span class="o">:=</span> <span class="p">(</span><span class="n">s</span> <span class="o">+</span> <span class="n">sep</span><span class="p">)</span> <span class="o">+</span> <span class="n">u</span> </pre></div> </div> <p>For a discussion of %-formatting w/r to Unicode objects, see Formatting Markers.</p> </section> <section id="exceptions"> <h2><a class="toc-backref" href="#exceptions" role="doc-backlink">Exceptions</a></h2> <p><code class="docutils literal notranslate"><span class="pre">UnicodeError</span></code> is defined in the exceptions module as a subclass of <code class="docutils literal notranslate"><span class="pre">ValueError</span></code>. It is available at the C level via <code class="docutils literal notranslate"><span class="pre">PyExc_UnicodeError</span></code>. All exceptions related to Unicode encoding/decoding should be subclasses of <code class="docutils literal notranslate"><span class="pre">UnicodeError</span></code>.</p> </section> <section id="codecs-coder-decoders-lookup"> <h2><a class="toc-backref" href="#codecs-coder-decoders-lookup" role="doc-backlink">Codecs (Coder/Decoders) Lookup</a></h2> <p>A Codec (see Codec Interface Definition) search registry should be implemented by a module “codecs”:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">codecs</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">search_function</span><span class="p">)</span> </pre></div> </div> <p>Search functions are expected to take one argument, the encoding name in all lower case letters and with hyphens and spaces converted to underscores, and return a tuple of functions (encoder, decoder, stream_reader, stream_writer) taking the following arguments:</p> <dl> <dt>encoder and decoder</dt><dd>These must be functions or methods which have the same interface as the <code class="docutils literal notranslate"><span class="pre">.encode</span></code>/<code class="docutils literal notranslate"><span class="pre">.decode</span></code> methods of Codec instances (see Codec Interface). The functions/methods are expected to work in a stateless mode.</dd> <dt>stream_reader and stream_writer</dt><dd>These need to be factory functions with the following interface:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">factory</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span><span class="n">errors</span><span class="o">=</span><span class="s1">&#39;strict&#39;</span><span class="p">)</span> </pre></div> </div> <p>The factory functions must return objects providing the interfaces defined by <code class="docutils literal notranslate"><span class="pre">StreamWriter</span></code>/<code class="docutils literal notranslate"><span class="pre">StreamReader</span></code> resp. (see Codec Interface). Stream codecs can maintain state.</p> <p>Possible values for errors are defined in the Codec section below.</p> </dd> </dl> <p>In case a search function cannot find a given encoding, it should return None.</p> <p>Aliasing support for encodings is left to the search functions to implement.</p> <p>The codecs module will maintain an encoding cache for performance reasons. Encodings are first looked up in the cache. If not found, the list of registered search functions is scanned. If no codecs tuple is found, a LookupError is raised. Otherwise, the codecs tuple is stored in the cache and returned to the caller.</p> <p>To query the Codec instance the following API should be used:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">codecs</span><span class="o">.</span><span class="n">lookup</span><span class="p">(</span><span class="n">encoding</span><span class="p">)</span> </pre></div> </div> <p>This will either return the found codecs tuple or raise a <code class="docutils literal notranslate"><span class="pre">LookupError</span></code>.</p> </section> <section id="standard-codecs"> <h2><a class="toc-backref" href="#standard-codecs" role="doc-backlink">Standard Codecs</a></h2> <p>Standard codecs should live inside an encodings/ package directory in the Standard Python Code Library. The <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> file of that directory should include a Codec Lookup compatible search function implementing a lazy module based codec lookup.</p> <p>Python should provide a few standard codecs for the most relevant encodings, e.g.</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;utf-8&#39;</span><span class="p">:</span> <span class="mi">8</span><span class="o">-</span><span class="n">bit</span> <span class="n">variable</span> <span class="n">length</span> <span class="n">encoding</span> <span class="s1">&#39;utf-16&#39;</span><span class="p">:</span> <span class="mi">16</span><span class="o">-</span><span class="n">bit</span> <span class="n">variable</span> <span class="n">length</span> <span class="n">encoding</span> <span class="p">(</span><span class="n">little</span><span class="o">/</span><span class="n">big</span> <span class="n">endian</span><span class="p">)</span> <span class="s1">&#39;utf-16-le&#39;</span><span class="p">:</span> <span class="n">utf</span><span class="o">-</span><span class="mi">16</span> <span class="n">but</span> <span class="n">explicitly</span> <span class="n">little</span> <span class="n">endian</span> <span class="s1">&#39;utf-16-be&#39;</span><span class="p">:</span> <span class="n">utf</span><span class="o">-</span><span class="mi">16</span> <span class="n">but</span> <span class="n">explicitly</span> <span class="n">big</span> <span class="n">endian</span> <span class="s1">&#39;ascii&#39;</span><span class="p">:</span> <span class="mi">7</span><span class="o">-</span><span class="n">bit</span> <span class="n">ASCII</span> <span class="n">codepage</span> <span class="s1">&#39;iso-8859-1&#39;</span><span class="p">:</span> <span class="n">ISO</span> <span class="mi">8859</span><span class="o">-</span><span class="mi">1</span> <span class="p">(</span><span class="n">Latin</span> <span class="mi">1</span><span class="p">)</span> <span class="n">codepage</span> <span class="s1">&#39;unicode-escape&#39;</span><span class="p">:</span> <span class="n">See</span> <span class="n">Unicode</span> <span class="n">Constructors</span> <span class="k">for</span> <span class="n">a</span> <span class="n">definition</span> <span class="s1">&#39;raw-unicode-escape&#39;</span><span class="p">:</span> <span class="n">See</span> <span class="n">Unicode</span> <span class="n">Constructors</span> <span class="k">for</span> <span class="n">a</span> <span class="n">definition</span> <span class="s1">&#39;native&#39;</span><span class="p">:</span> <span class="n">Dump</span> <span class="n">of</span> <span class="n">the</span> <span class="n">Internal</span> <span class="n">Format</span> <span class="n">used</span> <span class="n">by</span> <span class="n">Python</span> </pre></div> </div> <p>Common aliases should also be provided per default, e.g. ‘latin-1’ for ‘iso-8859-1’.</p> <p>Note: ‘utf-16’ should be implemented by using and requiring byte order marks (BOM) for file input/output.</p> <p>All other encodings such as the CJK ones to support Asian scripts should be implemented in separate packages which do not get included in the core Python distribution and are not a part of this proposal.</p> </section> <section id="codecs-interface-definition"> <h2><a class="toc-backref" href="#codecs-interface-definition" role="doc-backlink">Codecs Interface Definition</a></h2> <p>The following base class should be defined in the module “codecs”. They provide not only templates for use by encoding module implementors, but also define the interface which is expected by the Unicode implementation.</p> <p>Note that the Codec Interface defined here is well suitable for a larger range of applications. The Unicode implementation expects Unicode objects on input for <code class="docutils literal notranslate"><span class="pre">.encode()</span></code> and <code class="docutils literal notranslate"><span class="pre">.write()</span></code> and character buffer compatible objects on input for <code class="docutils literal notranslate"><span class="pre">.decode()</span></code>. Output of <code class="docutils literal notranslate"><span class="pre">.encode()</span></code> and <code class="docutils literal notranslate"><span class="pre">.read()</span></code> should be a Python string and <code class="docutils literal notranslate"><span class="pre">.decode()</span></code> must return an Unicode object.</p> <p>First, we have the stateless encoders/decoders. These do not work in chunks as the stream codecs (see below) do, because all components are expected to be available in memory.</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">Codec</span><span class="p">:</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Defines the interface for stateless encoders/decoders.</span> <span class="sd"> The .encode()/.decode() methods may implement different</span> <span class="sd"> error handling schemes by providing the errors argument.</span> <span class="sd"> These string values are defined:</span> <span class="sd"> &#39;strict&#39; - raise an error (or a subclass)</span> <span class="sd"> &#39;ignore&#39; - ignore the character and continue with the next</span> <span class="sd"> &#39;replace&#39; - replace with a suitable replacement character;</span> <span class="sd"> Python will use the official U+FFFD</span> <span class="sd"> REPLACEMENT CHARACTER for the builtin Unicode</span> <span class="sd"> codecs.</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">def</span><span class="w"> </span><span class="nf">encode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="nb">input</span><span class="p">,</span><span class="n">errors</span><span class="o">=</span><span class="s1">&#39;strict&#39;</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Encodes the object input and returns a tuple (output</span> <span class="sd"> object, length consumed).</span> <span class="sd"> errors defines the error handling to apply. It</span> <span class="sd"> defaults to &#39;strict&#39; handling.</span> <span class="sd"> The method may not store state in the Codec instance.</span> <span class="sd"> Use StreamCodec for codecs which have to keep state in</span> <span class="sd"> order to make encoding/decoding efficient.</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">def</span><span class="w"> </span><span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="nb">input</span><span class="p">,</span><span class="n">errors</span><span class="o">=</span><span class="s1">&#39;strict&#39;</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Decodes the object input and returns a tuple (output</span> <span class="sd"> object, length consumed).</span> <span class="sd"> input must be an object which provides the</span> <span class="sd"> bf_getreadbuf buffer slot. Python strings, buffer</span> <span class="sd"> objects and memory mapped files are examples of objects</span> <span class="sd"> providing this slot.</span> <span class="sd"> errors defines the error handling to apply. It</span> <span class="sd"> defaults to &#39;strict&#39; handling.</span> <span class="sd"> The method may not store state in the Codec instance.</span> <span class="sd"> Use StreamCodec for codecs which have to keep state in</span> <span class="sd"> order to make encoding/decoding efficient.</span> <span class="sd"> &quot;&quot;&quot;</span> </pre></div> </div> <p><code class="docutils literal notranslate"><span class="pre">StreamWriter</span></code> and <code class="docutils literal notranslate"><span class="pre">StreamReader</span></code> define the interface for stateful encoders/decoders which work on streams. These allow processing of the data in chunks to efficiently use memory. If you have large strings in memory, you may want to wrap them with <code class="docutils literal notranslate"><span class="pre">cStringIO</span></code> objects and then use these codecs on them to be able to do chunk processing as well, e.g. to provide progress information to the user.</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">StreamWriter</span><span class="p">(</span><span class="n">Codec</span><span class="p">):</span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">stream</span><span class="p">,</span><span class="n">errors</span><span class="o">=</span><span class="s1">&#39;strict&#39;</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Creates a StreamWriter instance.</span> <span class="sd"> stream must be a file-like object open for writing</span> <span class="sd"> (binary) data.</span> <span class="sd"> The StreamWriter may implement different error handling</span> <span class="sd"> schemes by providing the errors keyword argument.</span> <span class="sd"> These parameters are defined:</span> <span class="sd"> &#39;strict&#39; - raise a ValueError (or a subclass)</span> <span class="sd"> &#39;ignore&#39; - ignore the character and continue with the next</span> <span class="sd"> &#39;replace&#39;- replace with a suitable replacement character</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span> <span class="o">=</span> <span class="n">stream</span> <span class="bp">self</span><span class="o">.</span><span class="n">errors</span> <span class="o">=</span> <span class="n">errors</span> <span class="k">def</span><span class="w"> </span><span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="nb">object</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Writes the object&#39;s contents encoded to self.stream.</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="n">data</span><span class="p">,</span> <span class="n">consumed</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span><span class="bp">self</span><span class="o">.</span><span class="n">errors</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">writelines</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Writes the concatenated list of strings to the stream</span> <span class="sd"> using .write().</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="bp">self</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">list</span><span class="p">))</span> <span class="k">def</span><span class="w"> </span><span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Flushes and resets the codec buffers used for keeping state.</span> <span class="sd"> Calling this method should ensure that the data on the</span> <span class="sd"> output is put into a clean state, that allows appending</span> <span class="sd"> of new fresh data without having to rescan the whole</span> <span class="sd"> stream to recover state.</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">pass</span> <span class="k">def</span><span class="w"> </span><span class="fm">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">name</span><span class="p">,</span> <span class="nb">getattr</span><span class="o">=</span><span class="nb">getattr</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Inherit all other methods from the underlying stream.</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="p">,</span><span class="n">name</span><span class="p">)</span> <span class="k">class</span><span class="w"> </span><span class="nc">StreamReader</span><span class="p">(</span><span class="n">Codec</span><span class="p">):</span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">stream</span><span class="p">,</span><span class="n">errors</span><span class="o">=</span><span class="s1">&#39;strict&#39;</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Creates a StreamReader instance.</span> <span class="sd"> stream must be a file-like object open for reading</span> <span class="sd"> (binary) data.</span> <span class="sd"> The StreamReader may implement different error handling</span> <span class="sd"> schemes by providing the errors keyword argument.</span> <span class="sd"> These parameters are defined:</span> <span class="sd"> &#39;strict&#39; - raise a ValueError (or a subclass)</span> <span class="sd"> &#39;ignore&#39; - ignore the character and continue with the next</span> <span class="sd"> &#39;replace&#39;- replace with a suitable replacement character;</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span> <span class="o">=</span> <span class="n">stream</span> <span class="bp">self</span><span class="o">.</span><span class="n">errors</span> <span class="o">=</span> <span class="n">errors</span> <span class="k">def</span><span class="w"> </span><span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">size</span><span class="o">=-</span><span class="mi">1</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Decodes data from the stream self.stream and returns the</span> <span class="sd"> resulting object.</span> <span class="sd"> size indicates the approximate maximum number of bytes</span> <span class="sd"> to read from the stream for decoding purposes. The</span> <span class="sd"> decoder can modify this setting as appropriate. The</span> <span class="sd"> default value -1 indicates to read and decode as much</span> <span class="sd"> as possible. size is intended to prevent having to</span> <span class="sd"> decode huge files in one step.</span> <span class="sd"> The method should use a greedy read strategy meaning</span> <span class="sd"> that it should read as much data as is allowed within</span> <span class="sd"> the definition of the encoding and the given size, e.g.</span> <span class="sd"> if optional encoding endings or state markers are</span> <span class="sd"> available on the stream, these should be read too.</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="c1"># Unsliced reading:</span> <span class="k">if</span> <span class="n">size</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="o">.</span><span class="n">read</span><span class="p">())[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># Sliced reading:</span> <span class="n">read</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="o">.</span><span class="n">read</span> <span class="n">decode</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">decode</span> <span class="n">data</span> <span class="o">=</span> <span class="n">read</span><span class="p">(</span><span class="n">size</span><span class="p">)</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">while</span> <span class="mi">1</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="nb">object</span><span class="p">,</span> <span class="n">decodedbytes</span> <span class="o">=</span> <span class="n">decode</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">,</span><span class="n">why</span><span class="p">:</span> <span class="c1"># This method is slow but should work under pretty</span> <span class="c1"># much all conditions; at most 10 tries are made</span> <span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span> <span class="n">newdata</span> <span class="o">=</span> <span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">newdata</span> <span class="ow">or</span> <span class="n">i</span> <span class="o">&gt;</span> <span class="mi">10</span><span class="p">:</span> <span class="k">raise</span> <span class="n">data</span> <span class="o">=</span> <span class="n">data</span> <span class="o">+</span> <span class="n">newdata</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="nb">object</span> <span class="k">def</span><span class="w"> </span><span class="nf">readline</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Read one line from the input stream and return the</span> <span class="sd"> decoded data.</span> <span class="sd"> Note: Unlike the .readlines() method, this method</span> <span class="sd"> inherits the line breaking knowledge from the</span> <span class="sd"> underlying stream&#39;s .readline() method -- there is</span> <span class="sd"> currently no support for line breaking using the codec</span> <span class="sd"> decoder due to lack of line buffering. Subclasses</span> <span class="sd"> should however, if possible, try to implement this</span> <span class="sd"> method using their own knowledge of line breaking.</span> <span class="sd"> size, if given, is passed as size argument to the</span> <span class="sd"> stream&#39;s .readline() method.</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">if</span> <span class="n">size</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">line</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span> <span class="k">else</span><span class="p">:</span> <span class="n">line</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="o">.</span><span class="n">readline</span><span class="p">(</span><span class="n">size</span><span class="p">)</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">line</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="k">def</span><span class="w"> </span><span class="nf">readlines</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sizehint</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Read all lines available on the input stream</span> <span class="sd"> and return them as list of lines.</span> <span class="sd"> Line breaks are implemented using the codec&#39;s decoder</span> <span class="sd"> method and are included in the list entries.</span> <span class="sd"> sizehint, if given, is passed as size argument to the</span> <span class="sd"> stream&#39;s .read() method.</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">if</span> <span class="n">sizehint</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> <span class="k">else</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">sizehint</span><span class="p">)</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">data</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">splitlines</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Resets the codec buffers used for keeping state.</span> <span class="sd"> Note that no stream repositioning should take place.</span> <span class="sd"> This method is primarily intended to be able to recover</span> <span class="sd"> from decoding errors.</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">pass</span> <span class="k">def</span><span class="w"> </span><span class="fm">__getattr__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">name</span><span class="p">,</span> <span class="nb">getattr</span><span class="o">=</span><span class="nb">getattr</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot; Inherit all other methods from the underlying stream.</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="p">,</span><span class="n">name</span><span class="p">)</span> </pre></div> </div> <p>Stream codec implementors are free to combine the <code class="docutils literal notranslate"><span class="pre">StreamWriter</span></code> and <code class="docutils literal notranslate"><span class="pre">StreamReader</span></code> interfaces into one class. Even combining all these with the Codec class should be possible.</p> <p>Implementors are free to add additional methods to enhance the codec functionality or provide extra state information needed for them to work. The internal codec implementation will only use the above interfaces, though.</p> <p>It is not required by the Unicode implementation to use these base classes, only the interfaces must match; this allows writing Codecs as extension types.</p> <p>As guideline, large mapping tables should be implemented using static C data in separate (shared) extension modules. That way multiple processes can share the same data.</p> <p>A tool to auto-convert Unicode mapping files to mapping modules should be provided to simplify support for additional mappings (see References).</p> </section> <section id="whitespace"> <h2><a class="toc-backref" href="#whitespace" role="doc-backlink">Whitespace</a></h2> <p>The <code class="docutils literal notranslate"><span class="pre">.split()</span></code> method will have to know about what is considered whitespace in Unicode.</p> </section> <section id="case-conversion"> <h2><a class="toc-backref" href="#case-conversion" role="doc-backlink">Case Conversion</a></h2> <p>Case conversion is rather complicated with Unicode data, since there are many different conditions to respect. See</p> <blockquote> <div><a class="reference external" href="http://www.unicode.org/unicode/reports/tr13/">http://www.unicode.org/unicode/reports/tr13/</a></div></blockquote> <p>for some guidelines on implementing case conversion.</p> <p>For Python, we should only implement the 1-1 conversions included in Unicode. Locale dependent and other special case conversions (see the Unicode standard file SpecialCasing.txt) should be left to user land routines and not go into the core interpreter.</p> <p>The methods <code class="docutils literal notranslate"><span class="pre">.capitalize()</span></code> and <code class="docutils literal notranslate"><span class="pre">.iscapitalized()</span></code> should follow the case mapping algorithm defined in the above technical report as closely as possible.</p> </section> <section id="line-breaks"> <h2><a class="toc-backref" href="#line-breaks" role="doc-backlink">Line Breaks</a></h2> <p>Line breaking should be done for all Unicode characters having the B property as well as the combinations CRLF, CR, LF (interpreted in that order) and other special line separators defined by the standard.</p> <p>The Unicode type should provide a <code class="docutils literal notranslate"><span class="pre">.splitlines()</span></code> method which returns a list of lines according to the above specification. See Unicode Methods.</p> </section> <section id="unicode-character-properties"> <h2><a class="toc-backref" href="#unicode-character-properties" role="doc-backlink">Unicode Character Properties</a></h2> <p>A separate module “unicodedata” should provide a compact interface to all Unicode character properties defined in the standard’s UnicodeData.txt file.</p> <p>Among other things, these properties provide ways to recognize numbers, digits, spaces, whitespace, etc.</p> <p>Since this module will have to provide access to all Unicode characters, it will eventually have to contain the data from UnicodeData.txt which takes up around 600kB. For this reason, the data should be stored in static C data. This enables compilation as shared module which the underlying OS can shared between processes (unlike normal Python code modules).</p> <p>There should be a standard Python interface for accessing this information so that other implementors can plug in their own possibly enhanced versions, e.g. ones that do decompressing of the data on-the-fly.</p> </section> <section id="private-code-point-areas"> <h2><a class="toc-backref" href="#private-code-point-areas" role="doc-backlink">Private Code Point Areas</a></h2> <p>Support for these is left to user land Codecs and not explicitly integrated into the core. Note that due to the Internal Format being implemented, only the area between <code class="docutils literal notranslate"><span class="pre">\uE000</span></code> and <code class="docutils literal notranslate"><span class="pre">\uF8FF</span></code> is usable for private encodings.</p> </section> <section id="internal-format"> <h2><a class="toc-backref" href="#internal-format" role="doc-backlink">Internal Format</a></h2> <p>The internal format for Unicode objects should use a Python specific fixed format &lt;PythonUnicode&gt; implemented as ‘unsigned short’ (or another unsigned numeric type having 16 bits). Byte order is platform dependent.</p> <p>This format will hold UTF-16 encodings of the corresponding Unicode ordinals. The Python Unicode implementation will address these values as if they were UCS-2 values. UCS-2 and UTF-16 are the same for all currently defined Unicode character points. UTF-16 without surrogates provides access to about 64k characters and covers all characters in the Basic Multilingual Plane (BMP) of Unicode.</p> <p>It is the Codec’s responsibility to ensure that the data they pass to the Unicode object constructor respects this assumption. The constructor does not check the data for Unicode compliance or use of surrogates.</p> <p>Future implementations can extend the 32 bit restriction to the full set of all UTF-16 addressable characters (around 1M characters).</p> <p>The Unicode API should provide interface routines from &lt;PythonUnicode&gt; to the compiler’s wchar_t which can be 16 or 32 bit depending on the compiler/libc/platform being used.</p> <p>Unicode objects should have a pointer to a cached Python string object &lt;defenc&gt; holding the object’s value using the &lt;default encoding&gt;. This is needed for performance and internal parsing (see Internal Argument Parsing) reasons. The buffer is filled when the first conversion request to the &lt;default encoding&gt; is issued on the object.</p> <p>Interning is not needed (for now), since Python identifiers are defined as being ASCII only.</p> <p><code class="docutils literal notranslate"><span class="pre">codecs.BOM</span></code> should return the byte order mark (BOM) for the format used internally. The codecs module should provide the following additional constants for convenience and reference (<code class="docutils literal notranslate"><span class="pre">codecs.BOM</span></code> will either be <code class="docutils literal notranslate"><span class="pre">BOM_BE</span></code> or <code class="docutils literal notranslate"><span class="pre">BOM_LE</span></code> depending on the platform):</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">BOM_BE</span><span class="p">:</span> <span class="s1">&#39;</span><span class="se">\376\377</span><span class="s1">&#39;</span> <span class="p">(</span><span class="n">corresponds</span> <span class="n">to</span> <span class="n">Unicode</span> <span class="n">U</span><span class="o">+</span><span class="mi">0000</span><span class="n">FEFF</span> <span class="ow">in</span> <span class="n">UTF</span><span class="o">-</span><span class="mi">16</span> <span class="n">on</span> <span class="n">big</span> <span class="n">endian</span> <span class="n">platforms</span> <span class="o">==</span> <span class="n">ZERO</span> <span class="n">WIDTH</span> <span class="n">NO</span><span class="o">-</span><span class="n">BREAK</span> <span class="n">SPACE</span><span class="p">)</span> <span class="n">BOM_LE</span><span class="p">:</span> <span class="s1">&#39;</span><span class="se">\377\376</span><span class="s1">&#39;</span> <span class="p">(</span><span class="n">corresponds</span> <span class="n">to</span> <span class="n">Unicode</span> <span class="n">U</span><span class="o">+</span><span class="mi">0000</span><span class="n">FFFE</span> <span class="ow">in</span> <span class="n">UTF</span><span class="o">-</span><span class="mi">16</span> <span class="n">on</span> <span class="n">little</span> <span class="n">endian</span> <span class="n">platforms</span> <span class="o">==</span> <span class="n">defined</span> <span class="k">as</span> <span class="n">being</span> <span class="n">an</span> <span class="n">illegal</span> <span class="n">Unicode</span> <span class="n">character</span><span class="p">)</span> <span class="n">BOM4_BE</span><span class="p">:</span> <span class="s1">&#39;</span><span class="se">\000\000\376\377</span><span class="s1">&#39;</span> <span class="p">(</span><span class="n">corresponds</span> <span class="n">to</span> <span class="n">Unicode</span> <span class="n">U</span><span class="o">+</span><span class="mi">0000</span><span class="n">FEFF</span> <span class="ow">in</span> <span class="n">UCS</span><span class="o">-</span><span class="mi">4</span><span class="p">)</span> <span class="n">BOM4_LE</span><span class="p">:</span> <span class="s1">&#39;</span><span class="se">\377\376\000\000</span><span class="s1">&#39;</span> <span class="p">(</span><span class="n">corresponds</span> <span class="n">to</span> <span class="n">Unicode</span> <span class="n">U</span><span class="o">+</span><span class="mi">0000</span><span class="n">FFFE</span> <span class="ow">in</span> <span class="n">UCS</span><span class="o">-</span><span class="mi">4</span><span class="p">)</span> </pre></div> </div> <p>Note that Unicode sees big endian byte order as being “correct”. The swapped order is taken to be an indicator for a “wrong” format, hence the illegal character definition.</p> <p>The configure script should provide aid in deciding whether Python can use the native <code class="docutils literal notranslate"><span class="pre">wchar_t</span></code> type or not (it has to be a 16-bit unsigned type).</p> </section> <section id="buffer-interface"> <h2><a class="toc-backref" href="#buffer-interface" role="doc-backlink">Buffer Interface</a></h2> <p>Implement the buffer interface using the &lt;defenc&gt; Python string object as basis for <code class="docutils literal notranslate"><span class="pre">bf_getcharbuf</span></code> and the internal buffer for <code class="docutils literal notranslate"><span class="pre">bf_getreadbuf</span></code>. If <code class="docutils literal notranslate"><span class="pre">bf_getcharbuf</span></code> is requested and the &lt;defenc&gt; object does not yet exist, it is created first.</p> <p>Note that as special case, the parser marker “s#” will not return raw Unicode UTF-16 data (which the <code class="docutils literal notranslate"><span class="pre">bf_getreadbuf</span></code> returns), but instead tries to encode the Unicode object using the default encoding and then returns a pointer to the resulting string object (or raises an exception in case the conversion fails). This was done in order to prevent accidentally writing binary data to an output stream which the other end might not recognize.</p> <p>This has the advantage of being able to write to output streams (which typically use this interface) without additional specification of the encoding to use.</p> <p>If you need to access the read buffer interface of Unicode objects, use the <code class="docutils literal notranslate"><span class="pre">PyObject_AsReadBuffer()</span></code> interface.</p> <p>The internal format can also be accessed using the ‘unicode-internal’ codec, e.g. via <code class="docutils literal notranslate"><span class="pre">u.encode('unicode-internal')</span></code>.</p> </section> <section id="pickle-marshalling"> <h2><a class="toc-backref" href="#pickle-marshalling" role="doc-backlink">Pickle/Marshalling</a></h2> <p>Should have native Unicode object support. The objects should be encoded using platform independent encodings.</p> <p>Marshal should use UTF-8 and Pickle should either choose Raw-Unicode-Escape (in text mode) or UTF-8 (in binary mode) as encoding. Using UTF-8 instead of UTF-16 has the advantage of eliminating the need to store a BOM mark.</p> </section> <section id="regular-expressions"> <h2><a class="toc-backref" href="#regular-expressions" role="doc-backlink">Regular Expressions</a></h2> <p>Secret Labs AB is working on a Unicode-aware regular expression machinery. It works on plain 8-bit, UCS-2, and (optionally) UCS-4 internal character buffers.</p> <p>Also see</p> <blockquote> <div><a class="reference external" href="http://www.unicode.org/unicode/reports/tr18/">http://www.unicode.org/unicode/reports/tr18/</a></div></blockquote> <p>for some remarks on how to treat Unicode REs.</p> </section> <section id="formatting-markers"> <h2><a class="toc-backref" href="#formatting-markers" role="doc-backlink">Formatting Markers</a></h2> <p>Format markers are used in Python format strings. If Python strings are used as format strings, the following interpretations should be in effect:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;</span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">:</span> <span class="n">For</span> <span class="n">Unicode</span> <span class="n">objects</span> <span class="n">this</span> <span class="n">will</span> <span class="n">cause</span> <span class="n">coercion</span> <span class="n">of</span> <span class="n">the</span> <span class="n">whole</span> <span class="nb">format</span> <span class="n">string</span> <span class="n">to</span> <span class="n">Unicode</span><span class="o">.</span> <span class="n">Note</span> <span class="n">that</span> <span class="n">you</span> <span class="n">should</span> <span class="n">use</span> <span class="n">a</span> <span class="n">Unicode</span> <span class="nb">format</span> <span class="n">string</span> <span class="n">to</span> <span class="n">start</span> <span class="k">with</span> <span class="k">for</span> <span class="n">performance</span> <span class="n">reasons</span><span class="o">.</span> </pre></div> </div> <p>In case the format string is an Unicode object, all parameters are coerced to Unicode first and then put together and formatted according to the format string. Numbers are first converted to strings and then to Unicode.</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;</span><span class="si">%s</span><span class="s1">&#39;</span><span class="p">:</span> <span class="n">Python</span> <span class="n">strings</span> <span class="n">are</span> <span class="n">interpreted</span> <span class="k">as</span> <span class="n">Unicode</span> <span class="n">string</span> <span class="n">using</span> <span class="n">the</span> <span class="o">&lt;</span><span class="n">default</span> <span class="n">encoding</span><span class="o">&gt;.</span> <span class="n">Unicode</span> <span class="n">objects</span> <span class="n">are</span> <span class="n">taken</span> <span class="k">as</span> <span class="ow">is</span><span class="o">.</span> </pre></div> </div> <p>All other string formatters should work accordingly.</p> <p>Example:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="sa">u</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="sa">u</span><span class="s2">&quot;abc&quot;</span><span class="p">,</span> <span class="s2">&quot;abc&quot;</span><span class="p">)</span> <span class="o">==</span> <span class="sa">u</span><span class="s2">&quot;abc abc&quot;</span> </pre></div> </div> </section> <section id="internal-argument-parsing"> <h2><a class="toc-backref" href="#internal-argument-parsing" role="doc-backlink">Internal Argument Parsing</a></h2> <p>These markers are used by the <code class="docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code> APIs:</p> <dl> <dt>“U”</dt><dd>Check for Unicode object and return a pointer to it</dd> <dt>“s”</dt><dd>For Unicode objects: return a pointer to the object’s &lt;defenc&gt; buffer (which uses the &lt;default encoding&gt;).</dd> <dt>“s#”</dt><dd>Access to the default encoded version of the Unicode object (see Buffer Interface); note that the length relates to the length of the default encoded string rather than the Unicode object length.</dd> <dt>“t#”</dt><dd>Same as “s#”.</dd> <dt>“es”</dt><dd>Takes two parameters: encoding (<code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></code>) and buffer (<code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">**</span></code>).<p>The input object is first coerced to Unicode in the usual way and then encoded into a string using the given encoding.</p> <p>On output, a buffer of the needed size is allocated and returned through <code class="docutils literal notranslate"><span class="pre">*buffer</span></code> as NULL-terminated string. The encoded may not contain embedded NULL characters. The caller is responsible for calling <code class="docutils literal notranslate"><span class="pre">PyMem_Free()</span></code> to free the allocated <code class="docutils literal notranslate"><span class="pre">*buffer</span></code> after usage.</p> </dd> <dt>“es#”</dt><dd>Takes three parameters: encoding (<code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></code>), buffer (<code class="docutils literal notranslate"><span class="pre">char</span> <span class="pre">**</span></code>) and buffer_len (<code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">*</span></code>).<p>The input object is first coerced to Unicode in the usual way and then encoded into a string using the given encoding.</p> <p>If <code class="docutils literal notranslate"><span class="pre">*buffer</span></code> is non-NULL, <code class="docutils literal notranslate"><span class="pre">*buffer_len</span></code> must be set to <code class="docutils literal notranslate"><span class="pre">sizeof(buffer)</span></code> on input. Output is then copied to <code class="docutils literal notranslate"><span class="pre">*buffer</span></code>.</p> <p>If <code class="docutils literal notranslate"><span class="pre">*buffer</span></code> is NULL, a buffer of the needed size is allocated and output copied into it. <code class="docutils literal notranslate"><span class="pre">*buffer</span></code> is then updated to point to the allocated memory area. The caller is responsible for calling <code class="docutils literal notranslate"><span class="pre">PyMem_Free()</span></code> to free the allocated <code class="docutils literal notranslate"><span class="pre">*buffer</span></code> after usage.</p> <p>In both cases <code class="docutils literal notranslate"><span class="pre">*buffer_len</span></code> is updated to the number of characters written (excluding the trailing NULL-byte). The output buffer is assured to be NULL-terminated.</p> </dd> </dl> <p>Examples:</p> <p>Using “es#” with auto-allocation:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>static PyObject * test_parser(PyObject *self, PyObject *args) { PyObject *str; const char *encoding = &quot;latin-1&quot;; char *buffer = NULL; int buffer_len = 0; if (!PyArg_ParseTuple(args, &quot;es#:test_parser&quot;, encoding, &amp;buffer, &amp;buffer_len)) return NULL; if (!buffer) { PyErr_SetString(PyExc_SystemError, &quot;buffer is NULL&quot;); return NULL; } str = PyString_FromStringAndSize(buffer, buffer_len); PyMem_Free(buffer); return str; } </pre></div> </div> <p>Using “es” with auto-allocation returning a NULL-terminated string:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>static PyObject * test_parser(PyObject *self, PyObject *args) { PyObject *str; const char *encoding = &quot;latin-1&quot;; char *buffer = NULL; if (!PyArg_ParseTuple(args, &quot;es:test_parser&quot;, encoding, &amp;buffer)) return NULL; if (!buffer) { PyErr_SetString(PyExc_SystemError, &quot;buffer is NULL&quot;); return NULL; } str = PyString_FromString(buffer); PyMem_Free(buffer); return str; } </pre></div> </div> <p>Using “es#” with a pre-allocated buffer:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>static PyObject * test_parser(PyObject *self, PyObject *args) { PyObject *str; const char *encoding = &quot;latin-1&quot;; char _buffer[10]; char *buffer = _buffer; int buffer_len = sizeof(_buffer); if (!PyArg_ParseTuple(args, &quot;es#:test_parser&quot;, encoding, &amp;buffer, &amp;buffer_len)) return NULL; if (!buffer) { PyErr_SetString(PyExc_SystemError, &quot;buffer is NULL&quot;); return NULL; } str = PyString_FromStringAndSize(buffer, buffer_len); return str; } </pre></div> </div> </section> <section id="file-stream-output"> <h2><a class="toc-backref" href="#file-stream-output" role="doc-backlink">File/Stream Output</a></h2> <p>Since file.write(object) and most other stream writers use the “s#” or “t#” argument parsing marker for querying the data to write, the default encoded string version of the Unicode object will be written to the streams (see Buffer Interface).</p> <p>For explicit handling of files using Unicode, the standard stream codecs as available through the codecs module should be used.</p> <p>The codecs module should provide a short-cut open(filename,mode,encoding) available which also assures that mode contains the ‘b’ character when needed.</p> </section> <section id="file-stream-input"> <h2><a class="toc-backref" href="#file-stream-input" role="doc-backlink">File/Stream Input</a></h2> <p>Only the user knows what encoding the input data uses, so no special magic is applied. The user will have to explicitly convert the string data to Unicode objects as needed or use the file wrappers defined in the codecs module (see File/Stream Output).</p> </section> <section id="unicode-methods-attributes"> <h2><a class="toc-backref" href="#unicode-methods-attributes" role="doc-backlink">Unicode Methods &amp; Attributes</a></h2> <p>All Python string methods, plus:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">.</span><span class="n">encode</span><span class="p">([</span><span class="n">encoding</span><span class="o">=&lt;</span><span class="n">default</span> <span class="n">encoding</span><span class="o">&gt;</span><span class="p">][,</span><span class="n">errors</span><span class="o">=</span><span class="s2">&quot;strict&quot;</span><span class="p">])</span> <span class="o">--&gt;</span> <span class="n">see</span> <span class="n">Unicode</span> <span class="n">Output</span> <span class="o">.</span><span class="n">splitlines</span><span class="p">([</span><span class="n">include_breaks</span><span class="o">=</span><span class="mi">0</span><span class="p">])</span> <span class="o">--&gt;</span> <span class="n">breaks</span> <span class="n">the</span> <span class="n">Unicode</span> <span class="n">string</span> <span class="n">into</span> <span class="n">a</span> <span class="nb">list</span> <span class="n">of</span> <span class="p">(</span><span class="n">Unicode</span><span class="p">)</span> <span class="n">lines</span><span class="p">;</span> <span class="n">returns</span> <span class="n">the</span> <span class="n">lines</span> <span class="k">with</span> <span class="n">line</span> <span class="n">breaks</span> <span class="n">included</span><span class="p">,</span> <span class="k">if</span> <span class="n">include_breaks</span> <span class="ow">is</span> <span class="n">true</span><span class="o">.</span> <span class="n">See</span> <span class="n">Line</span> <span class="n">Breaks</span> <span class="k">for</span> <span class="n">a</span> <span class="n">specification</span> <span class="n">of</span> <span class="n">how</span> <span class="n">line</span> <span class="n">breaking</span> <span class="ow">is</span> <span class="n">done</span><span class="o">.</span> </pre></div> </div> </section> <section id="code-base"> <h2><a class="toc-backref" href="#code-base" role="doc-backlink">Code Base</a></h2> <p>We should use Fredrik Lundh’s Unicode object implementation as basis. It already implements most of the string methods needed and provides a well written code base which we can build upon.</p> <p>The object sharing implemented in Fredrik’s implementation should be dropped.</p> </section> <section id="test-cases"> <h2><a class="toc-backref" href="#test-cases" role="doc-backlink">Test Cases</a></h2> <p>Test cases should follow those in Lib/test/test_string.py and include additional checks for the Codec Registry and the Standard Codecs.</p> </section> <section id="references"> <h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2> <ul class="simple"> <li>Unicode Consortium: <a class="reference external" href="http://www.unicode.org/">http://www.unicode.org/</a></li> <li>Unicode FAQ: <a class="reference external" href="http://www.unicode.org/unicode/faq/">http://www.unicode.org/unicode/faq/</a></li> <li>Unicode 3.0: <a class="reference external" href="http://www.unicode.org/unicode/standard/versions/Unicode3.0.html">http://www.unicode.org/unicode/standard/versions/Unicode3.0.html</a></li> <li>Unicode-TechReports: <a class="reference external" href="http://www.unicode.org/unicode/reports/techreports.html">http://www.unicode.org/unicode/reports/techreports.html</a></li> <li>Unicode-Mappings: <a class="reference external" href="ftp://ftp.unicode.org/Public/MAPPINGS/">ftp://ftp.unicode.org/Public/MAPPINGS/</a></li> <li>Introduction to Unicode (a little outdated by still nice to read): <a class="reference external" href="http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html">http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html</a></li> <li>For comparison: Introducing Unicode to ECMAScript (aka JavaScript) – <a class="reference external" href="http://www-4.ibm.com/software/developer/library/internationalization-support.html">http://www-4.ibm.com/software/developer/library/internationalization-support.html</a></li> <li>IANA Character Set Names: <a class="reference external" href="ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets">ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets</a></li> <li>Discussion of UTF-8 and Unicode support for POSIX and Linux: <a class="reference external" href="http://www.cl.cam.ac.uk/~mgk25/unicode.html">http://www.cl.cam.ac.uk/~mgk25/unicode.html</a></li> <li>Encodings:<ul> <li>Overview: <a class="reference external" href="http://czyborra.com/utf/">http://czyborra.com/utf/</a></li> <li>UCS-2: <a class="reference external" href="http://www.uazone.org/multiling/unicode/ucs2.html">http://www.uazone.org/multiling/unicode/ucs2.html</a></li> <li>UTF-7: Defined in <span class="target" id="index-0"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2152.html"><strong>RFC 2152</strong></a></li> <li>UTF-8: Defined in <span class="target" id="index-1"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2279.html"><strong>RFC 2279</strong></a></li> <li>UTF-16: <a class="reference external" href="http://www.uazone.org/multiling/unicode/wg2n1035.html">http://www.uazone.org/multiling/unicode/wg2n1035.html</a></li> </ul> </li> </ul> </section> <section id="history-of-this-proposal"> <h2><a class="toc-backref" href="#history-of-this-proposal" role="doc-backlink">History of this Proposal</a></h2> <p>[ed. note: revisions prior to 1.7 are available in the CVS history of Misc/unicode.txt from the standard Python distribution. All subsequent history is available via the CVS revisions on this file.]</p> <section id="id1"> <h3><a class="toc-backref" href="#id1" role="doc-backlink">1.7</a></h3> <ul class="simple"> <li>Added note about the changed behaviour of “s#”.</li> </ul> </section> <section id="id2"> <h3><a class="toc-backref" href="#id2" role="doc-backlink">1.6</a></h3> <ul class="simple"> <li>Changed &lt;defencstr&gt; to &lt;defenc&gt; since this is the name used in the implementation.</li> <li>Added notes about the usage of &lt;defenc&gt; in the buffer protocol implementation.</li> </ul> </section> <section id="id3"> <h3><a class="toc-backref" href="#id3" role="doc-backlink">1.5</a></h3> <ul class="simple"> <li>Added notes about setting the &lt;default encoding&gt;.</li> <li>Fixed some typos (thanks to Andrew Kuchling).</li> <li>Changed &lt;defencstr&gt; to &lt;utf8str&gt;.</li> </ul> </section> <section id="id4"> <h3><a class="toc-backref" href="#id4" role="doc-backlink">1.4</a></h3> <ul class="simple"> <li>Added note about mixed type comparisons and contains tests.</li> <li>Changed treating of Unicode objects in format strings (if used with <code class="docutils literal notranslate"><span class="pre">'%s'</span> <span class="pre">%</span> <span class="pre">u</span></code> they will now cause the format string to be coerced to Unicode, thus producing a Unicode object on return).</li> <li>Added link to IANA charset names (thanks to Lars Marius Garshol).</li> <li>Added new codec methods <code class="docutils literal notranslate"><span class="pre">.readline()</span></code>, <code class="docutils literal notranslate"><span class="pre">.readlines()</span></code> and <code class="docutils literal notranslate"><span class="pre">.writelines()</span></code>.</li> </ul> </section> <section id="id5"> <h3><a class="toc-backref" href="#id5" role="doc-backlink">1.3</a></h3> <ul class="simple"> <li>Added new “es” and “es#” parser markers</li> </ul> </section> <section id="id6"> <h3><a class="toc-backref" href="#id6" role="doc-backlink">1.2</a></h3> <ul class="simple"> <li>Removed POD about <code class="docutils literal notranslate"><span class="pre">codecs.open()</span></code></li> </ul> </section> <section id="id7"> <h3><a class="toc-backref" href="#id7" role="doc-backlink">1.1</a></h3> <ul class="simple"> <li>Added note about comparisons and hash values.</li> <li>Added note about case mapping algorithms.</li> <li>Changed stream codecs <code class="docutils literal notranslate"><span class="pre">.read()</span></code> and <code class="docutils literal notranslate"><span class="pre">.write()</span></code> method to match the standard file-like object methods (bytes consumed information is no longer returned by the methods)</li> </ul> </section> <section id="id8"> <h3><a class="toc-backref" href="#id8" role="doc-backlink">1.0</a></h3> <ul class="simple"> <li>changed encode Codec method to be symmetric to the decode method (they both return (object, data consumed) now and thus become interchangeable);</li> <li>removed <code class="docutils literal notranslate"><span class="pre">__init__</span></code> method of Codec class (the methods are stateless) and moved the errors argument down to the methods;</li> <li>made the Codec design more generic w/r to type of input and output objects;</li> <li>changed <code class="docutils literal notranslate"><span class="pre">StreamWriter.flush</span></code> to <code class="docutils literal notranslate"><span class="pre">StreamWriter.reset</span></code> in order to avoid overriding the stream’s <code class="docutils literal notranslate"><span class="pre">.flush()</span></code> method;</li> <li>renamed <code class="docutils literal notranslate"><span class="pre">.breaklines()</span></code> to <code class="docutils literal notranslate"><span class="pre">.splitlines()</span></code>;</li> <li>renamed the module unicodec to codecs;</li> <li>modified the File I/O section to refer to the stream codecs.</li> </ul> </section> <section id="id9"> <h3><a class="toc-backref" href="#id9" role="doc-backlink">0.9</a></h3> <ul class="simple"> <li>changed errors keyword argument definition;</li> <li>added ‘replace’ error handling;</li> <li>changed the codec APIs to accept buffer like objects on input;</li> <li>some minor typo fixes;</li> <li>added Whitespace section and included references for Unicode characters that have the whitespace and the line break characteristic;</li> <li>added note that search functions can expect lower-case encoding names;</li> <li>dropped slicing and offsets in the codec APIs</li> </ul> </section> <section id="id10"> <h3><a class="toc-backref" href="#id10" role="doc-backlink">0.8</a></h3> <ul class="simple"> <li>added encodings package and raw unicode escape encoding;</li> <li>untabified the proposal;</li> <li>added notes on Unicode format strings;</li> <li>added <code class="docutils literal notranslate"><span class="pre">.breaklines()</span></code> method</li> </ul> </section> <section id="id11"> <h3><a class="toc-backref" href="#id11" role="doc-backlink">0.7</a></h3> <ul class="simple"> <li>added a whole new set of codec APIs;</li> <li>added a different encoder lookup scheme;</li> <li>fixed some names</li> </ul> </section> <section id="id12"> <h3><a class="toc-backref" href="#id12" role="doc-backlink">0.6</a></h3> <ul class="simple"> <li>changed “s#” to “t#”;</li> <li>changed &lt;defencbuf&gt; to &lt;defencstr&gt; holding a real Python string object;</li> <li>changed Buffer Interface to delegate requests to &lt;defencstr&gt;’s buffer interface;</li> <li>removed the explicit reference to the unicodec.codecs dictionary (the module can implement this in way fit for the purpose);</li> <li>removed the settable default encoding;</li> <li>move <code class="docutils literal notranslate"><span class="pre">UnicodeError</span></code> from unicodec to exceptions;</li> <li>“s#” not returns the internal data;</li> <li>passed the UCS-2/UTF-16 checking from the Unicode constructor to the Codecs</li> </ul> </section> <section id="id13"> <h3><a class="toc-backref" href="#id13" role="doc-backlink">0.5</a></h3> <ul class="simple"> <li>moved <code class="docutils literal notranslate"><span class="pre">sys.bom</span></code> to <code class="docutils literal notranslate"><span class="pre">unicodec.BOM</span></code>;</li> <li>added sections on case mapping,</li> <li>private use encodings and Unicode character properties</li> </ul> </section> <section id="id14"> <h3><a class="toc-backref" href="#id14" role="doc-backlink">0.4</a></h3> <ul class="simple"> <li>added Codec interface, notes on %-formatting,</li> <li>changed some encoding details,</li> <li>added comments on stream wrappers,</li> <li>fixed some discussion points (most important: Internal Format),</li> <li>clarified the ‘unicode-escape’ encoding, added encoding references</li> </ul> </section> <section id="id15"> <h3><a class="toc-backref" href="#id15" role="doc-backlink">0.3</a></h3> <ul class="simple"> <li>added references, comments on codec modules, the internal format, bf_getcharbuffer and the RE engine;</li> <li>added ‘unicode-escape’ encoding proposed by Tim Peters and fixed repr(u) accordingly</li> </ul> </section> <section id="id16"> <h3><a class="toc-backref" href="#id16" role="doc-backlink">0.2</a></h3> <ul class="simple"> <li>integrated Guido’s suggestions, added stream codecs and file wrapping</li> </ul> </section> <section id="id17"> <h3><a class="toc-backref" href="#id17" role="doc-backlink">0.1</a></h3> <ul class="simple"> <li>first version</li> </ul> </section> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0100.rst">https://github.com/python/peps/blob/main/peps/pep-0100.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0100.rst">2025-02-01 08:55:40 GMT</a></p> </article> <nav id="pep-sidebar"> <h2>Contents</h2> <ul> <li><a class="reference internal" href="#historical-note">Historical Note</a></li> <li><a class="reference internal" href="#introduction">Introduction</a></li> <li><a class="reference internal" href="#conventions">Conventions</a></li> <li><a class="reference internal" href="#general-remarks">General Remarks</a></li> <li><a class="reference internal" href="#unicode-default-encoding">Unicode Default Encoding</a></li> <li><a class="reference internal" href="#unicode-constructors">Unicode Constructors</a></li> <li><a class="reference internal" href="#unicode-type-object">Unicode Type Object</a></li> <li><a class="reference internal" href="#unicode-output">Unicode Output</a></li> <li><a class="reference internal" href="#unicode-ordinals">Unicode Ordinals</a></li> <li><a class="reference internal" href="#comparison-hash-value">Comparison &amp; Hash Value</a></li> <li><a class="reference internal" href="#coercion">Coercion</a></li> <li><a class="reference internal" href="#exceptions">Exceptions</a></li> <li><a class="reference internal" href="#codecs-coder-decoders-lookup">Codecs (Coder/Decoders) Lookup</a></li> <li><a class="reference internal" href="#standard-codecs">Standard Codecs</a></li> <li><a class="reference internal" href="#codecs-interface-definition">Codecs Interface Definition</a></li> <li><a class="reference internal" href="#whitespace">Whitespace</a></li> <li><a class="reference internal" href="#case-conversion">Case Conversion</a></li> <li><a class="reference internal" href="#line-breaks">Line Breaks</a></li> <li><a class="reference internal" href="#unicode-character-properties">Unicode Character Properties</a></li> <li><a class="reference internal" href="#private-code-point-areas">Private Code Point Areas</a></li> <li><a class="reference internal" href="#internal-format">Internal Format</a></li> <li><a class="reference internal" href="#buffer-interface">Buffer Interface</a></li> <li><a class="reference internal" href="#pickle-marshalling">Pickle/Marshalling</a></li> <li><a class="reference internal" href="#regular-expressions">Regular Expressions</a></li> <li><a class="reference internal" href="#formatting-markers">Formatting Markers</a></li> <li><a class="reference internal" href="#internal-argument-parsing">Internal Argument Parsing</a></li> <li><a class="reference internal" href="#file-stream-output">File/Stream Output</a></li> <li><a class="reference internal" href="#file-stream-input">File/Stream Input</a></li> <li><a class="reference internal" href="#unicode-methods-attributes">Unicode Methods &amp; Attributes</a></li> <li><a class="reference internal" href="#code-base">Code Base</a></li> <li><a class="reference internal" href="#test-cases">Test Cases</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#history-of-this-proposal">History of this Proposal</a><ul> <li><a class="reference internal" href="#id1">1.7</a></li> <li><a class="reference internal" href="#id2">1.6</a></li> <li><a class="reference internal" href="#id3">1.5</a></li> <li><a class="reference internal" href="#id4">1.4</a></li> <li><a class="reference internal" href="#id5">1.3</a></li> <li><a class="reference internal" href="#id6">1.2</a></li> <li><a class="reference internal" href="#id7">1.1</a></li> <li><a class="reference internal" href="#id8">1.0</a></li> <li><a class="reference internal" href="#id9">0.9</a></li> <li><a class="reference internal" href="#id10">0.8</a></li> <li><a class="reference internal" href="#id11">0.7</a></li> <li><a class="reference internal" href="#id12">0.6</a></li> <li><a class="reference internal" href="#id13">0.5</a></li> <li><a class="reference internal" href="#id14">0.4</a></li> <li><a class="reference internal" href="#id15">0.3</a></li> <li><a class="reference internal" href="#id16">0.2</a></li> <li><a class="reference internal" href="#id17">0.1</a></li> </ul> </li> </ul> <br> <a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0100.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>

Pages: 1 2 3 4 5 6 7 8 9 10