add files

This commit is contained in:
Caleb Fontenot
2019-07-15 09:16:41 -07:00
parent b4f7a8873b
commit 335515d331
1027 changed files with 679464 additions and 0 deletions

View 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 &#8212; 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> &#187;</li>
<li>
<span class="language_switcher_placeholder">en</span>
<span class="version_switcher_placeholder">3.7.4</span>
<a href="../index.html">Documentation </a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Extending and Embedding the Python Interpreter</a> &#187;</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_&lt;modulename&gt;</span></code>, with <code class="docutils literal notranslate"><span class="pre">&lt;modulename&gt;</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_&lt;modulename&gt;</span></code>, with <code class="docutils literal notranslate"><span class="pre">&lt;modulename&gt;</span></code> encoded using Pythons
<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">&#39;_&#39;</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">&#39;ascii&#39;</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">&#39;U_&#39;</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">&#39;punycode&#39;</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">&#39;-&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;_&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="sa">b</span><span class="s1">&#39;PyInit&#39;</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 dont
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">&#39;demo&#39;</span><span class="p">,</span>
<span class="n">sources</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;demo.c&#39;</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">&#39;PackageName&#39;</span><span class="p">,</span>
<span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;1.0&#39;</span><span class="p">,</span>
<span class="n">description</span> <span class="o">=</span> <span class="s1">&#39;This is a demo package&#39;</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">&#39;demo&#39;</span><span class="p">,</span>
<span class="n">define_macros</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">&#39;MAJOR_VERSION&#39;</span><span class="p">,</span> <span class="s1">&#39;1&#39;</span><span class="p">),</span>
<span class="p">(</span><span class="s1">&#39;MINOR_VERSION&#39;</span><span class="p">,</span> <span class="s1">&#39;0&#39;</span><span class="p">)],</span>
<span class="n">include_dirs</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;/usr/local/include&#39;</span><span class="p">],</span>
<span class="n">libraries</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;tcl83&#39;</span><span class="p">],</span>
<span class="n">library_dirs</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;/usr/local/lib&#39;</span><span class="p">],</span>
<span class="n">sources</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;demo.c&#39;</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">&#39;PackageName&#39;</span><span class="p">,</span>
<span class="n">version</span> <span class="o">=</span> <span class="s1">&#39;1.0&#39;</span><span class="p">,</span>
<span class="n">description</span> <span class="o">=</span> <span class="s1">&#39;This is a demo package&#39;</span><span class="p">,</span>
<span class="n">author</span> <span class="o">=</span> <span class="s1">&#39;Martin v. Loewis&#39;</span><span class="p">,</span>
<span class="n">author_email</span> <span class="o">=</span> <span class="s1">&#39;martin@v.loewis.de&#39;</span><span class="p">,</span>
<span class="n">url</span> <span class="o">=</span> <span class="s1">&#39;https://docs.python.org/extending/building&#39;</span><span class="p">,</span>
<span class="n">long_description</span> <span class="o">=</span> <span class="s1">&#39;&#39;&#39;</span>
<span class="s1">This is really just a demo package.</span>
<span class="s1">&#39;&#39;&#39;</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> &#187;</li>
<li>
<span class="language_switcher_placeholder">en</span>
<span class="version_switcher_placeholder">3.7.4</span>
<a href="../index.html">Documentation </a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Extending and Embedding the Python Interpreter</a> &#187;</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">
&copy; <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>

View 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 &#8212; 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> &#187;</li>
<li>
<span class="language_switcher_placeholder">en</span>
<span class="version_switcher_placeholder">3.7.4</span>
<a href="../index.html">Documentation </a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Extending and Embedding the Python Interpreter</a> &#187;</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 Pythons 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">&lt;Python.h&gt;</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">&quot;Fatal error: cannot decode argv[0]</span><span class="se">\n</span><span class="s">&quot;</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">&quot;from time import time,ctime</span><span class="se">\n</span><span class="s">&quot;</span>
<span class="s">&quot;print(&#39;Today is&#39;, ctime(time()))</span><span class="se">\n</span><span class="s">&quot;</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">&lt;</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">&lt;Python.h&gt;</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">&lt;</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">&quot;Usage: call pythonfile funcname [args]</span><span class="se">\n</span><span class="s">&quot;</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">&amp;&amp;</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">&lt;</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">&quot;Cannot convert argument</span><span class="se">\n</span><span class="s">&quot;</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">&quot;Result of call: %ld</span><span class="se">\n</span><span class="s">&quot;</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">&quot;Call failed</span><span class="se">\n</span><span class="s">&quot;</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">&quot;Cannot find function </span><span class="se">\&quot;</span><span class="s">%s</span><span class="se">\&quot;\n</span><span class="s">&quot;</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">&quot;Failed to load </span><span class="se">\&quot;</span><span class="s">%s</span><span class="se">\&quot;\n</span><span class="s">&quot;</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">&lt;</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 (lets 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">&quot;Will compute&quot;</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="s2">&quot;times&quot;</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">&amp;&amp;</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 were 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">&quot;:numargs&quot;</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">&quot;numargs&quot;</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">&quot;Return the number of arguments received by the process.&quot;</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">&quot;emb&quot;</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">&amp;</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">&quot;emb&quot;</span><span class="p">,</span> <span class="o">&amp;</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">&quot;Number of arguments&quot;</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 doesnt 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 systems documentation about dynamic linking and/or
examine Pythons <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">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sysconfig</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sysconfig</span><span class="o">.</span><span class="n">get_config_var</span><span class="p">(</span><span class="s1">&#39;LIBS&#39;</span><span class="p">)</span>
<span class="go">&#39;-lpthread -ldl -lutil&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sysconfig</span><span class="o">.</span><span class="n">get_config_var</span><span class="p">(</span><span class="s1">&#39;LINKFORSHARED&#39;</span><span class="p">)</span>
<span class="go">&#39;-Xlinker -export-dynamic&#39;</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> &#187;</li>
<li>
<span class="language_switcher_placeholder">en</span>
<span class="version_switcher_placeholder">3.7.4</span>
<a href="../index.html">Documentation </a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Extending and Embedding the Python Interpreter</a> &#187;</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">
&copy; <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>

File diff suppressed because it is too large Load Diff

View 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 &#8212; 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> &#187;</li>
<li>
<span class="language_switcher_placeholder">en</span>
<span class="version_switcher_placeholder">3.7.4</span>
<a href="../index.html">Documentation </a> &#187;
</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 Modules 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> &#187;</li>
<li>
<span class="language_switcher_placeholder">en</span>
<span class="version_switcher_placeholder">3.7.4</span>
<a href="../index.html">Documentation </a> &#187;
</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">
&copy; <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>

View 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 &#8212; 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> &#187;</li>
<li>
<span class="language_switcher_placeholder">en</span>
<span class="version_switcher_placeholder">3.7.4</span>
<a href="../index.html">Documentation </a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Extending and Embedding the Python Interpreter</a> &#187;</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 &quot;&lt;module&gt;.&lt;name&gt;&quot; */</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 thats a <em>lot</em> of methods. Dont 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, were going to go over this and give more
information about the various handlers. We wont 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. Its 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">-&gt;</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">-&gt;</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">-&gt;</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">&amp;</span><span class="n">err_type</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">err_value</span><span class="p">,</span> <span class="o">&amp;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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 objects 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">&quot;Repr-ified_newdatatype{{size:%d}}&quot;</span><span class="p">,</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">obj_UnderlyingDatatypePtr</span><span class="o">-&gt;</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 types <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">&quot;Stringified_newdatatype{{size:%d}}&quot;</span><span class="p">,</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">obj_UnderlyingDatatypePtr</span><span class="o">-&gt;</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 implementations 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, youll 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">&quot;data&quot;</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">-&gt;</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">&quot;&#39;%.50s&#39; object has no attribute &#39;%.400s&#39;&quot;</span><span class="p">,</span>
<span class="n">tp</span><span class="o">-&gt;</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">&quot;Read-only attribute: %s&quot;</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 objects 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">-&gt;</span><span class="n">obj_UnderlyingDatatypePtr</span><span class="o">-&gt;</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">-&gt;</span><span class="n">obj_UnderlyingDatatypePtr</span><span class="o">-&gt;</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">&lt;</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">&lt;=</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">&gt;</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">&gt;=</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">-&gt;</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">-&gt;</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">&quot;sss:call&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">arg1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">arg2</span><span class="p">,</span> <span class="o">&amp;</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">&quot;Returning -- value: [%d] arg1: [%s] arg2: [%s] arg3: [%s]</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">obj</span><span class="o">-&gt;</span><span class="n">obj_UnderlyingDatatypePtr</span><span class="o">-&gt;</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 iterators
<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 Pythons 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 objects 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">-&gt;</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">-&gt;</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">&amp;</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">&quot;arg #1 not a mything&quot;</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> &#187;</li>
<li>
<span class="language_switcher_placeholder">en</span>
<span class="version_switcher_placeholder">3.7.4</span>
<a href="../index.html">Documentation </a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Extending and Embedding the Python Interpreter</a> &#187;</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">
&copy; <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>

File diff suppressed because it is too large Load Diff

View 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 &#8212; 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> &#187;</li>
<li>
<span class="language_switcher_placeholder">en</span>
<span class="version_switcher_placeholder">3.7.4</span>
<a href="../index.html">Documentation </a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Extending and Embedding the Python Interpreter</a> &#187;</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 youre 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 files 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
programs memory; instead, the code already uses the DLLs 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 doesnt 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 As 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 spams 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> &#187;</li>
<li>
<span class="language_switcher_placeholder">en</span>
<span class="version_switcher_placeholder">3.7.4</span>
<a href="../index.html">Documentation </a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Extending and Embedding the Python Interpreter</a> &#187;</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">
&copy; <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>