CINXE.COM

PEP 296 – Adding a bytes Object Type | 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 296 – Adding a bytes Object Type | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0296/"> <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 296 – Adding a bytes Object Type | peps.python.org'> <meta property="og:description" content="This PEP proposes the creation of a new standard type and builtin constructor called ‘bytes’. The bytes object is an efficiently stored array of bytes with some additional characteristics that set it apart from several implementations that are similar."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0296/"> <meta property="og:site_name" content="Python Enhancement Proposals (PEPs)"> <meta property="og:image" content="https://peps.python.org/_static/og-image.png"> <meta property="og:image:alt" content="Python PEPs"> <meta property="og:image:width" content="200"> <meta property="og:image:height" content="200"> <meta name="description" content="This PEP proposes the creation of a new standard type and builtin constructor called ‘bytes’. The bytes object is an efficiently stored array of bytes with some additional characteristics that set it apart from several implementations that are similar."> <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 296</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 296 – Adding a bytes Object Type</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Scott Gilbert &lt;xscottg at yahoo.com&gt;</dd> <dt class="field-even">Status<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Removed from consideration by sponsor or authors">Withdrawn</abbr></dd> <dt class="field-odd">Type<span class="colon">:</span></dt> <dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd> <dt class="field-even">Created<span class="colon">:</span></dt> <dd class="field-even">12-Jul-2002</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">2.3</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="#notice">Notice</a></li> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#specification">Specification</a></li> <li><a class="reference internal" href="#contrast-to-existing-types">Contrast to existing types</a></li> <li><a class="reference internal" href="#backward-compatibility">Backward Compatibility</a></li> <li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li> <li><a class="reference internal" href="#additional-notes-comments">Additional Notes/Comments</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> </details></section> <section id="notice"> <h2><a class="toc-backref" href="#notice" role="doc-backlink">Notice</a></h2> <p>This PEP is withdrawn by the author (in favor of <a class="pep reference internal" href="../pep-0358/" title="PEP 358 – The “bytes” Object">PEP 358</a>).</p> </section> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>This PEP proposes the creation of a new standard type and builtin constructor called ‘bytes’. The bytes object is an efficiently stored array of bytes with some additional characteristics that set it apart from several implementations that are similar.</p> </section> <section id="rationale"> <h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2> <p>Python currently has many objects that implement something akin to the bytes object of this proposal. For instance the standard string, buffer, array, and mmap objects are all very similar in some regards to the bytes object. Additionally, several significant third party extensions have created similar objects to try and fill similar needs. Frustratingly, each of these objects is too narrow in scope and is missing critical features to make it applicable to a wider category of problems.</p> </section> <section id="specification"> <h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2> <p>The bytes object has the following important characteristics:</p> <ol class="arabic"> <li>Efficient underlying array storage via the standard C type “unsigned char”. This allows fine grain control over how much memory is allocated. With the alignment restrictions designated in the next item, it is trivial for low level extensions to cast the pointer to a different type as needed.<p>Also, since the object is implemented as an array of bytes, it is possible to pass the bytes object to the extensive library of routines already in the standard library that presently work with strings. For instance, the bytes object in conjunction with the struct module could be used to provide a complete replacement for the array module using only Python script.</p> <p>If an unusual platform comes to light, one where there isn’t a native unsigned 8 bit type, the object will do its best to represent itself at the Python script level as though it were an array of 8 bit unsigned values. It is doubtful whether many extensions would handle this correctly, but Python script could be portable in these cases.</p> </li> <li>Alignment of the allocated byte array is whatever is promised by the platform implementation of malloc. A bytes object created from an extension can be supplied that provides any arbitrary alignment as the extension author sees fit.<p>This alignment restriction should allow the bytes object to be used as storage for all standard C types - including <code class="docutils literal notranslate"><span class="pre">PyComplex</span></code> objects or other structs of standard C type types. Further alignment restrictions can be provided by extensions as necessary.</p> </li> <li>The bytes object implements a subset of the sequence operations provided by string/array objects, but with slightly different semantics in some cases. In particular, a slice always returns a new bytes object, but the underlying memory is shared between the two objects. This type of slice behavior has been called creating a “view”. Additionally, repetition and concatenation are undefined for bytes objects and will raise an exception.<p>As these objects are likely to find use in high performance applications, one motivation for the decision to use view slicing is that copying between bytes objects should be very efficient and not require the creation of temporary objects. The following code illustrates this:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># create two 10 Meg bytes objects</span> <span class="n">b1</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="mi">10000000</span><span class="p">)</span> <span class="n">b2</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="mi">10000000</span><span class="p">)</span> <span class="c1"># copy from part of one to another with out creating a 1 Meg temporary</span> <span class="n">b1</span><span class="p">[</span><span class="mi">2000000</span><span class="p">:</span><span class="mi">3000000</span><span class="p">]</span> <span class="o">=</span> <span class="n">b2</span><span class="p">[</span><span class="mi">4000000</span><span class="p">:</span><span class="mi">5000000</span><span class="p">]</span> </pre></div> </div> <p>Slice assignment where the rvalue is not the same length as the lvalue will raise an exception. However, slice assignment will work correctly with overlapping slices (typically implemented with memmove).</p> </li> <li>The bytes object will be recognized as a native type by the <code class="docutils literal notranslate"><span class="pre">pickle</span></code> and <code class="docutils literal notranslate"><span class="pre">cPickle</span></code> modules for efficient serialization. (In truth, this is the only requirement that can’t be implemented via a third party extension.)<p>Partial solutions to address the need to serialize the data stored in a bytes-like object without creating a temporary copy of the data into a string have been implemented in the past. The tofile and fromfile methods of the array object are good examples of this. The bytes object will support these methods too. However, pickling is useful in other situations - such as in the shelve module, or implementing RPC of Python objects, and requiring the end user to use two different serialization mechanisms to get an efficient transfer of data is undesirable.</p> <p>XXX: Will try to implement pickling of the new bytes object in such a way that previous versions of Python will unpickle it as a string object.</p> <p>When unpickling, the bytes object will be created from memory allocated from Python (via <code class="docutils literal notranslate"><span class="pre">malloc</span></code>). As such, it will lose any additional properties that an extension supplied pointer might have provided (special alignment, or special types of memory).</p> <p>XXX: Will try to make it so that C subclasses of bytes type can supply the memory that will be unpickled into. For instance, a derived class called PageAlignedBytes would unpickle to memory that is also page aligned.</p> <p>On any platform where an int is 32 bits (most of them), it is currently impossible to create a string with a length larger than can be represented in 31 bits. As such, pickling to a string will raise an exception when the operation is not possible.</p> <p>At least on platforms supporting large files (many of them), pickling large bytes objects to files should be possible via repeated calls to the <code class="docutils literal notranslate"><span class="pre">file.write()</span></code> method.</p> </li> <li>The bytes type supports the <code class="docutils literal notranslate"><span class="pre">PyBufferProcs</span></code> interface, but a bytes object provides the additional guarantee that the pointer will not be deallocated or reallocated as long as a reference to the bytes object is held. This implies that a bytes object is not resizable once it is created, but allows the global interpreter lock (GIL) to be released while a separate thread manipulates the memory pointed to if the <code class="docutils literal notranslate"><span class="pre">PyBytes_Check(...)</span></code> test passes.<p>This characteristic of the bytes object allows it to be used in situations such as asynchronous file I/O or on multiprocessor machines where the pointer obtained by <code class="docutils literal notranslate"><span class="pre">PyBufferProcs</span></code> will be used independently of the global interpreter lock.</p> <p>Knowing that the pointer can not be reallocated or freed after the GIL is released gives extension authors the capability to get true concurrency and make use of additional processors for long running computations on the pointer.</p> </li> <li>In C/C++ extensions, the bytes object can be created from a supplied pointer and destructor function to free the memory when the reference count goes to zero.<p>The special implementation of slicing for the bytes object allows multiple bytes objects to refer to the same pointer/destructor. As such, a refcount will be kept on the actual pointer/destructor. This refcount is separate from the refcount typically associated with Python objects.</p> <p>XXX: It may be desirable to expose the inner refcounted object as an actual Python object. If a good use case arises, it should be possible for this to be implemented later with no loss to backwards compatibility.</p> </li> <li>It is also possible to signify the bytes object as readonly, in this case it isn’t actually mutable, but does provide the other features of a bytes object.</li> <li>The bytes object keeps track of the length of its data with a Python <code class="docutils literal notranslate"><span class="pre">LONG_LONG</span></code> type. Even though the current definition for <code class="docutils literal notranslate"><span class="pre">PyBufferProcs</span></code> restricts the length to be the size of an int, this PEP does not propose to make any changes there. Instead, extensions can work around this limit by making an explicit <code class="docutils literal notranslate"><span class="pre">PyBytes_Check(...)</span></code> call, and if that succeeds they can make a <code class="docutils literal notranslate"><span class="pre">PyBytes_GetReadBuffer(...)</span></code> or <code class="docutils literal notranslate"><span class="pre">PyBytes_GetWriteBuffer</span></code> call to get the pointer and full length of the object as a <code class="docutils literal notranslate"><span class="pre">LONG_LONG</span></code>.<p>The bytes object will raise an exception if the standard <code class="docutils literal notranslate"><span class="pre">PyBufferProcs</span></code> mechanism is used and the size of the bytes object is greater than can be represented by an integer.</p> <p>From Python scripting, the bytes object will be subscriptable with longs so the 32 bit int limit can be avoided.</p> <p>There is still a problem with the <code class="docutils literal notranslate"><span class="pre">len()</span></code> function as it is <code class="docutils literal notranslate"><span class="pre">PyObject_Size()</span></code> and this returns an int as well. As a workaround, the bytes object will provide a <code class="docutils literal notranslate"><span class="pre">.length()</span></code> method that will return a long.</p> </li> <li>The bytes object can be constructed at the Python scripting level by passing an int/long to the bytes constructor with the number of bytes to allocate. For example:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="mi">100000</span><span class="p">)</span> <span class="c1"># alloc 100K bytes</span> </pre></div> </div> <p>The constructor can also take another bytes object. This will be useful for the implementation of unpickling, and in converting a read-write bytes object into a read-only one. An optional second argument will be used to designate creation of a readonly bytes object.</p> </li> <li>From the C API, the bytes object can be allocated using any of the following signatures:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">PyObject</span><span class="o">*</span> <span class="n">PyBytes_FromLength</span><span class="p">(</span><span class="n">LONG_LONG</span> <span class="nb">len</span><span class="p">,</span> <span class="nb">int</span> <span class="n">readonly</span><span class="p">);</span> <span class="n">PyObject</span><span class="o">*</span> <span class="n">PyBytes_FromPointer</span><span class="p">(</span><span class="n">void</span><span class="o">*</span> <span class="n">ptr</span><span class="p">,</span> <span class="n">LONG_LONG</span> <span class="nb">len</span><span class="p">,</span> <span class="nb">int</span> <span class="n">readonly</span> <span class="n">void</span> <span class="p">(</span><span class="o">*</span><span class="n">dest</span><span class="p">)(</span><span class="n">void</span> <span class="o">*</span><span class="n">ptr</span><span class="p">,</span> <span class="n">void</span> <span class="o">*</span><span class="n">user</span><span class="p">),</span> <span class="n">void</span><span class="o">*</span> <span class="n">user</span><span class="p">);</span> </pre></div> </div> <p>In the <code class="docutils literal notranslate"><span class="pre">PyBytes_FromPointer(...)</span></code> function, if the dest function pointer is passed in as <code class="docutils literal notranslate"><span class="pre">NULL</span></code>, it will not be called. This should only be used for creating bytes objects from statically allocated space.</p> <p>The user pointer has been called a closure in other places. It is a pointer that the user can use for whatever purposes. It will be passed to the destructor function on cleanup and can be useful for a number of things. If the user pointer is not needed, <code class="docutils literal notranslate"><span class="pre">NULL</span></code> should be passed instead.</p> </li> <li>The bytes type will be a new style class as that seems to be where all standard Python types are headed.</li> </ol> </section> <section id="contrast-to-existing-types"> <h2><a class="toc-backref" href="#contrast-to-existing-types" role="doc-backlink">Contrast to existing types</a></h2> <p>The most common way to work around the lack of a bytes object has been to simply use a string object in its place. Binary files, the struct/array modules, and several other examples exist of this. Putting aside the style issue that these uses typically have nothing to do with text strings, there is the real problem that strings are not mutable, so direct manipulation of the data returned in these cases is not possible. Also, numerous optimizations in the string module (such as caching the hash value or interning the pointers) mean that extension authors are on very thin ice if they try to break the rules with the string object.</p> <p>The buffer object seems like it was intended to address the purpose that the bytes object is trying fulfill, but several shortcomings in its implementation <a class="footnote-reference brackets" href="#id2" id="id1">[1]</a> have made it less useful in many common cases. The buffer object made a different choice for its slicing behavior (it returns new strings instead of buffers for slicing and other operations), and it doesn’t make many of the promises on alignment or being able to release the GIL that the bytes object does.</p> <p>Also in regards to the buffer object, it is not possible to simply replace the buffer object with the bytes object and maintain backwards compatibility. The buffer object provides a mechanism to take the <code class="docutils literal notranslate"><span class="pre">PyBufferProcs</span></code> supplied pointer of another object and present it as its own. Since the behavior of the other object can not be guaranteed to follow the same set of strict rules that a bytes object does, it can’t be used in places that a bytes object could.</p> <p>The array module supports the creation of an array of bytes, but it does not provide a C API for supplying pointers and destructors to extension supplied memory. This makes it unusable for constructing objects out of shared memory, or memory that has special alignment or locking for things like DMA transfers. Also, the array object does not currently pickle. Finally since the array object allows its contents to grow, via the extend method, the pointer can be changed if the GIL is not held while using it.</p> <p>Creating a buffer object from an array object has the same problem of leaving an invalid pointer when the array object is resized.</p> <p>The mmap object caters to its particular niche, but does not attempt to solve a wider class of problems.</p> <p>Finally, any third party extension can not implement pickling without creating a temporary object of a standard Python type. For example, in the Numeric community, it is unpleasant that a large array can’t pickle without creating a large binary string to duplicate the array data.</p> </section> <section id="backward-compatibility"> <h2><a class="toc-backref" href="#backward-compatibility" role="doc-backlink">Backward Compatibility</a></h2> <p>The only possibility for backwards compatibility problems that the author is aware of are in previous versions of Python that try to unpickle data containing the new bytes type.</p> </section> <section id="reference-implementation"> <h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2> <p>XXX: Actual implementation is in progress, but changes are still possible as this PEP gets further review.</p> <p>The following new files will be added to the Python baseline:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Include</span><span class="o">/</span><span class="n">bytesobject</span><span class="o">.</span><span class="n">h</span> <span class="c1"># C interface</span> <span class="n">Objects</span><span class="o">/</span><span class="n">bytesobject</span><span class="o">.</span><span class="n">c</span> <span class="c1"># C implementation</span> <span class="n">Lib</span><span class="o">/</span><span class="n">test</span><span class="o">/</span><span class="n">test_bytes</span><span class="o">.</span><span class="n">py</span> <span class="c1"># unit testing</span> <span class="n">Doc</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">libbytes</span><span class="o">.</span><span class="n">tex</span> <span class="c1"># documentation</span> </pre></div> </div> <p>The following files will also be modified:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Include</span><span class="o">/</span><span class="n">Python</span><span class="o">.</span><span class="n">h</span> <span class="c1"># adding bytesmodule.h include file</span> <span class="n">Python</span><span class="o">/</span><span class="n">bltinmodule</span><span class="o">.</span><span class="n">c</span> <span class="c1"># adding the bytes type object</span> <span class="n">Modules</span><span class="o">/</span><span class="n">cPickle</span><span class="o">.</span><span class="n">c</span> <span class="c1"># adding bytes to the standard types</span> <span class="n">Lib</span><span class="o">/</span><span class="n">pickle</span><span class="o">.</span><span class="n">py</span> <span class="c1"># adding bytes to the standard types</span> </pre></div> </div> <p>It is possible that several other modules could be cleaned up and implemented in terms of the bytes object. The mmap module comes to mind first, but as noted above it would be possible to reimplement the array module as a pure Python module. While it is attractive that this PEP could actually reduce the amount of source code by some amount, the author feels that this could cause unnecessary risk for breaking existing applications and should be avoided at this time.</p> </section> <section id="additional-notes-comments"> <h2><a class="toc-backref" href="#additional-notes-comments" role="doc-backlink">Additional Notes/Comments</a></h2> <ul> <li>Guido van Rossum wondered whether it would make sense to be able to create a bytes object from a mmap object. The mmap object appears to support the requirements necessary to provide memory for a bytes object. (It doesn’t resize, and the pointer is valid for the lifetime of the object.) As such, a method could be added to the mmap module such that a bytes object could be created directly from a mmap object. An initial stab at how this would be implemented would be to use the <code class="docutils literal notranslate"><span class="pre">PyBytes_FromPointer()</span></code> function described above and pass the <code class="docutils literal notranslate"><span class="pre">mmap_object</span></code> as the user pointer. The destructor function would decref the <code class="docutils literal notranslate"><span class="pre">mmap_object</span></code> for cleanup.</li> <li>Todd Miller notes that it may be useful to have two new functions: <code class="docutils literal notranslate"><span class="pre">PyObject_AsLargeReadBuffer()</span></code> and <code class="docutils literal notranslate"><span class="pre">PyObject_AsLargeWriteBuffer</span></code> that are similar to <code class="docutils literal notranslate"><span class="pre">PyObject_AsReadBuffer()</span></code> and <code class="docutils literal notranslate"><span class="pre">PyObject_AsWriteBuffer()</span></code>, but support getting a <code class="docutils literal notranslate"><span class="pre">LONG_LONG</span></code> length in addition to the <code class="docutils literal notranslate"><span class="pre">void*</span></code> pointer. These functions would allow extension authors to work transparently with bytes object (that support <code class="docutils literal notranslate"><span class="pre">LONG_LONG</span></code> lengths) and most other buffer like objects (which only support int lengths). These functions could be in lieu of, or in addition to, creating a specific <code class="docutils literal notranslate"><span class="pre">PyByte_GetReadBuffer()</span></code> and <code class="docutils literal notranslate"><span class="pre">PyBytes_GetWriteBuffer()</span></code> functions.<p>XXX: The author thinks this is very a good idea as it paves the way for other objects to eventually support large (64 bit) pointers, and it should only affect abstract.c and abstract.h. Should this be added above?</p> </li> <li>It was generally agreed that abusing the segment count of the <code class="docutils literal notranslate"><span class="pre">PyBufferProcs</span></code> interface is not a good hack to work around the 31 bit limitation of the length. If you don’t know what this means, then you’re in good company. Most code in the Python baseline, and presumably in many third party extensions, punt when the segment count is not 1.</li> </ul> </section> <section id="references"> <h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2> <aside class="footnote-list brackets"> <aside class="footnote brackets" id="id2" role="doc-footnote"> <dt class="label" id="id2">[<a href="#id1">1</a>]</dt> <dd>The buffer interface <a class="reference external" href="https://mail.python.org/pipermail/python-dev/2000-October/009974.html">https://mail.python.org/pipermail/python-dev/2000-October/009974.html</a></aside> </aside> </section> <section id="copyright"> <h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2> <p>This document has been placed in the public domain.</p> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0296.rst">https://github.com/python/peps/blob/main/peps/pep-0296.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0296.rst">2023-09-09 17:39:29 GMT</a></p> </article> <nav id="pep-sidebar"> <h2>Contents</h2> <ul> <li><a class="reference internal" href="#notice">Notice</a></li> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#specification">Specification</a></li> <li><a class="reference internal" href="#contrast-to-existing-types">Contrast to existing types</a></li> <li><a class="reference internal" href="#backward-compatibility">Backward Compatibility</a></li> <li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li> <li><a class="reference internal" href="#additional-notes-comments">Additional Notes/Comments</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> <br> <a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0296.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