add files
This commit is contained in:
325
python-3.7.4-docs-html/extending/building.html
Normal file
325
python-3.7.4-docs-html/extending/building.html
Normal file
@@ -0,0 +1,325 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>4. Building C and C++ Extensions — Python 3.7.4 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="Search within Python 3.7.4 documentation"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="About these documents" href="../about.html" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||||
<link rel="next" title="5. Building C and C++ Extensions on Windows" href="windows.html" />
|
||||
<link rel="prev" title="3. Defining Extension Types: Assorted Topics" href="newtypes.html" />
|
||||
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/extending/building.html" />
|
||||
|
||||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||||
<script type="text/javascript" src="../_static/switchers.js"></script>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head><body>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="windows.html" title="5. Building C and C++ Extensions on Windows"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="newtypes.html" title="3. Defining Extension Types: Assorted Topics"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||||
<li>
|
||||
<span class="language_switcher_placeholder">en</span>
|
||||
<span class="version_switcher_placeholder">3.7.4</span>
|
||||
<a href="../index.html">Documentation </a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Extending and Embedding the Python Interpreter</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" style="display: none" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="Quick search" type="text" name="q" />
|
||||
<input type="submit" value="Go" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="building-c-and-c-extensions">
|
||||
<span id="building"></span><h1>4. Building C and C++ Extensions<a class="headerlink" href="#building-c-and-c-extensions" title="Permalink to this headline">¶</a></h1>
|
||||
<p>A C extension for CPython is a shared library (e.g. a <code class="docutils literal notranslate"><span class="pre">.so</span></code> file on Linux,
|
||||
<code class="docutils literal notranslate"><span class="pre">.pyd</span></code> on Windows), which exports an <em>initialization function</em>.</p>
|
||||
<p>To be importable, the shared library must be available on <span class="target" id="index-0"></span><a class="reference internal" href="../using/cmdline.html#envvar-PYTHONPATH"><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PYTHONPATH</span></code></a>,
|
||||
and must be named after the module name, with an appropriate extension.
|
||||
When using distutils, the correct filename is generated automatically.</p>
|
||||
<p>The initialization function has the signature:</p>
|
||||
<dl class="function">
|
||||
<dt id="c.PyInit_modulename">
|
||||
<a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject">PyObject</a>* <code class="descname">PyInit_modulename</code><span class="sig-paren">(</span>void<span class="sig-paren">)</span><a class="headerlink" href="#c.PyInit_modulename" title="Permalink to this definition">¶</a></dt>
|
||||
<dd></dd></dl>
|
||||
|
||||
<p>It returns either a fully-initialized module, or a <a class="reference internal" href="../c-api/module.html#c.PyModuleDef" title="PyModuleDef"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyModuleDef</span></code></a>
|
||||
instance. See <a class="reference internal" href="../c-api/module.html#initializing-modules"><span class="std std-ref">Initializing C modules</span></a> for details.</p>
|
||||
<p>For modules with ASCII-only names, the function must be named
|
||||
<code class="docutils literal notranslate"><span class="pre">PyInit_<modulename></span></code>, with <code class="docutils literal notranslate"><span class="pre"><modulename></span></code> replaced by the name of the
|
||||
module. When using <a class="reference internal" href="../c-api/module.html#multi-phase-initialization"><span class="std std-ref">Multi-phase initialization</span></a>, non-ASCII module names
|
||||
are allowed. In this case, the initialization function name is
|
||||
<code class="docutils literal notranslate"><span class="pre">PyInitU_<modulename></span></code>, with <code class="docutils literal notranslate"><span class="pre"><modulename></span></code> encoded using Python’s
|
||||
<em>punycode</em> encoding with hyphens replaced by underscores. In Python:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">initfunc_name</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">suffix</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">'_'</span> <span class="o">+</span> <span class="n">name</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'ascii'</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">UnicodeEncodeError</span><span class="p">:</span>
|
||||
<span class="n">suffix</span> <span class="o">=</span> <span class="sa">b</span><span class="s1">'U_'</span> <span class="o">+</span> <span class="n">name</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'punycode'</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">b</span><span class="s1">'-'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'_'</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="sa">b</span><span class="s1">'PyInit'</span> <span class="o">+</span> <span class="n">suffix</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>It is possible to export multiple modules from a single shared library by
|
||||
defining multiple initialization functions. However, importing them requires
|
||||
using symbolic links or a custom importer, because by default only the
|
||||
function corresponding to the filename is found.
|
||||
See the <em>“Multiple modules in one library”</em> section in <span class="target" id="index-1"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0489"><strong>PEP 489</strong></a> for details.</p>
|
||||
<div class="section" id="building-c-and-c-extensions-with-distutils">
|
||||
<h2>4.1. Building C and C++ Extensions with distutils<a class="headerlink" href="#building-c-and-c-extensions-with-distutils" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Extension modules can be built using distutils, which is included in Python.
|
||||
Since distutils also supports creation of binary packages, users don’t
|
||||
necessarily need a compiler and distutils to install the extension.</p>
|
||||
<p>A distutils package contains a driver script, <code class="file docutils literal notranslate"><span class="pre">setup.py</span></code>. This is a plain
|
||||
Python file, which, in the most simple case, could look like this:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">distutils.core</span> <span class="k">import</span> <span class="n">setup</span><span class="p">,</span> <span class="n">Extension</span>
|
||||
|
||||
<span class="n">module1</span> <span class="o">=</span> <span class="n">Extension</span><span class="p">(</span><span class="s1">'demo'</span><span class="p">,</span>
|
||||
<span class="n">sources</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'demo.c'</span><span class="p">])</span>
|
||||
|
||||
<span class="n">setup</span> <span class="p">(</span><span class="n">name</span> <span class="o">=</span> <span class="s1">'PackageName'</span><span class="p">,</span>
|
||||
<span class="n">version</span> <span class="o">=</span> <span class="s1">'1.0'</span><span class="p">,</span>
|
||||
<span class="n">description</span> <span class="o">=</span> <span class="s1">'This is a demo package'</span><span class="p">,</span>
|
||||
<span class="n">ext_modules</span> <span class="o">=</span> <span class="p">[</span><span class="n">module1</span><span class="p">])</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>With this <code class="file docutils literal notranslate"><span class="pre">setup.py</span></code>, and a file <code class="file docutils literal notranslate"><span class="pre">demo.c</span></code>, running</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="n">setup</span><span class="p">.</span><span class="n">py</span> <span class="n">build</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>will compile <code class="file docutils literal notranslate"><span class="pre">demo.c</span></code>, and produce an extension module named <code class="docutils literal notranslate"><span class="pre">demo</span></code> in
|
||||
the <code class="file docutils literal notranslate"><span class="pre">build</span></code> directory. Depending on the system, the module file will end
|
||||
up in a subdirectory <code class="file docutils literal notranslate"><span class="pre">build/lib.system</span></code>, and may have a name like
|
||||
<code class="file docutils literal notranslate"><span class="pre">demo.so</span></code> or <code class="file docutils literal notranslate"><span class="pre">demo.pyd</span></code>.</p>
|
||||
<p>In the <code class="file docutils literal notranslate"><span class="pre">setup.py</span></code>, all execution is performed by calling the <code class="docutils literal notranslate"><span class="pre">setup</span></code>
|
||||
function. This takes a variable number of keyword arguments, of which the
|
||||
example above uses only a subset. Specifically, the example specifies
|
||||
meta-information to build packages, and it specifies the contents of the
|
||||
package. Normally, a package will contain additional modules, like Python
|
||||
source modules, documentation, subpackages, etc. Please refer to the distutils
|
||||
documentation in <a class="reference internal" href="../distutils/index.html#distutils-index"><span class="std std-ref">Distributing Python Modules (Legacy version)</span></a> to learn more about the features of
|
||||
distutils; this section explains building extension modules only.</p>
|
||||
<p>It is common to pre-compute arguments to <code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code>, to better structure the
|
||||
driver script. In the example above, the <code class="docutils literal notranslate"><span class="pre">ext_modules</span></code> argument to
|
||||
<a class="reference internal" href="../distutils/apiref.html#distutils.core.setup" title="distutils.core.setup"><code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code></a> is a list of extension modules, each of which is
|
||||
an instance of
|
||||
the <code class="xref py py-class docutils literal notranslate"><span class="pre">Extension</span></code>. In the example, the instance
|
||||
defines an extension named <code class="docutils literal notranslate"><span class="pre">demo</span></code> which is build by compiling a single source
|
||||
file, <code class="file docutils literal notranslate"><span class="pre">demo.c</span></code>.</p>
|
||||
<p>In many cases, building an extension is more complex, since additional
|
||||
preprocessor defines and libraries may be needed. This is demonstrated in the
|
||||
example below.</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">distutils.core</span> <span class="k">import</span> <span class="n">setup</span><span class="p">,</span> <span class="n">Extension</span>
|
||||
|
||||
<span class="n">module1</span> <span class="o">=</span> <span class="n">Extension</span><span class="p">(</span><span class="s1">'demo'</span><span class="p">,</span>
|
||||
<span class="n">define_macros</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">'MAJOR_VERSION'</span><span class="p">,</span> <span class="s1">'1'</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s1">'MINOR_VERSION'</span><span class="p">,</span> <span class="s1">'0'</span><span class="p">)],</span>
|
||||
<span class="n">include_dirs</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'/usr/local/include'</span><span class="p">],</span>
|
||||
<span class="n">libraries</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'tcl83'</span><span class="p">],</span>
|
||||
<span class="n">library_dirs</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'/usr/local/lib'</span><span class="p">],</span>
|
||||
<span class="n">sources</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'demo.c'</span><span class="p">])</span>
|
||||
|
||||
<span class="n">setup</span> <span class="p">(</span><span class="n">name</span> <span class="o">=</span> <span class="s1">'PackageName'</span><span class="p">,</span>
|
||||
<span class="n">version</span> <span class="o">=</span> <span class="s1">'1.0'</span><span class="p">,</span>
|
||||
<span class="n">description</span> <span class="o">=</span> <span class="s1">'This is a demo package'</span><span class="p">,</span>
|
||||
<span class="n">author</span> <span class="o">=</span> <span class="s1">'Martin v. Loewis'</span><span class="p">,</span>
|
||||
<span class="n">author_email</span> <span class="o">=</span> <span class="s1">'martin@v.loewis.de'</span><span class="p">,</span>
|
||||
<span class="n">url</span> <span class="o">=</span> <span class="s1">'https://docs.python.org/extending/building'</span><span class="p">,</span>
|
||||
<span class="n">long_description</span> <span class="o">=</span> <span class="s1">'''</span>
|
||||
<span class="s1">This is really just a demo package.</span>
|
||||
<span class="s1">'''</span><span class="p">,</span>
|
||||
<span class="n">ext_modules</span> <span class="o">=</span> <span class="p">[</span><span class="n">module1</span><span class="p">])</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>In this example, <a class="reference internal" href="../distutils/apiref.html#distutils.core.setup" title="distutils.core.setup"><code class="xref py py-func docutils literal notranslate"><span class="pre">setup()</span></code></a> is called with additional
|
||||
meta-information, which
|
||||
is recommended when distribution packages have to be built. For the extension
|
||||
itself, it specifies preprocessor defines, include directories, library
|
||||
directories, and libraries. Depending on the compiler, distutils passes this
|
||||
information in different ways to the compiler. For example, on Unix, this may
|
||||
result in the compilation commands</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">gcc</span> <span class="o">-</span><span class="n">DNDEBUG</span> <span class="o">-</span><span class="n">g</span> <span class="o">-</span><span class="n">O3</span> <span class="o">-</span><span class="n">Wall</span> <span class="o">-</span><span class="n">Wstrict</span><span class="o">-</span><span class="n">prototypes</span> <span class="o">-</span><span class="n">fPIC</span> <span class="o">-</span><span class="n">DMAJOR_VERSION</span><span class="o">=</span><span class="mi">1</span> <span class="o">-</span><span class="n">DMINOR_VERSION</span><span class="o">=</span><span class="mi">0</span> <span class="o">-</span><span class="n">I</span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="n">include</span> <span class="o">-</span><span class="n">I</span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="n">include</span><span class="o">/</span><span class="n">python2</span><span class="mf">.2</span> <span class="o">-</span><span class="n">c</span> <span class="n">demo</span><span class="p">.</span><span class="n">c</span> <span class="o">-</span><span class="n">o</span> <span class="n">build</span><span class="o">/</span><span class="n">temp</span><span class="p">.</span><span class="n">linux</span><span class="o">-</span><span class="n">i686</span><span class="o">-</span><span class="mf">2.2</span><span class="o">/</span><span class="n">demo</span><span class="p">.</span><span class="n">o</span>
|
||||
|
||||
<span class="n">gcc</span> <span class="o">-</span><span class="n">shared</span> <span class="n">build</span><span class="o">/</span><span class="n">temp</span><span class="p">.</span><span class="n">linux</span><span class="o">-</span><span class="n">i686</span><span class="o">-</span><span class="mf">2.2</span><span class="o">/</span><span class="n">demo</span><span class="p">.</span><span class="n">o</span> <span class="o">-</span><span class="n">L</span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">local</span><span class="o">/</span><span class="n">lib</span> <span class="o">-</span><span class="n">ltcl83</span> <span class="o">-</span><span class="n">o</span> <span class="n">build</span><span class="o">/</span><span class="n">lib</span><span class="p">.</span><span class="n">linux</span><span class="o">-</span><span class="n">i686</span><span class="o">-</span><span class="mf">2.2</span><span class="o">/</span><span class="n">demo</span><span class="p">.</span><span class="n">so</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>These lines are for demonstration purposes only; distutils users should trust
|
||||
that distutils gets the invocations right.</p>
|
||||
</div>
|
||||
<div class="section" id="distributing-your-extension-modules">
|
||||
<span id="distributing"></span><h2>4.2. Distributing your extension modules<a class="headerlink" href="#distributing-your-extension-modules" title="Permalink to this headline">¶</a></h2>
|
||||
<p>When an extension has been successfully build, there are three ways to use it.</p>
|
||||
<p>End-users will typically want to install the module, they do so by running</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="n">setup</span><span class="p">.</span><span class="n">py</span> <span class="n">install</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Module maintainers should produce source packages; to do so, they run</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="n">setup</span><span class="p">.</span><span class="n">py</span> <span class="n">sdist</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>In some cases, additional files need to be included in a source distribution;
|
||||
this is done through a <code class="file docutils literal notranslate"><span class="pre">MANIFEST.in</span></code> file; see <a class="reference internal" href="../distutils/sourcedist.html#manifest"><span class="std std-ref">Specifying the files to distribute</span></a> for details.</p>
|
||||
<p>If the source distribution has been build successfully, maintainers can also
|
||||
create binary distributions. Depending on the platform, one of the following
|
||||
commands can be used to do so.</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="n">setup</span><span class="p">.</span><span class="n">py</span> <span class="n">bdist_wininst</span>
|
||||
<span class="n">python</span> <span class="n">setup</span><span class="p">.</span><span class="n">py</span> <span class="n">bdist_rpm</span>
|
||||
<span class="n">python</span> <span class="n">setup</span><span class="p">.</span><span class="n">py</span> <span class="n">bdist_dumb</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">4. Building C and C++ Extensions</a><ul>
|
||||
<li><a class="reference internal" href="#building-c-and-c-extensions-with-distutils">4.1. Building C and C++ Extensions with distutils</a></li>
|
||||
<li><a class="reference internal" href="#distributing-your-extension-modules">4.2. Distributing your extension modules</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="newtypes.html"
|
||||
title="previous chapter">3. Defining Extension Types: Assorted Topics</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="windows.html"
|
||||
title="next chapter">5. Building C and C++ Extensions on Windows</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.7/Doc/extending/building.rst"
|
||||
rel="nofollow">Show Source
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="windows.html" title="5. Building C and C++ Extensions on Windows"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="newtypes.html" title="3. Defining Extension Types: Assorted Topics"
|
||||
>previous</a> |</li>
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||||
<li>
|
||||
<span class="language_switcher_placeholder">en</span>
|
||||
<span class="version_switcher_placeholder">3.7.4</span>
|
||||
<a href="../index.html">Documentation </a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Extending and Embedding the Python Interpreter</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" style="display: none" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="Quick search" type="text" name="q" />
|
||||
<input type="submit" value="Go" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
|
||||
<br />
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
Last updated on Jul 13, 2019.
|
||||
<a href="../bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.0.1.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
543
python-3.7.4-docs-html/extending/embedding.html
Normal file
543
python-3.7.4-docs-html/extending/embedding.html
Normal file
@@ -0,0 +1,543 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>1. Embedding Python in Another Application — Python 3.7.4 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="Search within Python 3.7.4 documentation"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="About these documents" href="../about.html" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||||
<link rel="next" title="Python/C API Reference Manual" href="../c-api/index.html" />
|
||||
<link rel="prev" title="5. Building C and C++ Extensions on Windows" href="windows.html" />
|
||||
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/extending/embedding.html" />
|
||||
|
||||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||||
<script type="text/javascript" src="../_static/switchers.js"></script>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head><body>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="../c-api/index.html" title="Python/C API Reference Manual"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="windows.html" title="5. Building C and C++ Extensions on Windows"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||||
<li>
|
||||
<span class="language_switcher_placeholder">en</span>
|
||||
<span class="version_switcher_placeholder">3.7.4</span>
|
||||
<a href="../index.html">Documentation </a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Extending and Embedding the Python Interpreter</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" style="display: none" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="Quick search" type="text" name="q" />
|
||||
<input type="submit" value="Go" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="embedding-python-in-another-application">
|
||||
<span id="embedding"></span><h1>1. Embedding Python in Another Application<a class="headerlink" href="#embedding-python-in-another-application" title="Permalink to this headline">¶</a></h1>
|
||||
<p>The previous chapters discussed how to extend Python, that is, how to extend the
|
||||
functionality of Python by attaching a library of C functions to it. It is also
|
||||
possible to do it the other way around: enrich your C/C++ application by
|
||||
embedding Python in it. Embedding provides your application with the ability to
|
||||
implement some of the functionality of your application in Python rather than C
|
||||
or C++. This can be used for many purposes; one example would be to allow users
|
||||
to tailor the application to their needs by writing some scripts in Python. You
|
||||
can also use it yourself if some of the functionality can be written in Python
|
||||
more easily.</p>
|
||||
<p>Embedding Python is similar to extending it, but not quite. The difference is
|
||||
that when you extend Python, the main program of the application is still the
|
||||
Python interpreter, while if you embed Python, the main program may have nothing
|
||||
to do with Python — instead, some parts of the application occasionally call
|
||||
the Python interpreter to run some Python code.</p>
|
||||
<p>So if you are embedding Python, you are providing your own main program. One of
|
||||
the things this main program has to do is initialize the Python interpreter. At
|
||||
the very least, you have to call the function <a class="reference internal" href="../c-api/init.html#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a>. There are
|
||||
optional calls to pass command line arguments to Python. Then later you can
|
||||
call the interpreter from any part of the application.</p>
|
||||
<p>There are several different ways to call the interpreter: you can pass a string
|
||||
containing Python statements to <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_SimpleString" title="PyRun_SimpleString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_SimpleString()</span></code></a>, or you can pass a
|
||||
stdio file pointer and a file name (for identification in error messages only)
|
||||
to <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_SimpleFile" title="PyRun_SimpleFile"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_SimpleFile()</span></code></a>. You can also call the lower-level operations
|
||||
described in the previous chapters to construct and use Python objects.</p>
|
||||
<div class="admonition seealso">
|
||||
<p class="admonition-title">See also</p>
|
||||
<dl class="simple">
|
||||
<dt><a class="reference internal" href="../c-api/index.html#c-api-index"><span class="std std-ref">Python/C API Reference Manual</span></a></dt><dd><p>The details of Python’s C interface are given in this manual. A great deal of
|
||||
necessary information can be found here.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section" id="very-high-level-embedding">
|
||||
<span id="high-level-embedding"></span><h2>1.1. Very High Level Embedding<a class="headerlink" href="#very-high-level-embedding" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The simplest form of embedding Python is the use of the very high level
|
||||
interface. This interface is intended to execute a Python script without needing
|
||||
to interact with the application directly. This can for example be used to
|
||||
perform some operation on a file.</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#define PY_SSIZE_T_CLEAN</span>
|
||||
<span class="cp">#include</span> <span class="cpf"><Python.h></span><span class="cp"></span>
|
||||
|
||||
<span class="kt">int</span>
|
||||
<span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
|
||||
<span class="p">{</span>
|
||||
<span class="kt">wchar_t</span> <span class="o">*</span><span class="n">program</span> <span class="o">=</span> <span class="n">Py_DecodeLocale</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">NULL</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">program</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Fatal error: cannot decode argv[0]</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
||||
<span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="n">Py_SetProgramName</span><span class="p">(</span><span class="n">program</span><span class="p">);</span> <span class="cm">/* optional but recommended */</span>
|
||||
<span class="n">Py_Initialize</span><span class="p">();</span>
|
||||
<span class="n">PyRun_SimpleString</span><span class="p">(</span><span class="s">"from time import time,ctime</span><span class="se">\n</span><span class="s">"</span>
|
||||
<span class="s">"print('Today is', ctime(time()))</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">Py_FinalizeEx</span><span class="p">()</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">exit</span><span class="p">(</span><span class="mi">120</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="n">PyMem_RawFree</span><span class="p">(</span><span class="n">program</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <a class="reference internal" href="../c-api/init.html#c.Py_SetProgramName" title="Py_SetProgramName"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_SetProgramName()</span></code></a> function should be called before
|
||||
<a class="reference internal" href="../c-api/init.html#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a> to inform the interpreter about paths to Python run-time
|
||||
libraries. Next, the Python interpreter is initialized with
|
||||
<a class="reference internal" href="../c-api/init.html#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a>, followed by the execution of a hard-coded Python script
|
||||
that prints the date and time. Afterwards, the <a class="reference internal" href="../c-api/init.html#c.Py_FinalizeEx" title="Py_FinalizeEx"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_FinalizeEx()</span></code></a> call shuts
|
||||
the interpreter down, followed by the end of the program. In a real program,
|
||||
you may want to get the Python script from another source, perhaps a text-editor
|
||||
routine, a file, or a database. Getting the Python code from a file can better
|
||||
be done by using the <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_SimpleFile" title="PyRun_SimpleFile"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_SimpleFile()</span></code></a> function, which saves you the
|
||||
trouble of allocating memory space and loading the file contents.</p>
|
||||
</div>
|
||||
<div class="section" id="beyond-very-high-level-embedding-an-overview">
|
||||
<span id="lower-level-embedding"></span><h2>1.2. Beyond Very High Level Embedding: An overview<a class="headerlink" href="#beyond-very-high-level-embedding-an-overview" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The high level interface gives you the ability to execute arbitrary pieces of
|
||||
Python code from your application, but exchanging data values is quite
|
||||
cumbersome to say the least. If you want that, you should use lower level calls.
|
||||
At the cost of having to write more C code, you can achieve almost anything.</p>
|
||||
<p>It should be noted that extending Python and embedding Python is quite the same
|
||||
activity, despite the different intent. Most topics discussed in the previous
|
||||
chapters are still valid. To show this, consider what the extension code from
|
||||
Python to C really does:</p>
|
||||
<ol class="arabic simple">
|
||||
<li><p>Convert data values from Python to C,</p></li>
|
||||
<li><p>Perform a function call to a C routine using the converted values, and</p></li>
|
||||
<li><p>Convert the data values from the call from C to Python.</p></li>
|
||||
</ol>
|
||||
<p>When embedding Python, the interface code does:</p>
|
||||
<ol class="arabic simple">
|
||||
<li><p>Convert data values from C to Python,</p></li>
|
||||
<li><p>Perform a function call to a Python interface routine using the converted
|
||||
values, and</p></li>
|
||||
<li><p>Convert the data values from the call from Python to C.</p></li>
|
||||
</ol>
|
||||
<p>As you can see, the data conversion steps are simply swapped to accommodate the
|
||||
different direction of the cross-language transfer. The only difference is the
|
||||
routine that you call between both data conversions. When extending, you call a
|
||||
C routine, when embedding, you call a Python routine.</p>
|
||||
<p>This chapter will not discuss how to convert data from Python to C and vice
|
||||
versa. Also, proper use of references and dealing with errors is assumed to be
|
||||
understood. Since these aspects do not differ from extending the interpreter,
|
||||
you can refer to earlier chapters for the required information.</p>
|
||||
</div>
|
||||
<div class="section" id="pure-embedding">
|
||||
<span id="id1"></span><h2>1.3. Pure Embedding<a class="headerlink" href="#pure-embedding" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The first program aims to execute a function in a Python script. Like in the
|
||||
section about the very high level interface, the Python interpreter does not
|
||||
directly interact with the application (but that will change in the next
|
||||
section).</p>
|
||||
<p>The code to run a function defined in a Python script is:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#define PY_SSIZE_T_CLEAN</span>
|
||||
<span class="cp">#include</span> <span class="cpf"><Python.h></span><span class="cp"></span>
|
||||
|
||||
<span class="kt">int</span>
|
||||
<span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
|
||||
<span class="p">{</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">pName</span><span class="p">,</span> <span class="o">*</span><span class="n">pModule</span><span class="p">,</span> <span class="o">*</span><span class="n">pFunc</span><span class="p">;</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">pArgs</span><span class="p">,</span> <span class="o">*</span><span class="n">pValue</span><span class="p">;</span>
|
||||
<span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">argc</span> <span class="o"><</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span><span class="s">"Usage: call pythonfile funcname [args]</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="n">Py_Initialize</span><span class="p">();</span>
|
||||
<span class="n">pName</span> <span class="o">=</span> <span class="n">PyUnicode_DecodeFSDefault</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
|
||||
<span class="cm">/* Error checking of pName left out */</span>
|
||||
|
||||
<span class="n">pModule</span> <span class="o">=</span> <span class="n">PyImport_Import</span><span class="p">(</span><span class="n">pName</span><span class="p">);</span>
|
||||
<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pName</span><span class="p">);</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">pModule</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">pFunc</span> <span class="o">=</span> <span class="n">PyObject_GetAttrString</span><span class="p">(</span><span class="n">pModule</span><span class="p">,</span> <span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
|
||||
<span class="cm">/* pFunc is a new reference */</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">pFunc</span> <span class="o">&&</span> <span class="n">PyCallable_Check</span><span class="p">(</span><span class="n">pFunc</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="n">pArgs</span> <span class="o">=</span> <span class="n">PyTuple_New</span><span class="p">(</span><span class="n">argc</span> <span class="o">-</span> <span class="mi">3</span><span class="p">);</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">argc</span> <span class="o">-</span> <span class="mi">3</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">pValue</span> <span class="o">=</span> <span class="n">PyLong_FromLong</span><span class="p">(</span><span class="n">atoi</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">3</span><span class="p">]));</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">pValue</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pArgs</span><span class="p">);</span>
|
||||
<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pModule</span><span class="p">);</span>
|
||||
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Cannot convert argument</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="cm">/* pValue reference stolen here: */</span>
|
||||
<span class="n">PyTuple_SetItem</span><span class="p">(</span><span class="n">pArgs</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">pValue</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="n">pValue</span> <span class="o">=</span> <span class="n">PyObject_CallObject</span><span class="p">(</span><span class="n">pFunc</span><span class="p">,</span> <span class="n">pArgs</span><span class="p">);</span>
|
||||
<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pArgs</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">pValue</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">printf</span><span class="p">(</span><span class="s">"Result of call: %ld</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">PyLong_AsLong</span><span class="p">(</span><span class="n">pValue</span><span class="p">));</span>
|
||||
<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pValue</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="p">{</span>
|
||||
<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pFunc</span><span class="p">);</span>
|
||||
<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pModule</span><span class="p">);</span>
|
||||
<span class="n">PyErr_Print</span><span class="p">();</span>
|
||||
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span><span class="s">"Call failed</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">PyErr_Occurred</span><span class="p">())</span>
|
||||
<span class="n">PyErr_Print</span><span class="p">();</span>
|
||||
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Cannot find function </span><span class="se">\"</span><span class="s">%s</span><span class="se">\"\n</span><span class="s">"</span><span class="p">,</span> <span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="n">Py_XDECREF</span><span class="p">(</span><span class="n">pFunc</span><span class="p">);</span>
|
||||
<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pModule</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span> <span class="p">{</span>
|
||||
<span class="n">PyErr_Print</span><span class="p">();</span>
|
||||
<span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Failed to load </span><span class="se">\"</span><span class="s">%s</span><span class="se">\"\n</span><span class="s">"</span><span class="p">,</span> <span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
|
||||
<span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">Py_FinalizeEx</span><span class="p">()</span> <span class="o"><</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="mi">120</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This code loads a Python script using <code class="docutils literal notranslate"><span class="pre">argv[1]</span></code>, and calls the function named
|
||||
in <code class="docutils literal notranslate"><span class="pre">argv[2]</span></code>. Its integer arguments are the other values of the <code class="docutils literal notranslate"><span class="pre">argv</span></code>
|
||||
array. If you <a class="reference internal" href="#compiling"><span class="std std-ref">compile and link</span></a> this program (let’s call
|
||||
the finished executable <strong class="program">call</strong>), and use it to execute a Python
|
||||
script, such as:</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">multiply</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">):</span>
|
||||
<span class="k">print</span><span class="p">(</span><span class="s2">"Will compute"</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="s2">"times"</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
|
||||
<span class="n">c</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
|
||||
<span class="n">c</span> <span class="o">=</span> <span class="n">c</span> <span class="o">+</span> <span class="n">b</span>
|
||||
<span class="k">return</span> <span class="n">c</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>then the result should be:</p>
|
||||
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> call multiply multiply <span class="m">3</span> <span class="m">2</span>
|
||||
<span class="go">Will compute 3 times 2</span>
|
||||
<span class="go">Result of call: 6</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Although the program is quite large for its functionality, most of the code is
|
||||
for data conversion between Python and C, and for error reporting. The
|
||||
interesting part with respect to embedding Python starts with</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">Py_Initialize</span><span class="p">();</span>
|
||||
<span class="n">pName</span> <span class="o">=</span> <span class="n">PyUnicode_DecodeFSDefault</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
|
||||
<span class="cm">/* Error checking of pName left out */</span>
|
||||
<span class="n">pModule</span> <span class="o">=</span> <span class="n">PyImport_Import</span><span class="p">(</span><span class="n">pName</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>After initializing the interpreter, the script is loaded using
|
||||
<a class="reference internal" href="../c-api/import.html#c.PyImport_Import" title="PyImport_Import"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyImport_Import()</span></code></a>. This routine needs a Python string as its argument,
|
||||
which is constructed using the <a class="reference internal" href="../c-api/unicode.html#c.PyUnicode_FromString" title="PyUnicode_FromString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyUnicode_FromString()</span></code></a> data conversion
|
||||
routine.</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">pFunc</span> <span class="o">=</span> <span class="n">PyObject_GetAttrString</span><span class="p">(</span><span class="n">pModule</span><span class="p">,</span> <span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
|
||||
<span class="cm">/* pFunc is a new reference */</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">pFunc</span> <span class="o">&&</span> <span class="n">PyCallable_Check</span><span class="p">(</span><span class="n">pFunc</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="p">...</span>
|
||||
<span class="p">}</span>
|
||||
<span class="n">Py_XDECREF</span><span class="p">(</span><span class="n">pFunc</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Once the script is loaded, the name we’re looking for is retrieved using
|
||||
<a class="reference internal" href="../c-api/object.html#c.PyObject_GetAttrString" title="PyObject_GetAttrString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_GetAttrString()</span></code></a>. If the name exists, and the object returned is
|
||||
callable, you can safely assume that it is a function. The program then
|
||||
proceeds by constructing a tuple of arguments as normal. The call to the Python
|
||||
function is then made with:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">pValue</span> <span class="o">=</span> <span class="n">PyObject_CallObject</span><span class="p">(</span><span class="n">pFunc</span><span class="p">,</span> <span class="n">pArgs</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Upon return of the function, <code class="docutils literal notranslate"><span class="pre">pValue</span></code> is either <em>NULL</em> or it contains a
|
||||
reference to the return value of the function. Be sure to release the reference
|
||||
after examining the value.</p>
|
||||
</div>
|
||||
<div class="section" id="extending-embedded-python">
|
||||
<span id="extending-with-embedding"></span><h2>1.4. Extending Embedded Python<a class="headerlink" href="#extending-embedded-python" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Until now, the embedded Python interpreter had no access to functionality from
|
||||
the application itself. The Python API allows this by extending the embedded
|
||||
interpreter. That is, the embedded interpreter gets extended with routines
|
||||
provided by the application. While it sounds complex, it is not so bad. Simply
|
||||
forget for a while that the application starts the Python interpreter. Instead,
|
||||
consider the application to be a set of subroutines, and write some glue code
|
||||
that gives Python access to those routines, just like you would write a normal
|
||||
Python extension. For example:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="kt">int</span> <span class="n">numargs</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* Return the number of arguments of the application command line */</span>
|
||||
<span class="k">static</span> <span class="n">PyObject</span><span class="o">*</span>
|
||||
<span class="nf">emb_numargs</span><span class="p">(</span><span class="n">PyObject</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">PyObject</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">PyArg_ParseTuple</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="s">":numargs"</span><span class="p">))</span>
|
||||
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
|
||||
<span class="k">return</span> <span class="n">PyLong_FromLong</span><span class="p">(</span><span class="n">numargs</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">static</span> <span class="n">PyMethodDef</span> <span class="n">EmbMethods</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="p">{</span><span class="s">"numargs"</span><span class="p">,</span> <span class="n">emb_numargs</span><span class="p">,</span> <span class="n">METH_VARARGS</span><span class="p">,</span>
|
||||
<span class="s">"Return the number of arguments received by the process."</span><span class="p">},</span>
|
||||
<span class="p">{</span><span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">}</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="k">static</span> <span class="n">PyModuleDef</span> <span class="n">EmbModule</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="n">PyModuleDef_HEAD_INIT</span><span class="p">,</span> <span class="s">"emb"</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">EmbMethods</span><span class="p">,</span>
|
||||
<span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span>
|
||||
<span class="p">};</span>
|
||||
|
||||
<span class="k">static</span> <span class="n">PyObject</span><span class="o">*</span>
|
||||
<span class="nf">PyInit_emb</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="n">PyModule_Create</span><span class="p">(</span><span class="o">&</span><span class="n">EmbModule</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Insert the above code just above the <code class="xref c c-func docutils literal notranslate"><span class="pre">main()</span></code> function. Also, insert the
|
||||
following two statements before the call to <a class="reference internal" href="../c-api/init.html#c.Py_Initialize" title="Py_Initialize"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_Initialize()</span></code></a>:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">numargs</span> <span class="o">=</span> <span class="n">argc</span><span class="p">;</span>
|
||||
<span class="n">PyImport_AppendInittab</span><span class="p">(</span><span class="s">"emb"</span><span class="p">,</span> <span class="o">&</span><span class="n">PyInit_emb</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>These two lines initialize the <code class="docutils literal notranslate"><span class="pre">numargs</span></code> variable, and make the
|
||||
<code class="xref py py-func docutils literal notranslate"><span class="pre">emb.numargs()</span></code> function accessible to the embedded Python interpreter.
|
||||
With these extensions, the Python script can do things like</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">emb</span>
|
||||
<span class="k">print</span><span class="p">(</span><span class="s2">"Number of arguments"</span><span class="p">,</span> <span class="n">emb</span><span class="o">.</span><span class="n">numargs</span><span class="p">())</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>In a real application, the methods will expose an API of the application to
|
||||
Python.</p>
|
||||
</div>
|
||||
<div class="section" id="embedding-python-in-c">
|
||||
<span id="embeddingincplusplus"></span><h2>1.5. Embedding Python in C++<a class="headerlink" href="#embedding-python-in-c" title="Permalink to this headline">¶</a></h2>
|
||||
<p>It is also possible to embed Python in a C++ program; precisely how this is done
|
||||
will depend on the details of the C++ system used; in general you will need to
|
||||
write the main program in C++, and use the C++ compiler to compile and link your
|
||||
program. There is no need to recompile Python itself using C++.</p>
|
||||
</div>
|
||||
<div class="section" id="compiling-and-linking-under-unix-like-systems">
|
||||
<span id="compiling"></span><h2>1.6. Compiling and Linking under Unix-like systems<a class="headerlink" href="#compiling-and-linking-under-unix-like-systems" title="Permalink to this headline">¶</a></h2>
|
||||
<p>It is not necessarily trivial to find the right flags to pass to your
|
||||
compiler (and linker) in order to embed the Python interpreter into your
|
||||
application, particularly because Python needs to load library modules
|
||||
implemented as C dynamic extensions (<code class="file docutils literal notranslate"><span class="pre">.so</span></code> files) linked against
|
||||
it.</p>
|
||||
<p>To find out the required compiler and linker flags, you can execute the
|
||||
<code class="file docutils literal notranslate"><span class="pre">python</span><em><span class="pre">X.Y</span></em><span class="pre">-config</span></code> script which is generated as part of the
|
||||
installation process (a <code class="file docutils literal notranslate"><span class="pre">python3-config</span></code> script may also be
|
||||
available). This script has several options, of which the following will
|
||||
be directly useful to you:</p>
|
||||
<ul>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">pythonX.Y-config</span> <span class="pre">--cflags</span></code> will give you the recommended flags when
|
||||
compiling:</p>
|
||||
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> /opt/bin/python3.4-config --cflags
|
||||
<span class="go">-I/opt/include/python3.4m -I/opt/include/python3.4m -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">pythonX.Y-config</span> <span class="pre">--ldflags</span></code> will give you the recommended flags when
|
||||
linking:</p>
|
||||
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> /opt/bin/python3.4-config --ldflags
|
||||
<span class="go">-L/opt/lib/python3.4/config-3.4m -lpthread -ldl -lutil -lm -lpython3.4m -Xlinker -export-dynamic</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Note</p>
|
||||
<p>To avoid confusion between several Python installations (and especially
|
||||
between the system Python and your own compiled Python), it is recommended
|
||||
that you use the absolute path to <code class="file docutils literal notranslate"><span class="pre">python</span><em><span class="pre">X.Y</span></em><span class="pre">-config</span></code>, as in the above
|
||||
example.</p>
|
||||
</div>
|
||||
<p>If this procedure doesn’t work for you (it is not guaranteed to work for
|
||||
all Unix-like platforms; however, we welcome <a class="reference internal" href="../bugs.html#reporting-bugs"><span class="std std-ref">bug reports</span></a>)
|
||||
you will have to read your system’s documentation about dynamic linking and/or
|
||||
examine Python’s <code class="file docutils literal notranslate"><span class="pre">Makefile</span></code> (use <a class="reference internal" href="../library/sysconfig.html#sysconfig.get_makefile_filename" title="sysconfig.get_makefile_filename"><code class="xref py py-func docutils literal notranslate"><span class="pre">sysconfig.get_makefile_filename()</span></code></a>
|
||||
to find its location) and compilation
|
||||
options. In this case, the <a class="reference internal" href="../library/sysconfig.html#module-sysconfig" title="sysconfig: Python's configuration information"><code class="xref py py-mod docutils literal notranslate"><span class="pre">sysconfig</span></code></a> module is a useful tool to
|
||||
programmatically extract the configuration values that you will want to
|
||||
combine together. For example:</p>
|
||||
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">sysconfig</span>
|
||||
<span class="gp">>>> </span><span class="n">sysconfig</span><span class="o">.</span><span class="n">get_config_var</span><span class="p">(</span><span class="s1">'LIBS'</span><span class="p">)</span>
|
||||
<span class="go">'-lpthread -ldl -lutil'</span>
|
||||
<span class="gp">>>> </span><span class="n">sysconfig</span><span class="o">.</span><span class="n">get_config_var</span><span class="p">(</span><span class="s1">'LINKFORSHARED'</span><span class="p">)</span>
|
||||
<span class="go">'-Xlinker -export-dynamic'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">1. Embedding Python in Another Application</a><ul>
|
||||
<li><a class="reference internal" href="#very-high-level-embedding">1.1. Very High Level Embedding</a></li>
|
||||
<li><a class="reference internal" href="#beyond-very-high-level-embedding-an-overview">1.2. Beyond Very High Level Embedding: An overview</a></li>
|
||||
<li><a class="reference internal" href="#pure-embedding">1.3. Pure Embedding</a></li>
|
||||
<li><a class="reference internal" href="#extending-embedded-python">1.4. Extending Embedded Python</a></li>
|
||||
<li><a class="reference internal" href="#embedding-python-in-c">1.5. Embedding Python in C++</a></li>
|
||||
<li><a class="reference internal" href="#compiling-and-linking-under-unix-like-systems">1.6. Compiling and Linking under Unix-like systems</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="windows.html"
|
||||
title="previous chapter">5. Building C and C++ Extensions on Windows</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="../c-api/index.html"
|
||||
title="next chapter">Python/C API Reference Manual</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.7/Doc/extending/embedding.rst"
|
||||
rel="nofollow">Show Source
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="../c-api/index.html" title="Python/C API Reference Manual"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="windows.html" title="5. Building C and C++ Extensions on Windows"
|
||||
>previous</a> |</li>
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||||
<li>
|
||||
<span class="language_switcher_placeholder">en</span>
|
||||
<span class="version_switcher_placeholder">3.7.4</span>
|
||||
<a href="../index.html">Documentation </a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Extending and Embedding the Python Interpreter</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" style="display: none" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="Quick search" type="text" name="q" />
|
||||
<input type="submit" value="Go" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
|
||||
<br />
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
Last updated on Jul 13, 2019.
|
||||
<a href="../bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.0.1.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
1395
python-3.7.4-docs-html/extending/extending.html
Normal file
1395
python-3.7.4-docs-html/extending/extending.html
Normal file
File diff suppressed because it is too large
Load Diff
297
python-3.7.4-docs-html/extending/index.html
Normal file
297
python-3.7.4-docs-html/extending/index.html
Normal file
@@ -0,0 +1,297 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Extending and Embedding the Python Interpreter — Python 3.7.4 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="Search within Python 3.7.4 documentation"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="About these documents" href="../about.html" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||||
<link rel="next" title="1. Extending Python with C or C++" href="extending.html" />
|
||||
<link rel="prev" title="Undocumented Modules" href="../library/undoc.html" />
|
||||
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/extending/index.html" />
|
||||
|
||||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||||
<script type="text/javascript" src="../_static/switchers.js"></script>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head><body>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="extending.html" title="1. Extending Python with C or C++"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="../library/undoc.html" title="Undocumented Modules"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||||
<li>
|
||||
<span class="language_switcher_placeholder">en</span>
|
||||
<span class="version_switcher_placeholder">3.7.4</span>
|
||||
<a href="../index.html">Documentation </a> »
|
||||
</li>
|
||||
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" style="display: none" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="Quick search" type="text" name="q" />
|
||||
<input type="submit" value="Go" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="extending-and-embedding-the-python-interpreter">
|
||||
<span id="extending-index"></span><h1>Extending and Embedding the Python Interpreter<a class="headerlink" href="#extending-and-embedding-the-python-interpreter" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This document describes how to write modules in C or C++ to extend the Python
|
||||
interpreter with new modules. Those modules can not only define new functions
|
||||
but also new object types and their methods. The document also describes how
|
||||
to embed the Python interpreter in another application, for use as an extension
|
||||
language. Finally, it shows how to compile and link extension modules so that
|
||||
they can be loaded dynamically (at run time) into the interpreter, if the
|
||||
underlying operating system supports this feature.</p>
|
||||
<p>This document assumes basic knowledge about Python. For an informal
|
||||
introduction to the language, see <a class="reference internal" href="../tutorial/index.html#tutorial-index"><span class="std std-ref">The Python Tutorial</span></a>. <a class="reference internal" href="../reference/index.html#reference-index"><span class="std std-ref">The Python Language Reference</span></a>
|
||||
gives a more formal definition of the language. <a class="reference internal" href="../library/index.html#library-index"><span class="std std-ref">The Python Standard Library</span></a> documents
|
||||
the existing object types, functions and modules (both built-in and written in
|
||||
Python) that give the language its wide application range.</p>
|
||||
<p>For a detailed description of the whole Python/C API, see the separate
|
||||
<a class="reference internal" href="../c-api/index.html#c-api-index"><span class="std std-ref">Python/C API Reference Manual</span></a>.</p>
|
||||
<div class="section" id="recommended-third-party-tools">
|
||||
<h2>Recommended third party tools<a class="headerlink" href="#recommended-third-party-tools" title="Permalink to this headline">¶</a></h2>
|
||||
<p>This guide only covers the basic tools for creating extensions provided
|
||||
as part of this version of CPython. Third party tools like
|
||||
<a class="reference external" href="http://cython.org/">Cython</a>, <a class="reference external" href="https://cffi.readthedocs.io">cffi</a>,
|
||||
<a class="reference external" href="http://www.swig.org">SWIG</a> and <a class="reference external" href="https://numba.pydata.org/">Numba</a>
|
||||
offer both simpler and more sophisticated approaches to creating C and C++
|
||||
extensions for Python.</p>
|
||||
<div class="admonition seealso">
|
||||
<p class="admonition-title">See also</p>
|
||||
<dl class="simple">
|
||||
<dt><a class="reference external" href="https://packaging.python.org/guides/packaging-binary-extensions/">Python Packaging User Guide: Binary Extensions</a></dt><dd><p>The Python Packaging User Guide not only covers several available
|
||||
tools that simplify the creation of binary extensions, but also
|
||||
discusses the various reasons why creating an extension module may be
|
||||
desirable in the first place.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="creating-extensions-without-third-party-tools">
|
||||
<h2>Creating extensions without third party tools<a class="headerlink" href="#creating-extensions-without-third-party-tools" title="Permalink to this headline">¶</a></h2>
|
||||
<p>This section of the guide covers creating C and C++ extensions without
|
||||
assistance from third party tools. It is intended primarily for creators
|
||||
of those tools, rather than being a recommended way to create your own
|
||||
C extensions.</p>
|
||||
<div class="toctree-wrapper compound">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="extending.html">1. Extending Python with C or C++</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#a-simple-example">1.1. A Simple Example</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#intermezzo-errors-and-exceptions">1.2. Intermezzo: Errors and Exceptions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#back-to-the-example">1.3. Back to the Example</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#the-module-s-method-table-and-initialization-function">1.4. The Module’s Method Table and Initialization Function</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#compilation-and-linkage">1.5. Compilation and Linkage</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#calling-python-functions-from-c">1.6. Calling Python Functions from C</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#extracting-parameters-in-extension-functions">1.7. Extracting Parameters in Extension Functions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#keyword-parameters-for-extension-functions">1.8. Keyword Parameters for Extension Functions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#building-arbitrary-values">1.9. Building Arbitrary Values</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#reference-counts">1.10. Reference Counts</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#writing-extensions-in-c">1.11. Writing Extensions in C++</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="extending.html#providing-a-c-api-for-an-extension-module">1.12. Providing a C API for an Extension Module</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="newtypes_tutorial.html">2. Defining Extension Types: Tutorial</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes_tutorial.html#the-basics">2.1. The Basics</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes_tutorial.html#adding-data-and-methods-to-the-basic-example">2.2. Adding data and methods to the Basic example</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes_tutorial.html#providing-finer-control-over-data-attributes">2.3. Providing finer control over data attributes</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes_tutorial.html#supporting-cyclic-garbage-collection">2.4. Supporting cyclic garbage collection</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes_tutorial.html#subclassing-other-types">2.5. Subclassing other types</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="newtypes.html">3. Defining Extension Types: Assorted Topics</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes.html#finalization-and-de-allocation">3.1. Finalization and De-allocation</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes.html#object-presentation">3.2. Object Presentation</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes.html#attribute-management">3.3. Attribute Management</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes.html#object-comparison">3.4. Object Comparison</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes.html#abstract-protocol-support">3.5. Abstract Protocol Support</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes.html#weak-reference-support">3.6. Weak Reference Support</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="newtypes.html#more-suggestions">3.7. More Suggestions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="building.html">4. Building C and C++ Extensions</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="building.html#building-c-and-c-extensions-with-distutils">4.1. Building C and C++ Extensions with distutils</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="building.html#distributing-your-extension-modules">4.2. Distributing your extension modules</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="windows.html">5. Building C and C++ Extensions on Windows</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="windows.html#a-cookbook-approach">5.1. A Cookbook Approach</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="windows.html#differences-between-unix-and-windows">5.2. Differences Between Unix and Windows</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="windows.html#using-dlls-in-practice">5.3. Using DLLs in Practice</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="embedding-the-cpython-runtime-in-a-larger-application">
|
||||
<h2>Embedding the CPython runtime in a larger application<a class="headerlink" href="#embedding-the-cpython-runtime-in-a-larger-application" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Sometimes, rather than creating an extension that runs inside the Python
|
||||
interpreter as the main application, it is desirable to instead embed
|
||||
the CPython runtime inside a larger application. This section covers
|
||||
some of the details involved in doing that successfully.</p>
|
||||
<div class="toctree-wrapper compound">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="embedding.html">1. Embedding Python in Another Application</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="embedding.html#very-high-level-embedding">1.1. Very High Level Embedding</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="embedding.html#beyond-very-high-level-embedding-an-overview">1.2. Beyond Very High Level Embedding: An overview</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="embedding.html#pure-embedding">1.3. Pure Embedding</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="embedding.html#extending-embedded-python">1.4. Extending Embedded Python</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="embedding.html#embedding-python-in-c">1.5. Embedding Python in C++</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="embedding.html#compiling-and-linking-under-unix-like-systems">1.6. Compiling and Linking under Unix-like systems</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Extending and Embedding the Python Interpreter</a><ul>
|
||||
<li><a class="reference internal" href="#recommended-third-party-tools">Recommended third party tools</a></li>
|
||||
<li><a class="reference internal" href="#creating-extensions-without-third-party-tools">Creating extensions without third party tools</a></li>
|
||||
<li><a class="reference internal" href="#embedding-the-cpython-runtime-in-a-larger-application">Embedding the CPython runtime in a larger application</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="../library/undoc.html"
|
||||
title="previous chapter">Undocumented Modules</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="extending.html"
|
||||
title="next chapter">1. Extending Python with C or C++</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.7/Doc/extending/index.rst"
|
||||
rel="nofollow">Show Source
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="extending.html" title="1. Extending Python with C or C++"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="../library/undoc.html" title="Undocumented Modules"
|
||||
>previous</a> |</li>
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||||
<li>
|
||||
<span class="language_switcher_placeholder">en</span>
|
||||
<span class="version_switcher_placeholder">3.7.4</span>
|
||||
<a href="../index.html">Documentation </a> »
|
||||
</li>
|
||||
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" style="display: none" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="Quick search" type="text" name="q" />
|
||||
<input type="submit" value="Go" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
|
||||
<br />
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
Last updated on Jul 13, 2019.
|
||||
<a href="../bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.0.1.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
828
python-3.7.4-docs-html/extending/newtypes.html
Normal file
828
python-3.7.4-docs-html/extending/newtypes.html
Normal file
@@ -0,0 +1,828 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>3. Defining Extension Types: Assorted Topics — Python 3.7.4 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="Search within Python 3.7.4 documentation"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="About these documents" href="../about.html" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||||
<link rel="next" title="4. Building C and C++ Extensions" href="building.html" />
|
||||
<link rel="prev" title="2. Defining Extension Types: Tutorial" href="newtypes_tutorial.html" />
|
||||
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/extending/newtypes.html" />
|
||||
|
||||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||||
<script type="text/javascript" src="../_static/switchers.js"></script>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head><body>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="building.html" title="4. Building C and C++ Extensions"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="newtypes_tutorial.html" title="2. Defining Extension Types: Tutorial"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||||
<li>
|
||||
<span class="language_switcher_placeholder">en</span>
|
||||
<span class="version_switcher_placeholder">3.7.4</span>
|
||||
<a href="../index.html">Documentation </a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Extending and Embedding the Python Interpreter</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" style="display: none" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="Quick search" type="text" name="q" />
|
||||
<input type="submit" value="Go" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="defining-extension-types-assorted-topics">
|
||||
<h1>3. Defining Extension Types: Assorted Topics<a class="headerlink" href="#defining-extension-types-assorted-topics" title="Permalink to this headline">¶</a></h1>
|
||||
<p id="dnt-type-methods">This section aims to give a quick fly-by on the various type methods you can
|
||||
implement and what they do.</p>
|
||||
<p>Here is the definition of <a class="reference internal" href="../c-api/type.html#c.PyTypeObject" title="PyTypeObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyTypeObject</span></code></a>, with some fields only used in
|
||||
debug builds omitted:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span> <span class="k">struct</span> <span class="n">_typeobject</span> <span class="p">{</span>
|
||||
<span class="n">PyObject_VAR_HEAD</span>
|
||||
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">tp_name</span><span class="p">;</span> <span class="cm">/* For printing, in format "<module>.<name>" */</span>
|
||||
<span class="n">Py_ssize_t</span> <span class="n">tp_basicsize</span><span class="p">,</span> <span class="n">tp_itemsize</span><span class="p">;</span> <span class="cm">/* For allocation */</span>
|
||||
|
||||
<span class="cm">/* Methods to implement standard operations */</span>
|
||||
|
||||
<span class="n">destructor</span> <span class="n">tp_dealloc</span><span class="p">;</span>
|
||||
<span class="n">printfunc</span> <span class="n">tp_print</span><span class="p">;</span>
|
||||
<span class="n">getattrfunc</span> <span class="n">tp_getattr</span><span class="p">;</span>
|
||||
<span class="n">setattrfunc</span> <span class="n">tp_setattr</span><span class="p">;</span>
|
||||
<span class="n">PyAsyncMethods</span> <span class="o">*</span><span class="n">tp_as_async</span><span class="p">;</span> <span class="cm">/* formerly known as tp_compare (Python 2)</span>
|
||||
<span class="cm"> or tp_reserved (Python 3) */</span>
|
||||
<span class="n">reprfunc</span> <span class="n">tp_repr</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* Method suites for standard classes */</span>
|
||||
|
||||
<span class="n">PyNumberMethods</span> <span class="o">*</span><span class="n">tp_as_number</span><span class="p">;</span>
|
||||
<span class="n">PySequenceMethods</span> <span class="o">*</span><span class="n">tp_as_sequence</span><span class="p">;</span>
|
||||
<span class="n">PyMappingMethods</span> <span class="o">*</span><span class="n">tp_as_mapping</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* More standard operations (here for binary compatibility) */</span>
|
||||
|
||||
<span class="n">hashfunc</span> <span class="n">tp_hash</span><span class="p">;</span>
|
||||
<span class="n">ternaryfunc</span> <span class="n">tp_call</span><span class="p">;</span>
|
||||
<span class="n">reprfunc</span> <span class="n">tp_str</span><span class="p">;</span>
|
||||
<span class="n">getattrofunc</span> <span class="n">tp_getattro</span><span class="p">;</span>
|
||||
<span class="n">setattrofunc</span> <span class="n">tp_setattro</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* Functions to access object as input/output buffer */</span>
|
||||
<span class="n">PyBufferProcs</span> <span class="o">*</span><span class="n">tp_as_buffer</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* Flags to define presence of optional/expanded features */</span>
|
||||
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">tp_flags</span><span class="p">;</span>
|
||||
|
||||
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">tp_doc</span><span class="p">;</span> <span class="cm">/* Documentation string */</span>
|
||||
|
||||
<span class="cm">/* call function for all accessible objects */</span>
|
||||
<span class="n">traverseproc</span> <span class="n">tp_traverse</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* delete references to contained objects */</span>
|
||||
<span class="n">inquiry</span> <span class="n">tp_clear</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* rich comparisons */</span>
|
||||
<span class="n">richcmpfunc</span> <span class="n">tp_richcompare</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* weak reference enabler */</span>
|
||||
<span class="n">Py_ssize_t</span> <span class="n">tp_weaklistoffset</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* Iterators */</span>
|
||||
<span class="n">getiterfunc</span> <span class="n">tp_iter</span><span class="p">;</span>
|
||||
<span class="n">iternextfunc</span> <span class="n">tp_iternext</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* Attribute descriptor and subclassing stuff */</span>
|
||||
<span class="k">struct</span> <span class="n">PyMethodDef</span> <span class="o">*</span><span class="n">tp_methods</span><span class="p">;</span>
|
||||
<span class="k">struct</span> <span class="n">PyMemberDef</span> <span class="o">*</span><span class="n">tp_members</span><span class="p">;</span>
|
||||
<span class="k">struct</span> <span class="n">PyGetSetDef</span> <span class="o">*</span><span class="n">tp_getset</span><span class="p">;</span>
|
||||
<span class="k">struct</span> <span class="n">_typeobject</span> <span class="o">*</span><span class="n">tp_base</span><span class="p">;</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">tp_dict</span><span class="p">;</span>
|
||||
<span class="n">descrgetfunc</span> <span class="n">tp_descr_get</span><span class="p">;</span>
|
||||
<span class="n">descrsetfunc</span> <span class="n">tp_descr_set</span><span class="p">;</span>
|
||||
<span class="n">Py_ssize_t</span> <span class="n">tp_dictoffset</span><span class="p">;</span>
|
||||
<span class="n">initproc</span> <span class="n">tp_init</span><span class="p">;</span>
|
||||
<span class="n">allocfunc</span> <span class="n">tp_alloc</span><span class="p">;</span>
|
||||
<span class="n">newfunc</span> <span class="n">tp_new</span><span class="p">;</span>
|
||||
<span class="n">freefunc</span> <span class="n">tp_free</span><span class="p">;</span> <span class="cm">/* Low-level free-memory routine */</span>
|
||||
<span class="n">inquiry</span> <span class="n">tp_is_gc</span><span class="p">;</span> <span class="cm">/* For PyObject_IS_GC */</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">tp_bases</span><span class="p">;</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">tp_mro</span><span class="p">;</span> <span class="cm">/* method resolution order */</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">tp_cache</span><span class="p">;</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">tp_subclasses</span><span class="p">;</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">tp_weaklist</span><span class="p">;</span>
|
||||
<span class="n">destructor</span> <span class="n">tp_del</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* Type attribute cache version tag. Added in version 2.6 */</span>
|
||||
<span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">tp_version_tag</span><span class="p">;</span>
|
||||
|
||||
<span class="n">destructor</span> <span class="n">tp_finalize</span><span class="p">;</span>
|
||||
|
||||
<span class="p">}</span> <span class="n">PyTypeObject</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now that’s a <em>lot</em> of methods. Don’t worry too much though – if you have
|
||||
a type you want to define, the chances are very good that you will only
|
||||
implement a handful of these.</p>
|
||||
<p>As you probably expect by now, we’re going to go over this and give more
|
||||
information about the various handlers. We won’t go in the order they are
|
||||
defined in the structure, because there is a lot of historical baggage that
|
||||
impacts the ordering of the fields. It’s often easiest to find an example
|
||||
that includes the fields you need and then change the values to suit your new
|
||||
type.</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">tp_name</span><span class="p">;</span> <span class="cm">/* For printing */</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The name of the type – as mentioned in the previous chapter, this will appear in
|
||||
various places, almost entirely for diagnostic purposes. Try to choose something
|
||||
that will be helpful in such a situation!</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">Py_ssize_t</span> <span class="n">tp_basicsize</span><span class="p">,</span> <span class="n">tp_itemsize</span><span class="p">;</span> <span class="cm">/* For allocation */</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>These fields tell the runtime how much memory to allocate when new objects of
|
||||
this type are created. Python has some built-in support for variable length
|
||||
structures (think: strings, tuples) which is where the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_itemsize" title="PyTypeObject.tp_itemsize"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_itemsize</span></code></a> field
|
||||
comes in. This will be dealt with later.</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">tp_doc</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Here you can put a string (or its address) that you want returned when the
|
||||
Python script references <code class="docutils literal notranslate"><span class="pre">obj.__doc__</span></code> to retrieve the doc string.</p>
|
||||
<p>Now we come to the basic type methods – the ones most extension types will
|
||||
implement.</p>
|
||||
<div class="section" id="finalization-and-de-allocation">
|
||||
<h2>3.1. Finalization and De-allocation<a class="headerlink" href="#finalization-and-de-allocation" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="highlight-c notranslate" id="index-0"><div class="highlight"><pre><span></span><span class="n">destructor</span> <span class="n">tp_dealloc</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This function is called when the reference count of the instance of your type is
|
||||
reduced to zero and the Python interpreter wants to reclaim it. If your type
|
||||
has memory to free or other clean-up to perform, you can put it here. The
|
||||
object itself needs to be freed here as well. Here is an example of this
|
||||
function:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="kt">void</span>
|
||||
<span class="nf">newdatatype_dealloc</span><span class="p">(</span><span class="n">newdatatypeobject</span> <span class="o">*</span><span class="n">obj</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="n">free</span><span class="p">(</span><span class="n">obj</span><span class="o">-></span><span class="n">obj_UnderlyingDatatypePtr</span><span class="p">);</span>
|
||||
<span class="n">Py_TYPE</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">-></span><span class="n">tp_free</span><span class="p">(</span><span class="n">obj</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p id="index-1">One important requirement of the deallocator function is that it leaves any
|
||||
pending exceptions alone. This is important since deallocators are frequently
|
||||
called as the interpreter unwinds the Python stack; when the stack is unwound
|
||||
due to an exception (rather than normal returns), nothing is done to protect the
|
||||
deallocators from seeing that an exception has already been set. Any actions
|
||||
which a deallocator performs which may cause additional Python code to be
|
||||
executed may detect that an exception has been set. This can lead to misleading
|
||||
errors from the interpreter. The proper way to protect against this is to save
|
||||
a pending exception before performing the unsafe action, and restoring it when
|
||||
done. This can be done using the <a class="reference internal" href="../c-api/exceptions.html#c.PyErr_Fetch" title="PyErr_Fetch"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyErr_Fetch()</span></code></a> and
|
||||
<a class="reference internal" href="../c-api/exceptions.html#c.PyErr_Restore" title="PyErr_Restore"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyErr_Restore()</span></code></a> functions:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="kt">void</span>
|
||||
<span class="nf">my_dealloc</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="p">{</span>
|
||||
<span class="n">MyObject</span> <span class="o">*</span><span class="n">self</span> <span class="o">=</span> <span class="p">(</span><span class="n">MyObject</span> <span class="o">*</span><span class="p">)</span> <span class="n">obj</span><span class="p">;</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">cbresult</span><span class="p">;</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">my_callback</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">err_type</span><span class="p">,</span> <span class="o">*</span><span class="n">err_value</span><span class="p">,</span> <span class="o">*</span><span class="n">err_traceback</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* This saves the current exception state */</span>
|
||||
<span class="n">PyErr_Fetch</span><span class="p">(</span><span class="o">&</span><span class="n">err_type</span><span class="p">,</span> <span class="o">&</span><span class="n">err_value</span><span class="p">,</span> <span class="o">&</span><span class="n">err_traceback</span><span class="p">);</span>
|
||||
|
||||
<span class="n">cbresult</span> <span class="o">=</span> <span class="n">PyObject_CallObject</span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">my_callback</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">cbresult</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
|
||||
<span class="n">PyErr_WriteUnraisable</span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">my_callback</span><span class="p">);</span>
|
||||
<span class="k">else</span>
|
||||
<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">cbresult</span><span class="p">);</span>
|
||||
|
||||
<span class="cm">/* This restores the saved exception state */</span>
|
||||
<span class="n">PyErr_Restore</span><span class="p">(</span><span class="n">err_type</span><span class="p">,</span> <span class="n">err_value</span><span class="p">,</span> <span class="n">err_traceback</span><span class="p">);</span>
|
||||
|
||||
<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">my_callback</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="n">Py_TYPE</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">-></span><span class="n">tp_free</span><span class="p">((</span><span class="n">PyObject</span><span class="o">*</span><span class="p">)</span><span class="n">self</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Note</p>
|
||||
<p>There are limitations to what you can safely do in a deallocator function.
|
||||
First, if your type supports garbage collection (using <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_traverse" title="PyTypeObject.tp_traverse"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_traverse</span></code></a>
|
||||
and/or <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_clear" title="PyTypeObject.tp_clear"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_clear</span></code></a>), some of the object’s members can have been
|
||||
cleared or finalized by the time <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_dealloc" title="PyTypeObject.tp_dealloc"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_dealloc</span></code></a> is called. Second, in
|
||||
<a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_dealloc" title="PyTypeObject.tp_dealloc"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_dealloc</span></code></a>, your object is in an unstable state: its reference
|
||||
count is equal to zero. Any call to a non-trivial object or API (as in the
|
||||
example above) might end up calling <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_dealloc" title="PyTypeObject.tp_dealloc"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_dealloc</span></code></a> again, causing a
|
||||
double free and a crash.</p>
|
||||
<p>Starting with Python 3.4, it is recommended not to put any complex
|
||||
finalization code in <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_dealloc" title="PyTypeObject.tp_dealloc"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_dealloc</span></code></a>, and instead use the new
|
||||
<a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_finalize" title="PyTypeObject.tp_finalize"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_finalize</span></code></a> type method.</p>
|
||||
<div class="admonition seealso">
|
||||
<p class="admonition-title">See also</p>
|
||||
<p><span class="target" id="index-2"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0442"><strong>PEP 442</strong></a> explains the new finalization scheme.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="object-presentation">
|
||||
<span id="index-3"></span><h2>3.2. Object Presentation<a class="headerlink" href="#object-presentation" title="Permalink to this headline">¶</a></h2>
|
||||
<p>In Python, there are two ways to generate a textual representation of an object:
|
||||
the <a class="reference internal" href="../library/functions.html#repr" title="repr"><code class="xref py py-func docutils literal notranslate"><span class="pre">repr()</span></code></a> function, and the <a class="reference internal" href="../library/stdtypes.html#str" title="str"><code class="xref py py-func docutils literal notranslate"><span class="pre">str()</span></code></a> function. (The <a class="reference internal" href="../library/functions.html#print" title="print"><code class="xref py py-func docutils literal notranslate"><span class="pre">print()</span></code></a>
|
||||
function just calls <a class="reference internal" href="../library/stdtypes.html#str" title="str"><code class="xref py py-func docutils literal notranslate"><span class="pre">str()</span></code></a>.) These handlers are both optional.</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">reprfunc</span> <span class="n">tp_repr</span><span class="p">;</span>
|
||||
<span class="n">reprfunc</span> <span class="n">tp_str</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_repr" title="PyTypeObject.tp_repr"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_repr</span></code></a> handler should return a string object containing a
|
||||
representation of the instance for which it is called. Here is a simple
|
||||
example:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">PyObject</span> <span class="o">*</span>
|
||||
<span class="nf">newdatatype_repr</span><span class="p">(</span><span class="n">newdatatypeobject</span> <span class="o">*</span> <span class="n">obj</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="n">PyUnicode_FromFormat</span><span class="p">(</span><span class="s">"Repr-ified_newdatatype{{size:%d}}"</span><span class="p">,</span>
|
||||
<span class="n">obj</span><span class="o">-></span><span class="n">obj_UnderlyingDatatypePtr</span><span class="o">-></span><span class="n">size</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If no <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_repr" title="PyTypeObject.tp_repr"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_repr</span></code></a> handler is specified, the interpreter will supply a
|
||||
representation that uses the type’s <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_name" title="PyTypeObject.tp_name"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_name</span></code></a> and a uniquely-identifying
|
||||
value for the object.</p>
|
||||
<p>The <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_str" title="PyTypeObject.tp_str"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_str</span></code></a> handler is to <a class="reference internal" href="../library/stdtypes.html#str" title="str"><code class="xref py py-func docutils literal notranslate"><span class="pre">str()</span></code></a> what the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_repr" title="PyTypeObject.tp_repr"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_repr</span></code></a> handler
|
||||
described above is to <a class="reference internal" href="../library/functions.html#repr" title="repr"><code class="xref py py-func docutils literal notranslate"><span class="pre">repr()</span></code></a>; that is, it is called when Python code calls
|
||||
<a class="reference internal" href="../library/stdtypes.html#str" title="str"><code class="xref py py-func docutils literal notranslate"><span class="pre">str()</span></code></a> on an instance of your object. Its implementation is very similar
|
||||
to the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_repr" title="PyTypeObject.tp_repr"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_repr</span></code></a> function, but the resulting string is intended for human
|
||||
consumption. If <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_str" title="PyTypeObject.tp_str"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_str</span></code></a> is not specified, the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_repr" title="PyTypeObject.tp_repr"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_repr</span></code></a> handler is
|
||||
used instead.</p>
|
||||
<p>Here is a simple example:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">PyObject</span> <span class="o">*</span>
|
||||
<span class="nf">newdatatype_str</span><span class="p">(</span><span class="n">newdatatypeobject</span> <span class="o">*</span> <span class="n">obj</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="n">PyUnicode_FromFormat</span><span class="p">(</span><span class="s">"Stringified_newdatatype{{size:%d}}"</span><span class="p">,</span>
|
||||
<span class="n">obj</span><span class="o">-></span><span class="n">obj_UnderlyingDatatypePtr</span><span class="o">-></span><span class="n">size</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="attribute-management">
|
||||
<h2>3.3. Attribute Management<a class="headerlink" href="#attribute-management" title="Permalink to this headline">¶</a></h2>
|
||||
<p>For every object which can support attributes, the corresponding type must
|
||||
provide the functions that control how the attributes are resolved. There needs
|
||||
to be a function which can retrieve attributes (if any are defined), and another
|
||||
to set attributes (if setting attributes is allowed). Removing an attribute is
|
||||
a special case, for which the new value passed to the handler is <em>NULL</em>.</p>
|
||||
<p>Python supports two pairs of attribute handlers; a type that supports attributes
|
||||
only needs to implement the functions for one pair. The difference is that one
|
||||
pair takes the name of the attribute as a <code class="xref c c-type docutils literal notranslate"><span class="pre">char*</span></code>, while the other
|
||||
accepts a <a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject*</span></code></a>. Each type can use whichever pair makes more
|
||||
sense for the implementation’s convenience.</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">getattrfunc</span> <span class="n">tp_getattr</span><span class="p">;</span> <span class="cm">/* char * version */</span>
|
||||
<span class="n">setattrfunc</span> <span class="n">tp_setattr</span><span class="p">;</span>
|
||||
<span class="cm">/* ... */</span>
|
||||
<span class="n">getattrofunc</span> <span class="n">tp_getattro</span><span class="p">;</span> <span class="cm">/* PyObject * version */</span>
|
||||
<span class="n">setattrofunc</span> <span class="n">tp_setattro</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If accessing attributes of an object is always a simple operation (this will be
|
||||
explained shortly), there are generic implementations which can be used to
|
||||
provide the <a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject*</span></code></a> version of the attribute management functions.
|
||||
The actual need for type-specific attribute handlers almost completely
|
||||
disappeared starting with Python 2.2, though there are many examples which have
|
||||
not been updated to use some of the new generic mechanism that is available.</p>
|
||||
<div class="section" id="generic-attribute-management">
|
||||
<span id="id1"></span><h3>3.3.1. Generic Attribute Management<a class="headerlink" href="#generic-attribute-management" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Most extension types only use <em>simple</em> attributes. So, what makes the
|
||||
attributes simple? There are only a couple of conditions that must be met:</p>
|
||||
<ol class="arabic simple">
|
||||
<li><p>The name of the attributes must be known when <a class="reference internal" href="../c-api/type.html#c.PyType_Ready" title="PyType_Ready"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyType_Ready()</span></code></a> is
|
||||
called.</p></li>
|
||||
<li><p>No special processing is needed to record that an attribute was looked up or
|
||||
set, nor do actions need to be taken based on the value.</p></li>
|
||||
</ol>
|
||||
<p>Note that this list does not place any restrictions on the values of the
|
||||
attributes, when the values are computed, or how relevant data is stored.</p>
|
||||
<p>When <a class="reference internal" href="../c-api/type.html#c.PyType_Ready" title="PyType_Ready"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyType_Ready()</span></code></a> is called, it uses three tables referenced by the
|
||||
type object to create <a class="reference internal" href="../glossary.html#term-descriptor"><span class="xref std std-term">descriptor</span></a>s which are placed in the dictionary of the
|
||||
type object. Each descriptor controls access to one attribute of the instance
|
||||
object. Each of the tables is optional; if all three are <em>NULL</em>, instances of
|
||||
the type will only have attributes that are inherited from their base type, and
|
||||
should leave the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_getattro" title="PyTypeObject.tp_getattro"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_getattro</span></code></a> and <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_setattro" title="PyTypeObject.tp_setattro"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_setattro</span></code></a> fields <em>NULL</em> as
|
||||
well, allowing the base type to handle attributes.</p>
|
||||
<p>The tables are declared as three fields of the type object:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span> <span class="n">PyMethodDef</span> <span class="o">*</span><span class="n">tp_methods</span><span class="p">;</span>
|
||||
<span class="k">struct</span> <span class="n">PyMemberDef</span> <span class="o">*</span><span class="n">tp_members</span><span class="p">;</span>
|
||||
<span class="k">struct</span> <span class="n">PyGetSetDef</span> <span class="o">*</span><span class="n">tp_getset</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_methods" title="PyTypeObject.tp_methods"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_methods</span></code></a> is not <em>NULL</em>, it must refer to an array of
|
||||
<a class="reference internal" href="../c-api/structures.html#c.PyMethodDef" title="PyMethodDef"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMethodDef</span></code></a> structures. Each entry in the table is an instance of this
|
||||
structure:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span> <span class="k">struct</span> <span class="n">PyMethodDef</span> <span class="p">{</span>
|
||||
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">ml_name</span><span class="p">;</span> <span class="cm">/* method name */</span>
|
||||
<span class="n">PyCFunction</span> <span class="n">ml_meth</span><span class="p">;</span> <span class="cm">/* implementation function */</span>
|
||||
<span class="kt">int</span> <span class="n">ml_flags</span><span class="p">;</span> <span class="cm">/* flags */</span>
|
||||
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">ml_doc</span><span class="p">;</span> <span class="cm">/* docstring */</span>
|
||||
<span class="p">}</span> <span class="n">PyMethodDef</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>One entry should be defined for each method provided by the type; no entries are
|
||||
needed for methods inherited from a base type. One additional entry is needed
|
||||
at the end; it is a sentinel that marks the end of the array. The
|
||||
<code class="xref py py-attr docutils literal notranslate"><span class="pre">ml_name</span></code> field of the sentinel must be <em>NULL</em>.</p>
|
||||
<p>The second table is used to define attributes which map directly to data stored
|
||||
in the instance. A variety of primitive C types are supported, and access may
|
||||
be read-only or read-write. The structures in the table are defined as:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span> <span class="k">struct</span> <span class="n">PyMemberDef</span> <span class="p">{</span>
|
||||
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">;</span>
|
||||
<span class="kt">int</span> <span class="n">type</span><span class="p">;</span>
|
||||
<span class="kt">int</span> <span class="n">offset</span><span class="p">;</span>
|
||||
<span class="kt">int</span> <span class="n">flags</span><span class="p">;</span>
|
||||
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">doc</span><span class="p">;</span>
|
||||
<span class="p">}</span> <span class="n">PyMemberDef</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>For each entry in the table, a <a class="reference internal" href="../glossary.html#term-descriptor"><span class="xref std std-term">descriptor</span></a> will be constructed and added to the
|
||||
type which will be able to extract a value from the instance structure. The
|
||||
<a class="reference internal" href="../library/functions.html#type" title="type"><code class="xref py py-attr docutils literal notranslate"><span class="pre">type</span></code></a> field should contain one of the type codes defined in the
|
||||
<code class="file docutils literal notranslate"><span class="pre">structmember.h</span></code> header; the value will be used to determine how to
|
||||
convert Python values to and from C values. The <code class="xref py py-attr docutils literal notranslate"><span class="pre">flags</span></code> field is used to
|
||||
store flags which control how the attribute can be accessed.</p>
|
||||
<p>The following flag constants are defined in <code class="file docutils literal notranslate"><span class="pre">structmember.h</span></code>; they may be
|
||||
combined using bitwise-OR.</p>
|
||||
<table class="docutils align-center">
|
||||
<colgroup>
|
||||
<col style="width: 37%" />
|
||||
<col style="width: 63%" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="row-odd"><th class="head"><p>Constant</p></th>
|
||||
<th class="head"><p>Meaning</p></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="row-even"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">READONLY</span></code></p></td>
|
||||
<td><p>Never writable.</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">READ_RESTRICTED</span></code></p></td>
|
||||
<td><p>Not readable in restricted mode.</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">WRITE_RESTRICTED</span></code></p></td>
|
||||
<td><p>Not writable in restricted mode.</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p><code class="xref py py-const docutils literal notranslate"><span class="pre">RESTRICTED</span></code></p></td>
|
||||
<td><p>Not readable or writable in restricted mode.</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p id="index-4">An interesting advantage of using the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_members" title="PyTypeObject.tp_members"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_members</span></code></a> table to build
|
||||
descriptors that are used at runtime is that any attribute defined this way can
|
||||
have an associated doc string simply by providing the text in the table. An
|
||||
application can use the introspection API to retrieve the descriptor from the
|
||||
class object, and get the doc string using its <code class="xref py py-attr docutils literal notranslate"><span class="pre">__doc__</span></code> attribute.</p>
|
||||
<p>As with the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_methods" title="PyTypeObject.tp_methods"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_methods</span></code></a> table, a sentinel entry with a <code class="xref py py-attr docutils literal notranslate"><span class="pre">name</span></code> value
|
||||
of <em>NULL</em> is required.</p>
|
||||
</div>
|
||||
<div class="section" id="type-specific-attribute-management">
|
||||
<h3>3.3.2. Type-specific Attribute Management<a class="headerlink" href="#type-specific-attribute-management" title="Permalink to this headline">¶</a></h3>
|
||||
<p>For simplicity, only the <code class="xref c c-type docutils literal notranslate"><span class="pre">char*</span></code> version will be demonstrated here; the
|
||||
type of the name parameter is the only difference between the <code class="xref c c-type docutils literal notranslate"><span class="pre">char*</span></code>
|
||||
and <a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject*</span></code></a> flavors of the interface. This example effectively does
|
||||
the same thing as the generic example above, but does not use the generic
|
||||
support added in Python 2.2. It explains how the handler functions are
|
||||
called, so that if you do need to extend their functionality, you’ll understand
|
||||
what needs to be done.</p>
|
||||
<p>The <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_getattr" title="PyTypeObject.tp_getattr"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_getattr</span></code></a> handler is called when the object requires an attribute
|
||||
look-up. It is called in the same situations where the <a class="reference internal" href="../reference/datamodel.html#object.__getattr__" title="object.__getattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__getattr__()</span></code></a>
|
||||
method of a class would be called.</p>
|
||||
<p>Here is an example:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">PyObject</span> <span class="o">*</span>
|
||||
<span class="nf">newdatatype_getattr</span><span class="p">(</span><span class="n">newdatatypeobject</span> <span class="o">*</span><span class="n">obj</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">strcmp</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="s">"data"</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="k">return</span> <span class="n">PyLong_FromLong</span><span class="p">(</span><span class="n">obj</span><span class="o">-></span><span class="n">data</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="n">PyErr_Format</span><span class="p">(</span><span class="n">PyExc_AttributeError</span><span class="p">,</span>
|
||||
<span class="s">"'%.50s' object has no attribute '%.400s'"</span><span class="p">,</span>
|
||||
<span class="n">tp</span><span class="o">-></span><span class="n">tp_name</span><span class="p">,</span> <span class="n">name</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_setattr" title="PyTypeObject.tp_setattr"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_setattr</span></code></a> handler is called when the <a class="reference internal" href="../reference/datamodel.html#object.__setattr__" title="object.__setattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__setattr__()</span></code></a> or
|
||||
<a class="reference internal" href="../reference/datamodel.html#object.__delattr__" title="object.__delattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__delattr__()</span></code></a> method of a class instance would be called. When an
|
||||
attribute should be deleted, the third parameter will be <em>NULL</em>. Here is an
|
||||
example that simply raises an exception; if this were really all you wanted, the
|
||||
<a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_setattr" title="PyTypeObject.tp_setattr"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_setattr</span></code></a> handler should be set to <em>NULL</em>.</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="kt">int</span>
|
||||
<span class="nf">newdatatype_setattr</span><span class="p">(</span><span class="n">newdatatypeobject</span> <span class="o">*</span><span class="n">obj</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">,</span> <span class="n">PyObject</span> <span class="o">*</span><span class="n">v</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="n">PyErr_Format</span><span class="p">(</span><span class="n">PyExc_RuntimeError</span><span class="p">,</span> <span class="s">"Read-only attribute: %s"</span><span class="p">,</span> <span class="n">name</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="object-comparison">
|
||||
<h2>3.4. Object Comparison<a class="headerlink" href="#object-comparison" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">richcmpfunc</span> <span class="n">tp_richcompare</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_richcompare" title="PyTypeObject.tp_richcompare"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_richcompare</span></code></a> handler is called when comparisons are needed. It is
|
||||
analogous to the <a class="reference internal" href="../reference/datamodel.html#richcmpfuncs"><span class="std std-ref">rich comparison methods</span></a>, like
|
||||
<a class="reference internal" href="../reference/datamodel.html#object.__lt__" title="object.__lt__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__lt__()</span></code></a>, and also called by <a class="reference internal" href="../c-api/object.html#c.PyObject_RichCompare" title="PyObject_RichCompare"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_RichCompare()</span></code></a> and
|
||||
<a class="reference internal" href="../c-api/object.html#c.PyObject_RichCompareBool" title="PyObject_RichCompareBool"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_RichCompareBool()</span></code></a>.</p>
|
||||
<p>This function is called with two Python objects and the operator as arguments,
|
||||
where the operator is one of <code class="docutils literal notranslate"><span class="pre">Py_EQ</span></code>, <code class="docutils literal notranslate"><span class="pre">Py_NE</span></code>, <code class="docutils literal notranslate"><span class="pre">Py_LE</span></code>, <code class="docutils literal notranslate"><span class="pre">Py_GT</span></code>,
|
||||
<code class="docutils literal notranslate"><span class="pre">Py_LT</span></code> or <code class="docutils literal notranslate"><span class="pre">Py_GT</span></code>. It should compare the two objects with respect to the
|
||||
specified operator and return <code class="docutils literal notranslate"><span class="pre">Py_True</span></code> or <code class="docutils literal notranslate"><span class="pre">Py_False</span></code> if the comparison is
|
||||
successful, <code class="docutils literal notranslate"><span class="pre">Py_NotImplemented</span></code> to indicate that comparison is not
|
||||
implemented and the other object’s comparison method should be tried, or <em>NULL</em>
|
||||
if an exception was set.</p>
|
||||
<p>Here is a sample implementation, for a datatype that is considered equal if the
|
||||
size of an internal pointer is equal:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">PyObject</span> <span class="o">*</span>
|
||||
<span class="nf">newdatatype_richcmp</span><span class="p">(</span><span class="n">PyObject</span> <span class="o">*</span><span class="n">obj1</span><span class="p">,</span> <span class="n">PyObject</span> <span class="o">*</span><span class="n">obj2</span><span class="p">,</span> <span class="kt">int</span> <span class="n">op</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">result</span><span class="p">;</span>
|
||||
<span class="kt">int</span> <span class="n">c</span><span class="p">,</span> <span class="n">size1</span><span class="p">,</span> <span class="n">size2</span><span class="p">;</span>
|
||||
|
||||
<span class="cm">/* code to make sure that both arguments are of type</span>
|
||||
<span class="cm"> newdatatype omitted */</span>
|
||||
|
||||
<span class="n">size1</span> <span class="o">=</span> <span class="n">obj1</span><span class="o">-></span><span class="n">obj_UnderlyingDatatypePtr</span><span class="o">-></span><span class="n">size</span><span class="p">;</span>
|
||||
<span class="n">size2</span> <span class="o">=</span> <span class="n">obj2</span><span class="o">-></span><span class="n">obj_UnderlyingDatatypePtr</span><span class="o">-></span><span class="n">size</span><span class="p">;</span>
|
||||
|
||||
<span class="k">switch</span> <span class="p">(</span><span class="n">op</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="k">case</span> <span class="nl">Py_LT</span><span class="p">:</span> <span class="n">c</span> <span class="o">=</span> <span class="n">size1</span> <span class="o"><</span> <span class="n">size2</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
|
||||
<span class="k">case</span> <span class="nl">Py_LE</span><span class="p">:</span> <span class="n">c</span> <span class="o">=</span> <span class="n">size1</span> <span class="o"><=</span> <span class="n">size2</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
|
||||
<span class="k">case</span> <span class="nl">Py_EQ</span><span class="p">:</span> <span class="n">c</span> <span class="o">=</span> <span class="n">size1</span> <span class="o">==</span> <span class="n">size2</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
|
||||
<span class="k">case</span> <span class="nl">Py_NE</span><span class="p">:</span> <span class="n">c</span> <span class="o">=</span> <span class="n">size1</span> <span class="o">!=</span> <span class="n">size2</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
|
||||
<span class="k">case</span> <span class="nl">Py_GT</span><span class="p">:</span> <span class="n">c</span> <span class="o">=</span> <span class="n">size1</span> <span class="o">></span> <span class="n">size2</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
|
||||
<span class="k">case</span> <span class="nl">Py_GE</span><span class="p">:</span> <span class="n">c</span> <span class="o">=</span> <span class="n">size1</span> <span class="o">>=</span> <span class="n">size2</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="n">c</span> <span class="o">?</span> <span class="nl">Py_True</span> <span class="p">:</span> <span class="n">Py_False</span><span class="p">;</span>
|
||||
<span class="n">Py_INCREF</span><span class="p">(</span><span class="n">result</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="abstract-protocol-support">
|
||||
<h2>3.5. Abstract Protocol Support<a class="headerlink" href="#abstract-protocol-support" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Python supports a variety of <em>abstract</em> ‘protocols;’ the specific interfaces
|
||||
provided to use these interfaces are documented in <a class="reference internal" href="../c-api/abstract.html#abstract"><span class="std std-ref">Abstract Objects Layer</span></a>.</p>
|
||||
<p>A number of these abstract interfaces were defined early in the development of
|
||||
the Python implementation. In particular, the number, mapping, and sequence
|
||||
protocols have been part of Python since the beginning. Other protocols have
|
||||
been added over time. For protocols which depend on several handler routines
|
||||
from the type implementation, the older protocols have been defined as optional
|
||||
blocks of handlers referenced by the type object. For newer protocols there are
|
||||
additional slots in the main type object, with a flag bit being set to indicate
|
||||
that the slots are present and should be checked by the interpreter. (The flag
|
||||
bit does not indicate that the slot values are non-<em>NULL</em>. The flag may be set
|
||||
to indicate the presence of a slot, but a slot may still be unfilled.)</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyNumberMethods</span> <span class="o">*</span><span class="n">tp_as_number</span><span class="p">;</span>
|
||||
<span class="n">PySequenceMethods</span> <span class="o">*</span><span class="n">tp_as_sequence</span><span class="p">;</span>
|
||||
<span class="n">PyMappingMethods</span> <span class="o">*</span><span class="n">tp_as_mapping</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you wish your object to be able to act like a number, a sequence, or a
|
||||
mapping object, then you place the address of a structure that implements the C
|
||||
type <a class="reference internal" href="../c-api/typeobj.html#c.PyNumberMethods" title="PyNumberMethods"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyNumberMethods</span></code></a>, <a class="reference internal" href="../c-api/typeobj.html#c.PySequenceMethods" title="PySequenceMethods"><code class="xref c c-type docutils literal notranslate"><span class="pre">PySequenceMethods</span></code></a>, or
|
||||
<a class="reference internal" href="../c-api/typeobj.html#c.PyMappingMethods" title="PyMappingMethods"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyMappingMethods</span></code></a>, respectively. It is up to you to fill in this
|
||||
structure with appropriate values. You can find examples of the use of each of
|
||||
these in the <code class="file docutils literal notranslate"><span class="pre">Objects</span></code> directory of the Python source distribution.</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">hashfunc</span> <span class="n">tp_hash</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This function, if you choose to provide it, should return a hash number for an
|
||||
instance of your data type. Here is a simple example:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">Py_hash_t</span>
|
||||
<span class="nf">newdatatype_hash</span><span class="p">(</span><span class="n">newdatatypeobject</span> <span class="o">*</span><span class="n">obj</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="n">Py_hash_t</span> <span class="n">result</span><span class="p">;</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="n">obj</span><span class="o">-></span><span class="n">some_size</span> <span class="o">+</span> <span class="mi">32767</span> <span class="o">*</span> <span class="n">obj</span><span class="o">-></span><span class="n">some_number</span><span class="p">;</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">result</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span><span class="p">;</span>
|
||||
<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_hash_t</span></code> is a signed integer type with a platform-varying width.
|
||||
Returning <code class="docutils literal notranslate"><span class="pre">-1</span></code> from <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_hash" title="PyTypeObject.tp_hash"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_hash</span></code></a> indicates an error,
|
||||
which is why you should be careful to avoid returning it when hash computation
|
||||
is successful, as seen above.</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">ternaryfunc</span> <span class="n">tp_call</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This function is called when an instance of your data type is “called”, for
|
||||
example, if <code class="docutils literal notranslate"><span class="pre">obj1</span></code> is an instance of your data type and the Python script
|
||||
contains <code class="docutils literal notranslate"><span class="pre">obj1('hello')</span></code>, the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_call" title="PyTypeObject.tp_call"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_call</span></code></a> handler is invoked.</p>
|
||||
<p>This function takes three arguments:</p>
|
||||
<ol class="arabic simple">
|
||||
<li><p><em>self</em> is the instance of the data type which is the subject of the call.
|
||||
If the call is <code class="docutils literal notranslate"><span class="pre">obj1('hello')</span></code>, then <em>self</em> is <code class="docutils literal notranslate"><span class="pre">obj1</span></code>.</p></li>
|
||||
<li><p><em>args</em> is a tuple containing the arguments to the call. You can use
|
||||
<a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a> to extract the arguments.</p></li>
|
||||
<li><p><em>kwds</em> is a dictionary of keyword arguments that were passed. If this is
|
||||
non-<em>NULL</em> and you support keyword arguments, use
|
||||
<a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTupleAndKeywords" title="PyArg_ParseTupleAndKeywords"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTupleAndKeywords()</span></code></a> to extract the arguments. If you
|
||||
do not want to support keyword arguments and this is non-<em>NULL</em>, raise a
|
||||
<a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> with a message saying that keyword arguments are not supported.</p></li>
|
||||
</ol>
|
||||
<p>Here is a toy <code class="docutils literal notranslate"><span class="pre">tp_call</span></code> implementation:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">PyObject</span> <span class="o">*</span>
|
||||
<span class="nf">newdatatype_call</span><span class="p">(</span><span class="n">newdatatypeobject</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">PyObject</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">PyObject</span> <span class="o">*</span><span class="n">kwds</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">result</span><span class="p">;</span>
|
||||
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">arg1</span><span class="p">;</span>
|
||||
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">arg2</span><span class="p">;</span>
|
||||
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">arg3</span><span class="p">;</span>
|
||||
|
||||
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">PyArg_ParseTuple</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="s">"sss:call"</span><span class="p">,</span> <span class="o">&</span><span class="n">arg1</span><span class="p">,</span> <span class="o">&</span><span class="n">arg2</span><span class="p">,</span> <span class="o">&</span><span class="n">arg3</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="n">PyUnicode_FromFormat</span><span class="p">(</span>
|
||||
<span class="s">"Returning -- value: [%d] arg1: [%s] arg2: [%s] arg3: [%s]</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
|
||||
<span class="n">obj</span><span class="o">-></span><span class="n">obj_UnderlyingDatatypePtr</span><span class="o">-></span><span class="n">size</span><span class="p">,</span>
|
||||
<span class="n">arg1</span><span class="p">,</span> <span class="n">arg2</span><span class="p">,</span> <span class="n">arg3</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/* Iterators */</span>
|
||||
<span class="n">getiterfunc</span> <span class="n">tp_iter</span><span class="p">;</span>
|
||||
<span class="n">iternextfunc</span> <span class="n">tp_iternext</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>These functions provide support for the iterator protocol. Both handlers
|
||||
take exactly one parameter, the instance for which they are being called,
|
||||
and return a new reference. In the case of an error, they should set an
|
||||
exception and return <em>NULL</em>. <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iter" title="PyTypeObject.tp_iter"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iter</span></code></a> corresponds
|
||||
to the Python <a class="reference internal" href="../reference/datamodel.html#object.__iter__" title="object.__iter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__iter__()</span></code></a> method, while <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iternext" title="PyTypeObject.tp_iternext"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iternext</span></code></a>
|
||||
corresponds to the Python <a class="reference internal" href="../library/stdtypes.html#iterator.__next__" title="iterator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> method.</p>
|
||||
<p>Any <a class="reference internal" href="../glossary.html#term-iterable"><span class="xref std std-term">iterable</span></a> object must implement the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iter" title="PyTypeObject.tp_iter"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iter</span></code></a>
|
||||
handler, which must return an <a class="reference internal" href="../glossary.html#term-iterator"><span class="xref std std-term">iterator</span></a> object. Here the same guidelines
|
||||
apply as for Python classes:</p>
|
||||
<ul class="simple">
|
||||
<li><p>For collections (such as lists and tuples) which can support multiple
|
||||
independent iterators, a new iterator should be created and returned by
|
||||
each call to <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iter" title="PyTypeObject.tp_iter"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iter</span></code></a>.</p></li>
|
||||
<li><p>Objects which can only be iterated over once (usually due to side effects of
|
||||
iteration, such as file objects) can implement <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iter" title="PyTypeObject.tp_iter"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iter</span></code></a>
|
||||
by returning a new reference to themselves – and should also therefore
|
||||
implement the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iternext" title="PyTypeObject.tp_iternext"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iternext</span></code></a> handler.</p></li>
|
||||
</ul>
|
||||
<p>Any <a class="reference internal" href="../glossary.html#term-iterator"><span class="xref std std-term">iterator</span></a> object should implement both <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iter" title="PyTypeObject.tp_iter"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iter</span></code></a>
|
||||
and <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iternext" title="PyTypeObject.tp_iternext"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iternext</span></code></a>. An iterator’s
|
||||
<a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iter" title="PyTypeObject.tp_iter"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iter</span></code></a> handler should return a new reference
|
||||
to the iterator. Its <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iternext" title="PyTypeObject.tp_iternext"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iternext</span></code></a> handler should
|
||||
return a new reference to the next object in the iteration, if there is one.
|
||||
If the iteration has reached the end, <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iternext" title="PyTypeObject.tp_iternext"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iternext</span></code></a>
|
||||
may return <em>NULL</em> without setting an exception, or it may set
|
||||
<a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> <em>in addition</em> to returning <em>NULL</em>; avoiding
|
||||
the exception can yield slightly better performance. If an actual error
|
||||
occurs, <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_iternext" title="PyTypeObject.tp_iternext"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_iternext</span></code></a> should always set an exception
|
||||
and return <em>NULL</em>.</p>
|
||||
</div>
|
||||
<div class="section" id="weak-reference-support">
|
||||
<span id="weakref-support"></span><h2>3.6. Weak Reference Support<a class="headerlink" href="#weak-reference-support" title="Permalink to this headline">¶</a></h2>
|
||||
<p>One of the goals of Python’s weak reference implementation is to allow any type
|
||||
to participate in the weak reference mechanism without incurring the overhead on
|
||||
performance-critical objects (such as numbers).</p>
|
||||
<div class="admonition seealso">
|
||||
<p class="admonition-title">See also</p>
|
||||
<p>Documentation for the <a class="reference internal" href="../library/weakref.html#module-weakref" title="weakref: Support for weak references and weak dictionaries."><code class="xref py py-mod docutils literal notranslate"><span class="pre">weakref</span></code></a> module.</p>
|
||||
</div>
|
||||
<p>For an object to be weakly referencable, the extension type must do two things:</p>
|
||||
<ol class="arabic simple">
|
||||
<li><p>Include a <a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject*</span></code></a> field in the C object structure dedicated to
|
||||
the weak reference mechanism. The object’s constructor should leave it
|
||||
<em>NULL</em> (which is automatic when using the default
|
||||
<a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_alloc" title="PyTypeObject.tp_alloc"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_alloc</span></code></a>).</p></li>
|
||||
<li><p>Set the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset" title="PyTypeObject.tp_weaklistoffset"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_weaklistoffset</span></code></a> type member
|
||||
to the offset of the aforementioned field in the C object structure,
|
||||
so that the interpreter knows how to access and modify that field.</p></li>
|
||||
</ol>
|
||||
<p>Concretely, here is how a trivial object structure would be augmented
|
||||
with the required field:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span> <span class="k">struct</span> <span class="p">{</span>
|
||||
<span class="n">PyObject_HEAD</span>
|
||||
<span class="n">PyObject</span> <span class="o">*</span><span class="n">weakreflist</span><span class="p">;</span> <span class="cm">/* List of weak references */</span>
|
||||
<span class="p">}</span> <span class="n">TrivialObject</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>And the corresponding member in the statically-declared type object:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">PyTypeObject</span> <span class="n">TrivialType</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="n">PyVarObject_HEAD_INIT</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||||
<span class="cm">/* ... other members omitted for brevity ... */</span>
|
||||
<span class="p">.</span><span class="n">tp_weaklistoffset</span> <span class="o">=</span> <span class="n">offsetof</span><span class="p">(</span><span class="n">TrivialObject</span><span class="p">,</span> <span class="n">weakreflist</span><span class="p">),</span>
|
||||
<span class="p">};</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The only further addition is that <code class="docutils literal notranslate"><span class="pre">tp_dealloc</span></code> needs to clear any weak
|
||||
references (by calling <code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_ClearWeakRefs()</span></code>) if the field is
|
||||
non-<em>NULL</em>:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="kt">void</span>
|
||||
<span class="nf">Trivial_dealloc</span><span class="p">(</span><span class="n">TrivialObject</span> <span class="o">*</span><span class="n">self</span><span class="p">)</span>
|
||||
<span class="p">{</span>
|
||||
<span class="cm">/* Clear weakrefs first before calling any destructors */</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="o">-></span><span class="n">weakreflist</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span>
|
||||
<span class="n">PyObject_ClearWeakRefs</span><span class="p">((</span><span class="n">PyObject</span> <span class="o">*</span><span class="p">)</span> <span class="n">self</span><span class="p">);</span>
|
||||
<span class="cm">/* ... remainder of destruction code omitted for brevity ... */</span>
|
||||
<span class="n">Py_TYPE</span><span class="p">(</span><span class="n">self</span><span class="p">)</span><span class="o">-></span><span class="n">tp_free</span><span class="p">((</span><span class="n">PyObject</span> <span class="o">*</span><span class="p">)</span> <span class="n">self</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="more-suggestions">
|
||||
<h2>3.7. More Suggestions<a class="headerlink" href="#more-suggestions" title="Permalink to this headline">¶</a></h2>
|
||||
<p>In order to learn how to implement any specific method for your new data type,
|
||||
get the <a class="reference internal" href="../glossary.html#term-cpython"><span class="xref std std-term">CPython</span></a> source code. Go to the <code class="file docutils literal notranslate"><span class="pre">Objects</span></code> directory,
|
||||
then search the C source files for <code class="docutils literal notranslate"><span class="pre">tp_</span></code> plus the function you want
|
||||
(for example, <code class="docutils literal notranslate"><span class="pre">tp_richcompare</span></code>). You will find examples of the function
|
||||
you want to implement.</p>
|
||||
<p>When you need to verify that an object is a concrete instance of the type you
|
||||
are implementing, use the <a class="reference internal" href="../c-api/object.html#c.PyObject_TypeCheck" title="PyObject_TypeCheck"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_TypeCheck()</span></code></a> function. A sample of
|
||||
its use might be something like the following:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">PyObject_TypeCheck</span><span class="p">(</span><span class="n">some_object</span><span class="p">,</span> <span class="o">&</span><span class="n">MyType</span><span class="p">))</span> <span class="p">{</span>
|
||||
<span class="n">PyErr_SetString</span><span class="p">(</span><span class="n">PyExc_TypeError</span><span class="p">,</span> <span class="s">"arg #1 not a mything"</span><span class="p">);</span>
|
||||
<span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="admonition seealso">
|
||||
<p class="admonition-title">See also</p>
|
||||
<dl class="simple">
|
||||
<dt>Download CPython source releases.</dt><dd><p><a class="reference external" href="https://www.python.org/downloads/source/">https://www.python.org/downloads/source/</a></p>
|
||||
</dd>
|
||||
<dt>The CPython project on GitHub, where the CPython source code is developed.</dt><dd><p><a class="reference external" href="https://github.com/python/cpython">https://github.com/python/cpython</a></p>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">3. Defining Extension Types: Assorted Topics</a><ul>
|
||||
<li><a class="reference internal" href="#finalization-and-de-allocation">3.1. Finalization and De-allocation</a></li>
|
||||
<li><a class="reference internal" href="#object-presentation">3.2. Object Presentation</a></li>
|
||||
<li><a class="reference internal" href="#attribute-management">3.3. Attribute Management</a><ul>
|
||||
<li><a class="reference internal" href="#generic-attribute-management">3.3.1. Generic Attribute Management</a></li>
|
||||
<li><a class="reference internal" href="#type-specific-attribute-management">3.3.2. Type-specific Attribute Management</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#object-comparison">3.4. Object Comparison</a></li>
|
||||
<li><a class="reference internal" href="#abstract-protocol-support">3.5. Abstract Protocol Support</a></li>
|
||||
<li><a class="reference internal" href="#weak-reference-support">3.6. Weak Reference Support</a></li>
|
||||
<li><a class="reference internal" href="#more-suggestions">3.7. More Suggestions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="newtypes_tutorial.html"
|
||||
title="previous chapter">2. Defining Extension Types: Tutorial</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="building.html"
|
||||
title="next chapter">4. Building C and C++ Extensions</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.7/Doc/extending/newtypes.rst"
|
||||
rel="nofollow">Show Source
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="building.html" title="4. Building C and C++ Extensions"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="newtypes_tutorial.html" title="2. Defining Extension Types: Tutorial"
|
||||
>previous</a> |</li>
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||||
<li>
|
||||
<span class="language_switcher_placeholder">en</span>
|
||||
<span class="version_switcher_placeholder">3.7.4</span>
|
||||
<a href="../index.html">Documentation </a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Extending and Embedding the Python Interpreter</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" style="display: none" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="Quick search" type="text" name="q" />
|
||||
<input type="submit" value="Go" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
|
||||
<br />
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
Last updated on Jul 13, 2019.
|
||||
<a href="../bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.0.1.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
1637
python-3.7.4-docs-html/extending/newtypes_tutorial.html
Normal file
1637
python-3.7.4-docs-html/extending/newtypes_tutorial.html
Normal file
File diff suppressed because it is too large
Load Diff
289
python-3.7.4-docs-html/extending/windows.html
Normal file
289
python-3.7.4-docs-html/extending/windows.html
Normal file
@@ -0,0 +1,289 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>5. Building C and C++ Extensions on Windows — Python 3.7.4 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="Search within Python 3.7.4 documentation"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="About these documents" href="../about.html" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||||
<link rel="next" title="1. Embedding Python in Another Application" href="embedding.html" />
|
||||
<link rel="prev" title="4. Building C and C++ Extensions" href="building.html" />
|
||||
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/extending/windows.html" />
|
||||
|
||||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||||
<script type="text/javascript" src="../_static/switchers.js"></script>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head><body>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
accesskey="I">index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="embedding.html" title="1. Embedding Python in Another Application"
|
||||
accesskey="N">next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="building.html" title="4. Building C and C++ Extensions"
|
||||
accesskey="P">previous</a> |</li>
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||||
<li>
|
||||
<span class="language_switcher_placeholder">en</span>
|
||||
<span class="version_switcher_placeholder">3.7.4</span>
|
||||
<a href="../index.html">Documentation </a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Extending and Embedding the Python Interpreter</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" style="display: none" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="Quick search" type="text" name="q" />
|
||||
<input type="submit" value="Go" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="building-c-and-c-extensions-on-windows">
|
||||
<span id="building-on-windows"></span><h1>5. Building C and C++ Extensions on Windows<a class="headerlink" href="#building-c-and-c-extensions-on-windows" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This chapter briefly explains how to create a Windows extension module for
|
||||
Python using Microsoft Visual C++, and follows with more detailed background
|
||||
information on how it works. The explanatory material is useful for both the
|
||||
Windows programmer learning to build Python extensions and the Unix programmer
|
||||
interested in producing software which can be successfully built on both Unix
|
||||
and Windows.</p>
|
||||
<p>Module authors are encouraged to use the distutils approach for building
|
||||
extension modules, instead of the one described in this section. You will still
|
||||
need the C compiler that was used to build Python; typically Microsoft Visual
|
||||
C++.</p>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Note</p>
|
||||
<p>This chapter mentions a number of filenames that include an encoded Python
|
||||
version number. These filenames are represented with the version number shown
|
||||
as <code class="docutils literal notranslate"><span class="pre">XY</span></code>; in practice, <code class="docutils literal notranslate"><span class="pre">'X'</span></code> will be the major version number and <code class="docutils literal notranslate"><span class="pre">'Y'</span></code>
|
||||
will be the minor version number of the Python release you’re working with. For
|
||||
example, if you are using Python 2.2.1, <code class="docutils literal notranslate"><span class="pre">XY</span></code> will actually be <code class="docutils literal notranslate"><span class="pre">22</span></code>.</p>
|
||||
</div>
|
||||
<div class="section" id="a-cookbook-approach">
|
||||
<span id="win-cookbook"></span><h2>5.1. A Cookbook Approach<a class="headerlink" href="#a-cookbook-approach" title="Permalink to this headline">¶</a></h2>
|
||||
<p>There are two approaches to building extension modules on Windows, just as there
|
||||
are on Unix: use the <a class="reference internal" href="../library/distutils.html#module-distutils" title="distutils: Support for building and installing Python modules into an existing Python installation."><code class="xref py py-mod docutils literal notranslate"><span class="pre">distutils</span></code></a> package to control the build process, or
|
||||
do things manually. The distutils approach works well for most extensions;
|
||||
documentation on using <a class="reference internal" href="../library/distutils.html#module-distutils" title="distutils: Support for building and installing Python modules into an existing Python installation."><code class="xref py py-mod docutils literal notranslate"><span class="pre">distutils</span></code></a> to build and package extension modules
|
||||
is available in <a class="reference internal" href="../distutils/index.html#distutils-index"><span class="std std-ref">Distributing Python Modules (Legacy version)</span></a>. If you find you really need to do
|
||||
things manually, it may be instructive to study the project file for the
|
||||
<a class="reference external" href="https://github.com/python/cpython/tree/3.7/PCbuild/winsound.vcxproj">winsound</a> standard library module.</p>
|
||||
</div>
|
||||
<div class="section" id="differences-between-unix-and-windows">
|
||||
<span id="dynamic-linking"></span><h2>5.2. Differences Between Unix and Windows<a class="headerlink" href="#differences-between-unix-and-windows" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Unix and Windows use completely different paradigms for run-time loading of
|
||||
code. Before you try to build a module that can be dynamically loaded, be aware
|
||||
of how your system works.</p>
|
||||
<p>In Unix, a shared object (<code class="file docutils literal notranslate"><span class="pre">.so</span></code>) file contains code to be used by the
|
||||
program, and also the names of functions and data that it expects to find in the
|
||||
program. When the file is joined to the program, all references to those
|
||||
functions and data in the file’s code are changed to point to the actual
|
||||
locations in the program where the functions and data are placed in memory.
|
||||
This is basically a link operation.</p>
|
||||
<p>In Windows, a dynamic-link library (<code class="file docutils literal notranslate"><span class="pre">.dll</span></code>) file has no dangling
|
||||
references. Instead, an access to functions or data goes through a lookup
|
||||
table. So the DLL code does not have to be fixed up at runtime to refer to the
|
||||
program’s memory; instead, the code already uses the DLL’s lookup table, and the
|
||||
lookup table is modified at runtime to point to the functions and data.</p>
|
||||
<p>In Unix, there is only one type of library file (<code class="file docutils literal notranslate"><span class="pre">.a</span></code>) which contains code
|
||||
from several object files (<code class="file docutils literal notranslate"><span class="pre">.o</span></code>). During the link step to create a shared
|
||||
object file (<code class="file docutils literal notranslate"><span class="pre">.so</span></code>), the linker may find that it doesn’t know where an
|
||||
identifier is defined. The linker will look for it in the object files in the
|
||||
libraries; if it finds it, it will include all the code from that object file.</p>
|
||||
<p>In Windows, there are two types of library, a static library and an import
|
||||
library (both called <code class="file docutils literal notranslate"><span class="pre">.lib</span></code>). A static library is like a Unix <code class="file docutils literal notranslate"><span class="pre">.a</span></code>
|
||||
file; it contains code to be included as necessary. An import library is
|
||||
basically used only to reassure the linker that a certain identifier is legal,
|
||||
and will be present in the program when the DLL is loaded. So the linker uses
|
||||
the information from the import library to build the lookup table for using
|
||||
identifiers that are not included in the DLL. When an application or a DLL is
|
||||
linked, an import library may be generated, which will need to be used for all
|
||||
future DLLs that depend on the symbols in the application or DLL.</p>
|
||||
<p>Suppose you are building two dynamic-load modules, B and C, which should share
|
||||
another block of code A. On Unix, you would <em>not</em> pass <code class="file docutils literal notranslate"><span class="pre">A.a</span></code> to the
|
||||
linker for <code class="file docutils literal notranslate"><span class="pre">B.so</span></code> and <code class="file docutils literal notranslate"><span class="pre">C.so</span></code>; that would cause it to be included
|
||||
twice, so that B and C would each have their own copy. In Windows, building
|
||||
<code class="file docutils literal notranslate"><span class="pre">A.dll</span></code> will also build <code class="file docutils literal notranslate"><span class="pre">A.lib</span></code>. You <em>do</em> pass <code class="file docutils literal notranslate"><span class="pre">A.lib</span></code> to the
|
||||
linker for B and C. <code class="file docutils literal notranslate"><span class="pre">A.lib</span></code> does not contain code; it just contains
|
||||
information which will be used at runtime to access A’s code.</p>
|
||||
<p>In Windows, using an import library is sort of like using <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">spam</span></code>; it
|
||||
gives you access to spam’s names, but does not create a separate copy. On Unix,
|
||||
linking with a library is more like <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">spam</span> <span class="pre">import</span> <span class="pre">*</span></code>; it does create a
|
||||
separate copy.</p>
|
||||
</div>
|
||||
<div class="section" id="using-dlls-in-practice">
|
||||
<span id="win-dlls"></span><h2>5.3. Using DLLs in Practice<a class="headerlink" href="#using-dlls-in-practice" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Windows Python is built in Microsoft Visual C++; using other compilers may or
|
||||
may not work (though Borland seems to). The rest of this section is MSVC++
|
||||
specific.</p>
|
||||
<p>When creating DLLs in Windows, you must pass <code class="file docutils literal notranslate"><span class="pre">pythonXY.lib</span></code> to the linker.
|
||||
To build two DLLs, spam and ni (which uses C functions found in spam), you could
|
||||
use these commands:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">cl</span> <span class="o">/</span><span class="n">LD</span> <span class="o">/</span><span class="n">I</span><span class="o">/</span><span class="n">python</span><span class="o">/</span><span class="n">include</span> <span class="n">spam</span><span class="p">.</span><span class="n">c</span> <span class="p">..</span><span class="o">/</span><span class="n">libs</span><span class="o">/</span><span class="n">pythonXY</span><span class="p">.</span><span class="n">lib</span>
|
||||
<span class="n">cl</span> <span class="o">/</span><span class="n">LD</span> <span class="o">/</span><span class="n">I</span><span class="o">/</span><span class="n">python</span><span class="o">/</span><span class="n">include</span> <span class="n">ni</span><span class="p">.</span><span class="n">c</span> <span class="n">spam</span><span class="p">.</span><span class="n">lib</span> <span class="p">..</span><span class="o">/</span><span class="n">libs</span><span class="o">/</span><span class="n">pythonXY</span><span class="p">.</span><span class="n">lib</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The first command created three files: <code class="file docutils literal notranslate"><span class="pre">spam.obj</span></code>, <code class="file docutils literal notranslate"><span class="pre">spam.dll</span></code> and
|
||||
<code class="file docutils literal notranslate"><span class="pre">spam.lib</span></code>. <code class="file docutils literal notranslate"><span class="pre">Spam.dll</span></code> does not contain any Python functions (such
|
||||
as <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a>), but it does know how to find the Python code
|
||||
thanks to <code class="file docutils literal notranslate"><span class="pre">pythonXY.lib</span></code>.</p>
|
||||
<p>The second command created <code class="file docutils literal notranslate"><span class="pre">ni.dll</span></code> (and <code class="file docutils literal notranslate"><span class="pre">.obj</span></code> and <code class="file docutils literal notranslate"><span class="pre">.lib</span></code>),
|
||||
which knows how to find the necessary functions from spam, and also from the
|
||||
Python executable.</p>
|
||||
<p>Not every identifier is exported to the lookup table. If you want any other
|
||||
modules (including Python) to be able to see your identifiers, you have to say
|
||||
<code class="docutils literal notranslate"><span class="pre">_declspec(dllexport)</span></code>, as in <code class="docutils literal notranslate"><span class="pre">void</span> <span class="pre">_declspec(dllexport)</span> <span class="pre">initspam(void)</span></code> or
|
||||
<code class="docutils literal notranslate"><span class="pre">PyObject</span> <span class="pre">_declspec(dllexport)</span> <span class="pre">*NiGetSpamData(void)</span></code>.</p>
|
||||
<p>Developer Studio will throw in a lot of import libraries that you do not really
|
||||
need, adding about 100K to your executable. To get rid of them, use the Project
|
||||
Settings dialog, Link tab, to specify <em>ignore default libraries</em>. Add the
|
||||
correct <code class="file docutils literal notranslate"><span class="pre">msvcrtxx.lib</span></code> to the list of libraries.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">5. Building C and C++ Extensions on Windows</a><ul>
|
||||
<li><a class="reference internal" href="#a-cookbook-approach">5.1. A Cookbook Approach</a></li>
|
||||
<li><a class="reference internal" href="#differences-between-unix-and-windows">5.2. Differences Between Unix and Windows</a></li>
|
||||
<li><a class="reference internal" href="#using-dlls-in-practice">5.3. Using DLLs in Practice</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>Previous topic</h4>
|
||||
<p class="topless"><a href="building.html"
|
||||
title="previous chapter">4. Building C and C++ Extensions</a></p>
|
||||
<h4>Next topic</h4>
|
||||
<p class="topless"><a href="embedding.html"
|
||||
title="next chapter">1. Embedding Python in Another Application</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>This Page</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.7/Doc/extending/windows.rst"
|
||||
rel="nofollow">Show Source
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="General Index"
|
||||
>index</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python Module Index"
|
||||
>modules</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="embedding.html" title="1. Embedding Python in Another Application"
|
||||
>next</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="building.html" title="4. Building C and C++ Extensions"
|
||||
>previous</a> |</li>
|
||||
<li><img src="../_static/py.png" alt=""
|
||||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||||
<li>
|
||||
<span class="language_switcher_placeholder">en</span>
|
||||
<span class="version_switcher_placeholder">3.7.4</span>
|
||||
<a href="../index.html">Documentation </a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Extending and Embedding the Python Interpreter</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" style="display: none" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="Quick search" type="text" name="q" />
|
||||
<input type="submit" value="Go" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
|
||||
<br />
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
Last updated on Jul 13, 2019.
|
||||
<a href="../bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.0.1.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user