python-peps/pep-0357/index.html

349 lines
28 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 357 Allowing Any Object to be Used for Slicing | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0357/">
<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 357 Allowing Any Object to be Used for Slicing | peps.python.org'>
<meta property="og:description" content="This PEP proposes adding an nb_index slot in PyNumberMethods and an __index__ special method so that arbitrary objects can be used whenever integers are explicitly needed in Python, such as in slice syntax (from which the slot gets its name).">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0357/">
<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 adding an nb_index slot in PyNumberMethods and an __index__ special method so that arbitrary objects can be used whenever integers are explicitly needed in Python, such as in slice syntax (from which the slot gets its name).">
<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 357</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 357 Allowing Any Object to be Used for Slicing</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Travis Oliphant &lt;oliphant&#32;&#97;t&#32;ee.byu.edu&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">09-Feb-2006</dd>
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
<dd class="field-odd">2.5</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="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#proposal">Proposal</a></li>
<li><a class="reference internal" href="#specification">Specification</a></li>
<li><a class="reference internal" href="#implementation-plan">Implementation Plan</a></li>
<li><a class="reference internal" href="#discussion-questions">Discussion Questions</a><ul>
<li><a class="reference internal" href="#speed">Speed</a></li>
<li><a class="reference internal" href="#why-not-use-nb-int-which-is-already-there">Why not use <code class="docutils literal notranslate"><span class="pre">nb_int</span></code> which is already there?</a></li>
<li><a class="reference internal" href="#why-the-name-index">Why the name <code class="docutils literal notranslate"><span class="pre">__index__</span></code>?</a></li>
<li><a class="reference internal" href="#why-return-pyobject-from-nb-index">Why return <code class="docutils literal notranslate"><span class="pre">PyObject</span> <span class="pre">*</span></code> from <code class="docutils literal notranslate"><span class="pre">nb_index</span></code>?</a></li>
<li><a class="reference internal" href="#why-can-t-index-return-any-object-with-the-nb-index-method">Why cant <code class="docutils literal notranslate"><span class="pre">__index__</span></code> return any object with the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> method?</a></li>
</ul>
</li>
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</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="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This PEP proposes adding an <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot in <code class="docutils literal notranslate"><span class="pre">PyNumberMethods</span></code> and an
<code class="docutils literal notranslate"><span class="pre">__index__</span></code> special method so that arbitrary objects can be used
whenever integers are explicitly needed in Python, such as in slice
syntax (from which the slot gets its name).</p>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<p>Currently integers and long integers play a special role in
slicing in that they are the only objects allowed in slice
syntax. In other words, if X is an object implementing the
sequence protocol, then <code class="docutils literal notranslate"><span class="pre">X[obj1:obj2]</span></code> is only valid if <code class="docutils literal notranslate"><span class="pre">obj1</span></code> and
<code class="docutils literal notranslate"><span class="pre">obj2</span></code> are both integers or long integers. There is no way for <code class="docutils literal notranslate"><span class="pre">obj1</span></code>
and <code class="docutils literal notranslate"><span class="pre">obj2</span></code> to tell Python that they could be reasonably used as
indexes into a sequence. This is an unnecessary limitation.</p>
<p>In NumPy, for example, there are 8 different integer scalars
corresponding to unsigned and signed integers of 8, 16, 32, and 64
bits. These type-objects could reasonably be used as integers in
many places where Python expects true integers but cannot inherit from
the Python integer type because of incompatible memory layouts.
There should be some way to be able to tell Python that an object can
behave like an integer.</p>
<p>It is not possible to use the <code class="docutils literal notranslate"><span class="pre">nb_int</span></code> (and <code class="docutils literal notranslate"><span class="pre">__int__</span></code> special method)
for this purpose because that method is used to <em>coerce</em> objects
to integers. It would be inappropriate to allow every object that
can be coerced to an integer to be used as an integer everywhere
Python expects a true integer. For example, if <code class="docutils literal notranslate"><span class="pre">__int__</span></code> were used
to convert an object to an integer in slicing, then float objects
would be allowed in slicing and <code class="docutils literal notranslate"><span class="pre">x[3.2:5.8]</span></code> would not raise an error
as it should.</p>
</section>
<section id="proposal">
<h2><a class="toc-backref" href="#proposal" role="doc-backlink">Proposal</a></h2>
<p>Add an <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot to <code class="docutils literal notranslate"><span class="pre">PyNumberMethods</span></code>, and a corresponding
<code class="docutils literal notranslate"><span class="pre">__index__</span></code> special method. Objects could define a function to
place in the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot that returns a Python integer
(either an int or a long). This integer can
then be appropriately converted to a <code class="docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> value whenever
Python needs one such as in <code class="docutils literal notranslate"><span class="pre">PySequence_GetSlice</span></code>,
<code class="docutils literal notranslate"><span class="pre">PySequence_SetSlice</span></code>, and <code class="docutils literal notranslate"><span class="pre">PySequence_DelSlice</span></code>.</p>
</section>
<section id="specification">
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
<ol class="arabic">
<li>The <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot will have the following signature:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">PyObject</span> <span class="o">*</span><span class="n">index_func</span> <span class="p">(</span><span class="n">PyObject</span> <span class="o">*</span><span class="bp">self</span><span class="p">)</span>
</pre></div>
</div>
<p>The returned object must be a Python <code class="docutils literal notranslate"><span class="pre">IntType</span></code> or
Python <code class="docutils literal notranslate"><span class="pre">LongType</span></code>. NULL should be returned on
error with an appropriate error set.</p>
</li>
<li>The <code class="docutils literal notranslate"><span class="pre">__index__</span></code> special method will have the signature:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="fm">__index__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="n">obj</span>
</pre></div>
</div>
<p>where obj must be either an int or a long.</p>
</li>
<li>3 new abstract C-API functions will be added<ol class="loweralpha">
<li>The first checks to see if the object supports the index
slot and if it is filled in.<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">int</span> <span class="n">PyIndex_Check</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
</pre></div>
</div>
<p>This will return true if the object defines the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code>
slot.</p>
</li>
<li>The second is a simple wrapper around the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> call that
raises <code class="docutils literal notranslate"><span class="pre">PyExc_TypeError</span></code> if the call is not available or if it
doesnt return an int or long. Because the
<code class="docutils literal notranslate"><span class="pre">PyIndex_Check</span></code> is performed inside the <code class="docutils literal notranslate"><span class="pre">PyNumber_Index</span></code> call
you can call it directly and manage any error rather than
check for compatibility first.<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">PyObject</span> <span class="o">*</span><span class="n">PyNumber_Index</span> <span class="p">(</span><span class="n">PyObject</span> <span class="o">*</span><span class="n">obj</span><span class="p">)</span>
</pre></div>
</div>
</li>
<li>The third call helps deal with the common situation of
actually needing a <code class="docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> value from the object to use for
indexing or other needs.<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Py_ssize_t</span> <span class="n">PyNumber_AsSsize_t</span><span class="p">(</span><span class="n">PyObject</span> <span class="o">*</span><span class="n">obj</span><span class="p">,</span> <span class="n">PyObject</span> <span class="o">*</span><span class="n">exc</span><span class="p">)</span>
</pre></div>
</div>
<p>The function calls the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot of obj if it is
available and then converts the returned Python integer into
a <code class="docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> value. If this goes well, then the value is
returned. The second argument allows control over what
happens if the integer returned from <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> cannot fit
into a <code class="docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> value.</p>
<p>If exc is NULL, then the returned value will be clipped to
<code class="docutils literal notranslate"><span class="pre">PY_SSIZE_T_MAX</span></code> or <code class="docutils literal notranslate"><span class="pre">PY_SSIZE_T_MIN</span></code> depending on whether the
<code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot of obj returned a positive or negative
integer. If exc is non-NULL, then it is the error object
that will be set to replace the <code class="docutils literal notranslate"><span class="pre">PyExc_OverflowError</span></code> that was
raised when the Python integer or long was converted to <code class="docutils literal notranslate"><span class="pre">Py_ssize_t</span></code>.</p>
</li>
</ol>
</li>
<li>A new <code class="docutils literal notranslate"><span class="pre">operator.index(obj)</span></code> function will be added that calls
equivalent of <code class="docutils literal notranslate"><span class="pre">obj.__index__()</span></code> and raises an error if obj does not implement
the special method.</li>
</ol>
</section>
<section id="implementation-plan">
<h2><a class="toc-backref" href="#implementation-plan" role="doc-backlink">Implementation Plan</a></h2>
<ol class="arabic simple">
<li>Add the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot in <code class="docutils literal notranslate"><span class="pre">object.h</span></code> and modify <code class="docutils literal notranslate"><span class="pre">typeobject.c</span></code> to
create the <code class="docutils literal notranslate"><span class="pre">__index__</span></code> method</li>
<li>Change the <code class="docutils literal notranslate"><span class="pre">ISINT</span></code> macro in <code class="docutils literal notranslate"><span class="pre">ceval.c</span></code> to <code class="docutils literal notranslate"><span class="pre">ISINDEX</span></code> and alter it to
accommodate objects with the index slot defined.</li>
<li>Change the <code class="docutils literal notranslate"><span class="pre">_PyEval_SliceIndex</span></code> function to accommodate objects
with the index slot defined.</li>
<li>Change all builtin objects (e.g. lists) that use the <code class="docutils literal notranslate"><span class="pre">as_mapping</span></code>
slots for subscript access and use a special-check for integers to
check for the slot as well.</li>
<li>Add the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot to integers and long_integers
(which just return themselves)</li>
<li>Add <code class="docutils literal notranslate"><span class="pre">PyNumber_Index</span></code> C-API to return an integer from any
Python Object that has the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot.</li>
<li>Add the <code class="docutils literal notranslate"><span class="pre">operator.index(x)</span></code> function.</li>
<li>Alter <code class="docutils literal notranslate"><span class="pre">arrayobject.c</span></code> and <code class="docutils literal notranslate"><span class="pre">mmapmodule.c</span></code> to use the new C-API for their
sub-scripting and other needs.</li>
<li>Add unit-tests</li>
</ol>
</section>
<section id="discussion-questions">
<h2><a class="toc-backref" href="#discussion-questions" role="doc-backlink">Discussion Questions</a></h2>
<section id="speed">
<h3><a class="toc-backref" href="#speed" role="doc-backlink">Speed</a></h3>
<p>Implementation should not slow down Python because integers and long
integers used as indexes will complete in the same number of
instructions. The only change will be that what used to generate
an error will now be acceptable.</p>
</section>
<section id="why-not-use-nb-int-which-is-already-there">
<h3><a class="toc-backref" href="#why-not-use-nb-int-which-is-already-there" role="doc-backlink">Why not use <code class="docutils literal notranslate"><span class="pre">nb_int</span></code> which is already there?</a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">nb_int</span></code> method is used for coercion and so means something
fundamentally different than what is requested here. This PEP
proposes a method for something that <em>can</em> already be thought of as
an integer communicate that information to Python when it needs an
integer. The biggest example of why using <code class="docutils literal notranslate"><span class="pre">nb_int</span></code> would be a bad
thing is that float objects already define the <code class="docutils literal notranslate"><span class="pre">nb_int</span></code> method, but
float objects <em>should not</em> be used as indexes in a sequence.</p>
</section>
<section id="why-the-name-index">
<h3><a class="toc-backref" href="#why-the-name-index" role="doc-backlink">Why the name <code class="docutils literal notranslate"><span class="pre">__index__</span></code>?</a></h3>
<p>Some questions were raised regarding the name <code class="docutils literal notranslate"><span class="pre">__index__</span></code> when other
interpretations of the slot are possible. For example, the slot
can be used any time Python requires an integer internally (such
as in <code class="docutils literal notranslate"><span class="pre">&quot;mystring&quot;</span> <span class="pre">*</span> <span class="pre">3</span></code>). The name was suggested by Guido because
slicing syntax is the biggest reason for having such a slot and
in the end no better name emerged. See the discussion thread <a class="footnote-reference brackets" href="#id2" id="id1">[1]</a>
for examples of names that were suggested such as “<code class="docutils literal notranslate"><span class="pre">__discrete__</span></code>” and
<code class="docutils literal notranslate"><span class="pre">__ordinal__</span></code>”.</p>
</section>
<section id="why-return-pyobject-from-nb-index">
<h3><a class="toc-backref" href="#why-return-pyobject-from-nb-index" role="doc-backlink">Why return <code class="docutils literal notranslate"><span class="pre">PyObject</span> <span class="pre">*</span></code> from <code class="docutils literal notranslate"><span class="pre">nb_index</span></code>?</a></h3>
<p>Initially <code class="docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> was selected as the return type for the
<code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot. However, this led to an inability to track and
distinguish overflow and underflow errors without ugly and brittle
hacks. As the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> slot is used in at least 3 different ways
in the Python core (to get an integer, to get a slice end-point,
and to get a sequence index), there is quite a bit of flexibility
needed to handle all these cases. The importance of having the
necessary flexibility to handle all the use cases is critical.
For example, the initial implementation that returned <code class="docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> for
<code class="docutils literal notranslate"><span class="pre">nb_index</span></code> led to the discovery that on a 32-bit machine with &gt;=2GB of RAM
<code class="docutils literal notranslate"><span class="pre">s</span> <span class="pre">=</span> <span class="pre">'x'</span> <span class="pre">*</span> <span class="pre">(2**100)</span></code> works but <code class="docutils literal notranslate"><span class="pre">len(s)</span></code> was clipped at 2147483647.
Several fixes were suggested but eventually it was decided that
<code class="docutils literal notranslate"><span class="pre">nb_index</span></code> needed to return a Python Object similar to the <code class="docutils literal notranslate"><span class="pre">nb_int</span></code>
and <code class="docutils literal notranslate"><span class="pre">nb_long</span></code> slots in order to handle overflow correctly.</p>
</section>
<section id="why-can-t-index-return-any-object-with-the-nb-index-method">
<h3><a class="toc-backref" href="#why-can-t-index-return-any-object-with-the-nb-index-method" role="doc-backlink">Why cant <code class="docutils literal notranslate"><span class="pre">__index__</span></code> return any object with the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> method?</a></h3>
<p>This would allow infinite recursion in many different ways that are not
easy to check for. This restriction is similar to the requirement that
<code class="docutils literal notranslate"><span class="pre">__nonzero__</span></code> return an int or a bool.</p>
</section>
</section>
<section id="reference-implementation">
<h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2>
<p>Submitted as patch 1436368 to SourceForge.</p>
</section>
<section id="references">
<h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id2" role="doc-footnote">
<dt class="label" id="id2">[<a href="#id1">1</a>]</dt>
<dd>Travis Oliphant, PEP for adding an sq_index slot so that any object, a
or b, can be used in X[a:b] notation,<p><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2006-February/thread.html#60594">https://mail.python.org/pipermail/python-dev/2006-February/thread.html#60594</a></p>
</aside>
</aside>
</section>
<section id="copyright">
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
<p>This document is 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-0357.rst">https://github.com/python/peps/blob/main/peps/pep-0357.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0357.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#proposal">Proposal</a></li>
<li><a class="reference internal" href="#specification">Specification</a></li>
<li><a class="reference internal" href="#implementation-plan">Implementation Plan</a></li>
<li><a class="reference internal" href="#discussion-questions">Discussion Questions</a><ul>
<li><a class="reference internal" href="#speed">Speed</a></li>
<li><a class="reference internal" href="#why-not-use-nb-int-which-is-already-there">Why not use <code class="docutils literal notranslate"><span class="pre">nb_int</span></code> which is already there?</a></li>
<li><a class="reference internal" href="#why-the-name-index">Why the name <code class="docutils literal notranslate"><span class="pre">__index__</span></code>?</a></li>
<li><a class="reference internal" href="#why-return-pyobject-from-nb-index">Why return <code class="docutils literal notranslate"><span class="pre">PyObject</span> <span class="pre">*</span></code> from <code class="docutils literal notranslate"><span class="pre">nb_index</span></code>?</a></li>
<li><a class="reference internal" href="#why-can-t-index-return-any-object-with-the-nb-index-method">Why cant <code class="docutils literal notranslate"><span class="pre">__index__</span></code> return any object with the <code class="docutils literal notranslate"><span class="pre">nb_index</span></code> method?</a></li>
</ul>
</li>
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</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-0357.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>