Removed the Requirement to Install Python and NodeJS (Now Bundled with Borealis)

This commit is contained in:
2025-04-24 00:42:19 -06:00
parent 785265d3e7
commit 9c68cdea84
7786 changed files with 2386458 additions and 217 deletions

View File

@ -0,0 +1,370 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:title" content="4. Building C and C++ Extensions" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://docs.python.org/3/extending/building.html" />
<meta property="og:site_name" content="Python documentation" />
<meta property="og:description" content="A C extension for CPython is a shared library (e.g. a.so file on Linux,.pyd on Windows), which exports an initialization function. To be importable, the shared library must be available on PYTHONPA..." />
<meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
<meta property="og:image:alt" content="Python documentation" />
<meta name="description" content="A C extension for CPython is a shared library (e.g. a.so file on Linux,.pyd on Windows), which exports an initialization function. To be importable, the shared library must be available on PYTHONPA..." />
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="theme-color" content="#3776ab">
<title>4. Building C and C++ Extensions &#8212; Python 3.13.3 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
<link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=23252803" />
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />
<script src="../_static/documentation_options.js?v=5d57ca2d"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="Search within Python 3.13.3 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="canonical" href="https://docs.python.org/3/extending/building.html">
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
<script type="text/javascript" src="../_static/search-focus.js"></script>
<script type="text/javascript" src="../_static/themetoggle.js"></script>
<script type="text/javascript" src="../_static/rtd_switcher.js"></script>
<meta name="readthedocs-addons-api-version" content="1">
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<nav class="nav-content" role="navigation">
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<span class="nav-items-wrapper">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Python logo"/>
</a>
<span class="version_switcher_placeholder"></span>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
<input type="submit" value="Go"/>
</form>
</span>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label>
<div>
<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-setuptools">4.1. Building C and C++ Extensions with setuptools</a></li>
</ul>
</li>
</ul>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="newtypes.html"
title="previous chapter"><span class="section-number">3. </span>Defining Extension Types: Assorted Topics</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="windows.html"
title="next chapter"><span class="section-number">5. </span>Building C and C++ Extensions on Windows</a></p>
</div>
<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/main/Doc/extending/building.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.13.3 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="nav-item nav-item-this"><a href=""><span class="section-number">4. </span>Building C and C++ Extensions</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="building-c-and-c-extensions">
<span id="building"></span><h1><span class="section-number">4. </span>Building C and C++ Extensions<a class="headerlink" href="#building-c-and-c-extensions" title="Link to this heading"></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 setuptools, the correct filename is generated automatically.</p>
<p>The initialization function has the signature:</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.PyInit_modulename">
<a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject"><span class="n"><span class="pre">PyObject</span></span></a><span class="w"> </span><span class="p"><span class="pre">*</span></span><span class="sig-name descname"><span class="n"><span class="pre">PyInit_modulename</span></span></span><span class="sig-paren">(</span><span class="kt"><span class="pre">void</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.PyInit_modulename" title="Link to this definition"></a><br /></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="w"> </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://peps.python.org/pep-0489/"><strong>PEP 489</strong></a> for details.</p>
<section id="building-c-and-c-extensions-with-setuptools">
<span id="setuptools-index"></span><span id="install-index"></span><h2><span class="section-number">4.1. </span>Building C and C++ Extensions with setuptools<a class="headerlink" href="#building-c-and-c-extensions-with-setuptools" title="Link to this heading"></a></h2>
<p>Python 3.12 and newer no longer come with distutils. Please refer to the
<code class="docutils literal notranslate"><span class="pre">setuptools</span></code> documentation at
<a class="reference external" href="https://setuptools.readthedocs.io/en/latest/setuptools.html">https://setuptools.readthedocs.io/en/latest/setuptools.html</a>
to learn more about how build and distribute C/C++ extensions with setuptools.</p>
</section>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<div>
<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-setuptools">4.1. Building C and C++ Extensions with setuptools</a></li>
</ul>
</li>
</ul>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="newtypes.html"
title="previous chapter"><span class="section-number">3. </span>Defining Extension Types: Assorted Topics</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="windows.html"
title="next chapter"><span class="section-number">5. </span>Building C and C++ Extensions on Windows</a></p>
</div>
<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/main/Doc/extending/building.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</div>
<div id="sidebarbutton" title="Collapse sidebar">
<span>«</span>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.13.3 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="nav-item nav-item-this"><a href=""><span class="section-number">4. </span>Building C and C++ Extensions</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="footer">
&copy;
<a href="../copyright.html">
Copyright
</a>
2001-2025, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
See <a href="/license.html">History and License</a> for more information.<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
Last updated on Apr 08, 2025 (14:33 UTC).
<a href="/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>

View File

@ -0,0 +1,709 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:title" content="1. Embedding Python in Another Application" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://docs.python.org/3/extending/embedding.html" />
<meta property="og:site_name" content="Python documentation" />
<meta property="og:description" content="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 arou..." />
<meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
<meta property="og:image:alt" content="Python documentation" />
<meta name="description" content="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 arou..." />
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="theme-color" content="#3776ab">
<title>1. Embedding Python in Another Application &#8212; Python 3.13.3 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
<link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=23252803" />
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />
<script src="../_static/documentation_options.js?v=5d57ca2d"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="Search within Python 3.13.3 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="canonical" href="https://docs.python.org/3/extending/embedding.html">
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
<script type="text/javascript" src="../_static/search-focus.js"></script>
<script type="text/javascript" src="../_static/themetoggle.js"></script>
<script type="text/javascript" src="../_static/rtd_switcher.js"></script>
<meta name="readthedocs-addons-api-version" content="1">
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<nav class="nav-content" role="navigation">
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<span class="nav-items-wrapper">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Python logo"/>
</a>
<span class="version_switcher_placeholder"></span>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
<input type="submit" value="Go"/>
</form>
</span>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label>
<div>
<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>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="windows.html"
title="previous chapter"><span class="section-number">5. </span>Building C and C++ Extensions on Windows</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="../c-api/index.html"
title="next chapter">Python/C API Reference Manual</a></p>
</div>
<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/main/Doc/extending/embedding.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.13.3 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="nav-item nav-item-this"><a href=""><span class="section-number">1. </span>Embedding Python in Another Application</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="embedding-python-in-another-application">
<span id="embedding"></span><h1><span class="section-number">1. </span>Embedding Python in Another Application<a class="headerlink" href="#embedding-python-in-another-application" title="Link to this heading"></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>
<section id="very-high-level-embedding">
<span id="high-level-embedding"></span><h2><span class="section-number">1.1. </span>Very High Level Embedding<a class="headerlink" href="#very-high-level-embedding" title="Link to this heading"></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="w"> </span><span class="cpf">&lt;Python.h&gt;</span>
<span class="kt">int</span>
<span class="nf">main</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">PyStatus</span><span class="w"> </span><span class="n">status</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyConfig</span><span class="w"> </span><span class="n">config</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyConfig_InitPythonConfig</span><span class="p">(</span><span class="o">&amp;</span><span class="n">config</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* optional but recommended */</span>
<span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyConfig_SetBytesString</span><span class="p">(</span><span class="o">&amp;</span><span class="n">config</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">config</span><span class="p">.</span><span class="n">program_name</span><span class="p">,</span><span class="w"> </span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">PyStatus_Exception</span><span class="p">(</span><span class="n">status</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">goto</span><span class="w"> </span><span class="n">exception</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Py_InitializeFromConfig</span><span class="p">(</span><span class="o">&amp;</span><span class="n">config</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">PyStatus_Exception</span><span class="p">(</span><span class="n">status</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">goto</span><span class="w"> </span><span class="n">exception</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">PyConfig_Clear</span><span class="p">(</span><span class="o">&amp;</span><span class="n">config</span><span class="p">);</span>
<span class="w"> </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="w"> </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="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">Py_FinalizeEx</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">exit</span><span class="p">(</span><span class="mi">120</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="nl">exception</span><span class="p">:</span>
<span class="w"> </span><span class="n">PyConfig_Clear</span><span class="p">(</span><span class="o">&amp;</span><span class="n">config</span><span class="p">);</span>
<span class="w"> </span><span class="n">Py_ExitStatusException</span><span class="p">(</span><span class="n">status</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="docutils literal notranslate"><span class="pre">#define</span> <span class="pre">PY_SSIZE_T_CLEAN</span></code> was used to indicate that <code class="docutils literal notranslate"><span class="pre">Py_ssize_t</span></code> should be
used in some APIs instead of <code class="docutils literal notranslate"><span class="pre">int</span></code>.
It is not necessary since Python 3.13, but we keep it here for backward compatibility.
See <a class="reference internal" href="../c-api/arg.html#arg-parsing-string-and-buffers"><span class="std std-ref">Strings and buffers</span></a> for a description of this macro.</p>
</div>
<p>Setting <a class="reference internal" href="../c-api/init_config.html#c.PyConfig.program_name" title="PyConfig.program_name"><code class="xref c c-member docutils literal notranslate"><span class="pre">PyConfig.program_name</span></code></a> should be called before
<a class="reference internal" href="../c-api/init.html#c.Py_InitializeFromConfig" title="Py_InitializeFromConfig"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_InitializeFromConfig()</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>
</section>
<section id="beyond-very-high-level-embedding-an-overview">
<span id="lower-level-embedding"></span><h2><span class="section-number">1.2. </span>Beyond Very High Level Embedding: An overview<a class="headerlink" href="#beyond-very-high-level-embedding-an-overview" title="Link to this heading"></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>
</section>
<section id="pure-embedding">
<span id="id1"></span><h2><span class="section-number">1.3. </span>Pure Embedding<a class="headerlink" href="#pure-embedding" title="Link to this heading"></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="w"> </span><span class="cpf">&lt;Python.h&gt;</span>
<span class="kt">int</span>
<span class="nf">main</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">pName</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">pModule</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">pFunc</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">pArgs</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">pValue</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">argc</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </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="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">Py_Initialize</span><span class="p">();</span>
<span class="w"> </span><span class="n">pName</span><span class="w"> </span><span class="o">=</span><span class="w"> </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="w"> </span><span class="cm">/* Error checking of pName left out */</span>
<span class="w"> </span><span class="n">pModule</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyImport_Import</span><span class="p">(</span><span class="n">pName</span><span class="p">);</span>
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pName</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">pModule</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">pFunc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyObject_GetAttrString</span><span class="p">(</span><span class="n">pModule</span><span class="p">,</span><span class="w"> </span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
<span class="w"> </span><span class="cm">/* pFunc is a new reference */</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">pFunc</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">PyCallable_Check</span><span class="p">(</span><span class="n">pFunc</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">pArgs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyTuple_New</span><span class="p">(</span><span class="n">argc</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">3</span><span class="p">);</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">argc</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">3</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">pValue</span><span class="w"> </span><span class="o">=</span><span class="w"> </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="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">3</span><span class="p">]));</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">pValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pArgs</span><span class="p">);</span>
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pModule</span><span class="p">);</span>
<span class="w"> </span><span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span><span class="w"> </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="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="cm">/* pValue reference stolen here: */</span>
<span class="w"> </span><span class="n">PyTuple_SetItem</span><span class="p">(</span><span class="n">pArgs</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">pValue</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">pValue</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyObject_CallObject</span><span class="p">(</span><span class="n">pFunc</span><span class="p">,</span><span class="w"> </span><span class="n">pArgs</span><span class="p">);</span>
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pArgs</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">pValue</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </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="w"> </span><span class="n">PyLong_AsLong</span><span class="p">(</span><span class="n">pValue</span><span class="p">));</span>
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pValue</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pFunc</span><span class="p">);</span>
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pModule</span><span class="p">);</span>
<span class="w"> </span><span class="n">PyErr_Print</span><span class="p">();</span>
<span class="w"> </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="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">PyErr_Occurred</span><span class="p">())</span>
<span class="w"> </span><span class="n">PyErr_Print</span><span class="p">();</span>
<span class="w"> </span><span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span><span class="w"> </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="w"> </span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="p">(</span><span class="n">pFunc</span><span class="p">);</span>
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">pModule</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">PyErr_Print</span><span class="p">();</span>
<span class="w"> </span><span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span><span class="w"> </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="w"> </span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">Py_FinalizeEx</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">120</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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="w"> </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="nb">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<span class="w"> </span>multiply<span class="w"> </span>multiply<span class="w"> </span><span class="m">3</span><span class="w"> </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="w"> </span><span class="o">=</span><span class="w"> </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="w"> </span><span class="o">=</span><span class="w"> </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_DecodeFSDefault" title="PyUnicode_DecodeFSDefault"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyUnicode_DecodeFSDefault()</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="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyObject_GetAttrString</span><span class="p">(</span><span class="n">pModule</span><span class="p">,</span><span class="w"> </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="w"> </span><span class="p">(</span><span class="n">pFunc</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">PyCallable_Check</span><span class="p">(</span><span class="n">pFunc</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </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="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyObject_CallObject</span><span class="p">(</span><span class="n">pFunc</span><span class="p">,</span><span class="w"> </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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code> or it contains a
reference to the return value of the function. Be sure to release the reference
after examining the value.</p>
</section>
<section id="extending-embedded-python">
<span id="extending-with-embedding"></span><h2><span class="section-number">1.4. </span>Extending Embedded Python<a class="headerlink" href="#extending-embedded-python" title="Link to this heading"></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="w"> </span><span class="kt">int</span><span class="w"> </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="w"> </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="w"> </span><span class="o">*</span><span class="n">self</span><span class="p">,</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </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="w"> </span><span class="s">&quot;:numargs&quot;</span><span class="p">))</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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="w"> </span><span class="n">PyMethodDef</span><span class="w"> </span><span class="n">EmbMethods</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">{</span><span class="s">&quot;numargs&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">emb_numargs</span><span class="p">,</span><span class="w"> </span><span class="n">METH_VARARGS</span><span class="p">,</span>
<span class="w"> </span><span class="s">&quot;Return the number of arguments received by the process.&quot;</span><span class="p">},</span>
<span class="w"> </span><span class="p">{</span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">}</span>
<span class="p">};</span>
<span class="k">static</span><span class="w"> </span><span class="n">PyModuleDef</span><span class="w"> </span><span class="n">EmbModule</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">PyModuleDef_HEAD_INIT</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;emb&quot;</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="mi">-1</span><span class="p">,</span><span class="w"> </span><span class="n">EmbMethods</span><span class="p">,</span>
<span class="w"> </span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span>
<span class="p">};</span>
<span class="k">static</span><span class="w"> </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="w"> </span><span class="k">return</span><span class="w"> </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="w"> </span><span class="o">=</span><span class="w"> </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="w"> </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="w"> </span><span class="nn">emb</span>
<span class="nb">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>
</section>
<section id="embedding-python-in-c">
<span id="embeddingincplusplus"></span><h2><span class="section-number">1.5. </span>Embedding Python in C++<a class="headerlink" href="#embedding-python-in-c" title="Link to this heading"></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>
</section>
<section id="compiling-and-linking-under-unix-like-systems">
<span id="compiling"></span><h2><span class="section-number">1.6. </span>Compiling and Linking under Unix-like systems<a class="headerlink" href="#compiling-and-linking-under-unix-like-systems" title="Link to this heading"></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.11-config<span class="w"> </span>--cflags
<span class="go">-I/opt/include/python3.11 -I/opt/include/python3.11 -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall</span>
</pre></div>
</div>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">pythonX.Y-config</span> <span class="pre">--ldflags</span> <span class="pre">--embed</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.11-config<span class="w"> </span>--ldflags<span class="w"> </span>--embed
<span class="go">-L/opt/lib/python3.11/config-3.11-x86_64-linux-gnu -L/opt/lib -lpython3.11 -lpthread -ldl -lutil -lm</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="w"> </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>
</section>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<div>
<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>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="windows.html"
title="previous chapter"><span class="section-number">5. </span>Building C and C++ Extensions on Windows</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="../c-api/index.html"
title="next chapter">Python/C API Reference Manual</a></p>
</div>
<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/main/Doc/extending/embedding.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</div>
<div id="sidebarbutton" title="Collapse sidebar">
<span>«</span>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.13.3 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="nav-item nav-item-this"><a href=""><span class="section-number">1. </span>Embedding Python in Another Application</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="footer">
&copy;
<a href="../copyright.html">
Copyright
</a>
2001-2025, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
See <a href="/license.html">History and License</a> for more information.<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
Last updated on Apr 08, 2025 (14:33 UTC).
<a href="/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,440 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:title" content="Extending and Embedding the Python Interpreter" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://docs.python.org/3/extending/index.html" />
<meta property="og:site_name" content="Python documentation" />
<meta property="og:description" content="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 metho..." />
<meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
<meta property="og:image:alt" content="Python documentation" />
<meta name="description" content="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 metho..." />
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="theme-color" content="#3776ab">
<title>Extending and Embedding the Python Interpreter &#8212; Python 3.13.3 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
<link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=23252803" />
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />
<script src="../_static/documentation_options.js?v=5d57ca2d"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="Search within Python 3.13.3 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="Security Considerations" href="../library/security_warnings.html" />
<link rel="canonical" href="https://docs.python.org/3/extending/index.html">
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
<script type="text/javascript" src="../_static/search-focus.js"></script>
<script type="text/javascript" src="../_static/themetoggle.js"></script>
<script type="text/javascript" src="../_static/rtd_switcher.js"></script>
<meta name="readthedocs-addons-api-version" content="1">
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<nav class="nav-content" role="navigation">
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<span class="nav-items-wrapper">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Python logo"/>
</a>
<span class="version_switcher_placeholder"></span>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
<input type="submit" value="Go"/>
</form>
</span>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label>
<div>
<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>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="../library/security_warnings.html"
title="previous chapter">Security Considerations</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="extending.html"
title="next chapter"><span class="section-number">1. </span>Extending Python with C or C++</a></p>
</div>
<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/main/Doc/extending/index.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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/security_warnings.html" title="Security Considerations"
accesskey="P">previous</a> |</li>
<li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.13.3 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-this"><a href="">Extending and Embedding the Python Interpreter</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<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="Link to this heading"></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>
<section id="recommended-third-party-tools">
<h2>Recommended third party tools<a class="headerlink" href="#recommended-third-party-tools" title="Link to this heading"></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="https://cython.org/">Cython</a>, <a class="reference external" href="https://cffi.readthedocs.io">cffi</a>,
<a class="reference external" href="https://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>
</section>
<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="Link to this heading"></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-setuptools">4.1. Building C and C++ Extensions with setuptools</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>
</section>
<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="Link to this heading"></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>
</section>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<div>
<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>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="../library/security_warnings.html"
title="previous chapter">Security Considerations</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="extending.html"
title="next chapter"><span class="section-number">1. </span>Extending Python with C or C++</a></p>
</div>
<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/main/Doc/extending/index.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</div>
<div id="sidebarbutton" title="Collapse sidebar">
<span>«</span>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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/security_warnings.html" title="Security Considerations"
>previous</a> |</li>
<li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.13.3 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-this"><a href="">Extending and Embedding the Python Interpreter</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="footer">
&copy;
<a href="../copyright.html">
Copyright
</a>
2001-2025, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
See <a href="/license.html">History and License</a> for more information.<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
Last updated on Apr 08, 2025 (14:33 UTC).
<a href="/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>

View File

@ -0,0 +1,956 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:title" content="3. Defining Extension Types: Assorted Topics" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://docs.python.org/3/extending/newtypes.html" />
<meta property="og:site_name" content="Python documentation" />
<meta property="og:description" content="This section aims to give a quick fly-by on the various type methods you can implement and what they do. Here is the definition of PyTypeObject, with some fields only used in debug builds omitted: ..." />
<meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
<meta property="og:image:alt" content="Python documentation" />
<meta name="description" content="This section aims to give a quick fly-by on the various type methods you can implement and what they do. Here is the definition of PyTypeObject, with some fields only used in debug builds omitted: ..." />
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="theme-color" content="#3776ab">
<title>3. Defining Extension Types: Assorted Topics &#8212; Python 3.13.3 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
<link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=23252803" />
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />
<script src="../_static/documentation_options.js?v=5d57ca2d"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="Search within Python 3.13.3 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="canonical" href="https://docs.python.org/3/extending/newtypes.html">
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
<script type="text/javascript" src="../_static/search-focus.js"></script>
<script type="text/javascript" src="../_static/themetoggle.js"></script>
<script type="text/javascript" src="../_static/rtd_switcher.js"></script>
<meta name="readthedocs-addons-api-version" content="1">
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<nav class="nav-content" role="navigation">
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<span class="nav-items-wrapper">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Python logo"/>
</a>
<span class="version_switcher_placeholder"></span>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
<input type="submit" value="Go"/>
</form>
</span>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label>
<div>
<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>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="newtypes_tutorial.html"
title="previous chapter"><span class="section-number">2. </span>Defining Extension Types: Tutorial</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="building.html"
title="next chapter"><span class="section-number">4. </span>Building C and C++ Extensions</a></p>
</div>
<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/main/Doc/extending/newtypes.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.13.3 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="nav-item nav-item-this"><a href=""><span class="section-number">3. </span>Defining Extension Types: Assorted Topics</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="defining-extension-types-assorted-topics">
<span id="new-types-topics"></span><h1><span class="section-number">3. </span>Defining Extension Types: Assorted Topics<a class="headerlink" href="#defining-extension-types-assorted-topics" title="Link to this heading"></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
<a class="reference internal" href="../using/configure.html#debug-build"><span class="std std-ref">debug builds</span></a> omitted:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">typedef</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_typeobject</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">PyObject_VAR_HEAD</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">tp_name</span><span class="p">;</span><span class="w"> </span><span class="cm">/* For printing, in format &quot;&lt;module&gt;.&lt;name&gt;&quot; */</span>
<span class="w"> </span><span class="n">Py_ssize_t</span><span class="w"> </span><span class="n">tp_basicsize</span><span class="p">,</span><span class="w"> </span><span class="n">tp_itemsize</span><span class="p">;</span><span class="w"> </span><span class="cm">/* For allocation */</span>
<span class="w"> </span><span class="cm">/* Methods to implement standard operations */</span>
<span class="w"> </span><span class="n">destructor</span><span class="w"> </span><span class="n">tp_dealloc</span><span class="p">;</span>
<span class="w"> </span><span class="n">Py_ssize_t</span><span class="w"> </span><span class="n">tp_vectorcall_offset</span><span class="p">;</span>
<span class="w"> </span><span class="n">getattrfunc</span><span class="w"> </span><span class="n">tp_getattr</span><span class="p">;</span>
<span class="w"> </span><span class="n">setattrfunc</span><span class="w"> </span><span class="n">tp_setattr</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyAsyncMethods</span><span class="w"> </span><span class="o">*</span><span class="n">tp_as_async</span><span class="p">;</span><span class="w"> </span><span class="cm">/* formerly known as tp_compare (Python 2)</span>
<span class="cm"> or tp_reserved (Python 3) */</span>
<span class="w"> </span><span class="n">reprfunc</span><span class="w"> </span><span class="n">tp_repr</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Method suites for standard classes */</span>
<span class="w"> </span><span class="n">PyNumberMethods</span><span class="w"> </span><span class="o">*</span><span class="n">tp_as_number</span><span class="p">;</span>
<span class="w"> </span><span class="n">PySequenceMethods</span><span class="w"> </span><span class="o">*</span><span class="n">tp_as_sequence</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyMappingMethods</span><span class="w"> </span><span class="o">*</span><span class="n">tp_as_mapping</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* More standard operations (here for binary compatibility) */</span>
<span class="w"> </span><span class="n">hashfunc</span><span class="w"> </span><span class="n">tp_hash</span><span class="p">;</span>
<span class="w"> </span><span class="n">ternaryfunc</span><span class="w"> </span><span class="n">tp_call</span><span class="p">;</span>
<span class="w"> </span><span class="n">reprfunc</span><span class="w"> </span><span class="n">tp_str</span><span class="p">;</span>
<span class="w"> </span><span class="n">getattrofunc</span><span class="w"> </span><span class="n">tp_getattro</span><span class="p">;</span>
<span class="w"> </span><span class="n">setattrofunc</span><span class="w"> </span><span class="n">tp_setattro</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Functions to access object as input/output buffer */</span>
<span class="w"> </span><span class="n">PyBufferProcs</span><span class="w"> </span><span class="o">*</span><span class="n">tp_as_buffer</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Flags to define presence of optional/expanded features */</span>
<span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">tp_flags</span><span class="p">;</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">tp_doc</span><span class="p">;</span><span class="w"> </span><span class="cm">/* Documentation string */</span>
<span class="w"> </span><span class="cm">/* Assigned meaning in release 2.0 */</span>
<span class="w"> </span><span class="cm">/* call function for all accessible objects */</span>
<span class="w"> </span><span class="n">traverseproc</span><span class="w"> </span><span class="n">tp_traverse</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* delete references to contained objects */</span>
<span class="w"> </span><span class="n">inquiry</span><span class="w"> </span><span class="n">tp_clear</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Assigned meaning in release 2.1 */</span>
<span class="w"> </span><span class="cm">/* rich comparisons */</span>
<span class="w"> </span><span class="n">richcmpfunc</span><span class="w"> </span><span class="n">tp_richcompare</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* weak reference enabler */</span>
<span class="w"> </span><span class="n">Py_ssize_t</span><span class="w"> </span><span class="n">tp_weaklistoffset</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Iterators */</span>
<span class="w"> </span><span class="n">getiterfunc</span><span class="w"> </span><span class="n">tp_iter</span><span class="p">;</span>
<span class="w"> </span><span class="n">iternextfunc</span><span class="w"> </span><span class="n">tp_iternext</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Attribute descriptor and subclassing stuff */</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">PyMethodDef</span><span class="w"> </span><span class="o">*</span><span class="n">tp_methods</span><span class="p">;</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">PyMemberDef</span><span class="w"> </span><span class="o">*</span><span class="n">tp_members</span><span class="p">;</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">PyGetSetDef</span><span class="w"> </span><span class="o">*</span><span class="n">tp_getset</span><span class="p">;</span>
<span class="w"> </span><span class="c1">// Strong reference on a heap type, borrowed reference on a static type</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">_typeobject</span><span class="w"> </span><span class="o">*</span><span class="n">tp_base</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">tp_dict</span><span class="p">;</span>
<span class="w"> </span><span class="n">descrgetfunc</span><span class="w"> </span><span class="n">tp_descr_get</span><span class="p">;</span>
<span class="w"> </span><span class="n">descrsetfunc</span><span class="w"> </span><span class="n">tp_descr_set</span><span class="p">;</span>
<span class="w"> </span><span class="n">Py_ssize_t</span><span class="w"> </span><span class="n">tp_dictoffset</span><span class="p">;</span>
<span class="w"> </span><span class="n">initproc</span><span class="w"> </span><span class="n">tp_init</span><span class="p">;</span>
<span class="w"> </span><span class="n">allocfunc</span><span class="w"> </span><span class="n">tp_alloc</span><span class="p">;</span>
<span class="w"> </span><span class="n">newfunc</span><span class="w"> </span><span class="n">tp_new</span><span class="p">;</span>
<span class="w"> </span><span class="n">freefunc</span><span class="w"> </span><span class="n">tp_free</span><span class="p">;</span><span class="w"> </span><span class="cm">/* Low-level free-memory routine */</span>
<span class="w"> </span><span class="n">inquiry</span><span class="w"> </span><span class="n">tp_is_gc</span><span class="p">;</span><span class="w"> </span><span class="cm">/* For PyObject_IS_GC */</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">tp_bases</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">tp_mro</span><span class="p">;</span><span class="w"> </span><span class="cm">/* method resolution order */</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">tp_cache</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">tp_subclasses</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">tp_weaklist</span><span class="p">;</span>
<span class="w"> </span><span class="n">destructor</span><span class="w"> </span><span class="n">tp_del</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Type attribute cache version tag. Added in version 2.6 */</span>
<span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">tp_version_tag</span><span class="p">;</span>
<span class="w"> </span><span class="n">destructor</span><span class="w"> </span><span class="n">tp_finalize</span><span class="p">;</span>
<span class="w"> </span><span class="n">vectorcallfunc</span><span class="w"> </span><span class="n">tp_vectorcall</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* bitset of which type-watchers care about this type */</span>
<span class="w"> </span><span class="kt">unsigned</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">tp_watched</span><span class="p">;</span>
<span class="p">}</span><span class="w"> </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="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">tp_name</span><span class="p">;</span><span class="w"> </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="w"> </span><span class="n">tp_basicsize</span><span class="p">,</span><span class="w"> </span><span class="n">tp_itemsize</span><span class="p">;</span><span class="w"> </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="w"> </span><span class="kt">char</span><span class="w"> </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>
<section id="finalization-and-de-allocation">
<h2><span class="section-number">3.1. </span>Finalization and De-allocation<a class="headerlink" href="#finalization-and-de-allocation" title="Link to this heading"></a></h2>
<div class="highlight-c notranslate" id="index-0"><div class="highlight"><pre><span></span><span class="n">destructor</span><span class="w"> </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="w"> </span><span class="kt">void</span>
<span class="nf">newdatatype_dealloc</span><span class="p">(</span><span class="n">newdatatypeobject</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </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="w"> </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="w"> </span><span class="o">*</span><span class="p">)</span><span class="n">obj</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>If your type supports garbage collection, the destructor should call
<a class="reference internal" href="../c-api/gcsupport.html#c.PyObject_GC_UnTrack" title="PyObject_GC_UnTrack"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_GC_UnTrack()</span></code></a> before clearing any member fields:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">void</span>
<span class="nf">newdatatype_dealloc</span><span class="p">(</span><span class="n">newdatatypeobject</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">PyObject_GC_UnTrack</span><span class="p">(</span><span class="n">obj</span><span class="p">);</span>
<span class="w"> </span><span class="n">Py_CLEAR</span><span class="p">(</span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">other_obj</span><span class="p">);</span>
<span class="w"> </span><span class="p">...</span>
<span class="w"> </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="w"> </span><span class="o">*</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="w"> </span><span class="kt">void</span>
<span class="nf">my_dealloc</span><span class="p">(</span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">MyObject</span><span class="w"> </span><span class="o">*</span><span class="n">self</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">MyObject</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="n">obj</span><span class="p">;</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">cbresult</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">self</span><span class="o">-&gt;</span><span class="n">my_callback</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">err_type</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">err_value</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">err_traceback</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* This saves the current exception state */</span>
<span class="w"> </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="w"> </span><span class="o">&amp;</span><span class="n">err_value</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">err_traceback</span><span class="p">);</span>
<span class="w"> </span><span class="n">cbresult</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyObject_CallNoArgs</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="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">cbresult</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span>
<span class="w"> </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="w"> </span><span class="k">else</span>
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">cbresult</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* This restores the saved exception state */</span>
<span class="w"> </span><span class="n">PyErr_Restore</span><span class="p">(</span><span class="n">err_type</span><span class="p">,</span><span class="w"> </span><span class="n">err_value</span><span class="p">,</span><span class="w"> </span><span class="n">err_traceback</span><span class="p">);</span>
<span class="w"> </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="w"> </span><span class="p">}</span>
<span class="w"> </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://peps.python.org/pep-0442/"><strong>PEP 442</strong></a> explains the new finalization scheme.</p>
</div>
</div>
</section>
<section id="object-presentation">
<span id="index-3"></span><h2><span class="section-number">3.2. </span>Object Presentation<a class="headerlink" href="#object-presentation" title="Link to this heading"></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="w"> </span><span class="n">tp_repr</span><span class="p">;</span>
<span class="n">reprfunc</span><span class="w"> </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="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
<span class="nf">newdatatype_repr</span><span class="p">(</span><span class="n">newdatatypeobject</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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="w"> </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="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
<span class="nf">newdatatype_str</span><span class="p">(</span><span class="n">newdatatypeobject</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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="w"> </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>
</section>
<section id="attribute-management">
<h2><span class="section-number">3.3. </span>Attribute Management<a class="headerlink" href="#attribute-management" title="Link to this heading"></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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>.</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 <span class="c-expr sig sig-inline c"><span class="kt">char</span><span class="p">*</span></span>, while the other
accepts a <span class="c-expr sig sig-inline c"><a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject"><span class="n">PyObject</span></a><span class="p">*</span></span>. 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="w"> </span><span class="n">tp_getattr</span><span class="p">;</span><span class="w"> </span><span class="cm">/* char * version */</span>
<span class="n">setattrfunc</span><span class="w"> </span><span class="n">tp_setattr</span><span class="p">;</span>
<span class="cm">/* ... */</span>
<span class="n">getattrofunc</span><span class="w"> </span><span class="n">tp_getattro</span><span class="p">;</span><span class="w"> </span><span class="cm">/* PyObject * version */</span>
<span class="n">setattrofunc</span><span class="w"> </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 <span class="c-expr sig sig-inline c"><a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject"><span class="n">PyObject</span></a><span class="p">*</span></span> 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>
<section id="generic-attribute-management">
<span id="id1"></span><h3><span class="section-number">3.3.1. </span>Generic Attribute Management<a class="headerlink" href="#generic-attribute-management" title="Link to this heading"></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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>, 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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code> 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="w"> </span><span class="nc">PyMethodDef</span><span class="w"> </span><span class="o">*</span><span class="n">tp_methods</span><span class="p">;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">PyMemberDef</span><span class="w"> </span><span class="o">*</span><span class="n">tp_members</span><span class="p">;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">PyGetSetDef</span><span class="w"> </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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>, 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="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">PyMethodDef</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">ml_name</span><span class="p">;</span><span class="w"> </span><span class="cm">/* method name */</span>
<span class="w"> </span><span class="n">PyCFunction</span><span class="w"> </span><span class="n">ml_meth</span><span class="p">;</span><span class="w"> </span><span class="cm">/* implementation function */</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">ml_flags</span><span class="p">;</span><span class="w"> </span><span class="cm">/* flags */</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">ml_doc</span><span class="p">;</span><span class="w"> </span><span class="cm">/* docstring */</span>
<span class="p">}</span><span class="w"> </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
<a class="reference internal" href="../c-api/structures.html#c.PyMethodDef.ml_name" title="PyMethodDef.ml_name"><code class="xref c c-member docutils literal notranslate"><span class="pre">ml_name</span></code></a> field of the sentinel must be <code class="docutils literal notranslate"><span class="pre">NULL</span></code>.</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="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">PyMemberDef</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">name</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">type</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">offset</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">flags</span><span class="p">;</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">doc</span><span class="p">;</span>
<span class="p">}</span><span class="w"> </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="../c-api/structures.html#c.PyMemberDef.type" title="PyMemberDef.type"><code class="xref c c-member docutils literal notranslate"><span class="pre">type</span></code></a> field should contain a type code like <a class="reference internal" href="../c-api/structures.html#c.Py_T_INT" title="Py_T_INT"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_T_INT</span></code></a> or
<a class="reference internal" href="../c-api/structures.html#c.Py_T_DOUBLE" title="Py_T_DOUBLE"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_T_DOUBLE</span></code></a>; the value will be used to determine how to
convert Python values to and from C values. The <a class="reference internal" href="../c-api/structures.html#c.PyMemberDef.flags" title="PyMemberDef.flags"><code class="xref c c-member docutils literal notranslate"><span class="pre">flags</span></code></a> field is used to
store flags which control how the attribute can be accessed: you can set it to
<a class="reference internal" href="../c-api/structures.html#c.Py_READONLY" title="Py_READONLY"><code class="xref c c-macro docutils literal notranslate"><span class="pre">Py_READONLY</span></code></a> to prevent Python code from setting it.</p>
<p>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 <a class="reference internal" href="../reference/datamodel.html#type.__doc__" title="type.__doc__"><code class="xref py py-attr docutils literal notranslate"><span class="pre">__doc__</span></code></a> 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 <a class="reference internal" href="../c-api/structures.html#c.PyMethodDef.ml_name" title="PyMethodDef.ml_name"><code class="xref c c-member docutils literal notranslate"><span class="pre">ml_name</span></code></a> value
of <code class="docutils literal notranslate"><span class="pre">NULL</span></code> is required.</p>
</section>
<section id="type-specific-attribute-management">
<h3><span class="section-number">3.3.2. </span>Type-specific Attribute Management<a class="headerlink" href="#type-specific-attribute-management" title="Link to this heading"></a></h3>
<p>For simplicity, only the <span class="c-expr sig sig-inline c"><span class="kt">char</span><span class="p">*</span></span> version will be demonstrated here; the
type of the name parameter is the only difference between the <span class="c-expr sig sig-inline c"><span class="kt">char</span><span class="p">*</span></span>
and <span class="c-expr sig sig-inline c"><a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject"><span class="n">PyObject</span></a><span class="p">*</span></span> 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="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
<span class="nf">newdatatype_getattr</span><span class="p">(</span><span class="n">newdatatypeobject</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">name</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </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="w"> </span><span class="s">&quot;data&quot;</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">PyErr_Format</span><span class="p">(</span><span class="n">PyExc_AttributeError</span><span class="p">,</span>
<span class="w"> </span><span class="s">&quot;&#39;%.100s&#39; object has no attribute &#39;%.400s&#39;&quot;</span><span class="p">,</span>
<span class="w"> </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_name</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>. 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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">int</span>
<span class="nf">newdatatype_setattr</span><span class="p">(</span><span class="n">newdatatypeobject</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">name</span><span class="p">,</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">v</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">PyErr_Format</span><span class="p">(</span><span class="n">PyExc_RuntimeError</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;Read-only attribute: %s&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">-1</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
</section>
<section id="object-comparison">
<h2><span class="section-number">3.4. </span>Object Comparison<a class="headerlink" href="#object-comparison" title="Link to this heading"></a></h2>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">richcmpfunc</span><span class="w"> </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
<code class="xref py py-meth docutils literal notranslate"><span class="pre">__lt__()</span></code>, 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_GE</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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>
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="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
<span class="nf">newdatatype_richcmp</span><span class="p">(</span><span class="n">newdatatypeobject</span><span class="w"> </span><span class="o">*</span><span class="n">obj1</span><span class="p">,</span><span class="w"> </span><span class="n">newdatatypeobject</span><span class="w"> </span><span class="o">*</span><span class="n">obj2</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">op</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">result</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">c</span><span class="p">,</span><span class="w"> </span><span class="n">size1</span><span class="p">,</span><span class="w"> </span><span class="n">size2</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* code to make sure that both arguments are of type</span>
<span class="cm"> newdatatype omitted */</span>
<span class="w"> </span><span class="n">size1</span><span class="w"> </span><span class="o">=</span><span class="w"> </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="w"> </span><span class="n">size2</span><span class="w"> </span><span class="o">=</span><span class="w"> </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="w"> </span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="n">op</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">Py_LT</span><span class="p">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size1</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">size2</span><span class="p">;</span><span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">Py_LE</span><span class="p">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size1</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">size2</span><span class="p">;</span><span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">Py_EQ</span><span class="p">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size1</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">size2</span><span class="p">;</span><span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">Py_NE</span><span class="p">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size1</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">size2</span><span class="p">;</span><span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">Py_GT</span><span class="p">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size1</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">size2</span><span class="p">;</span><span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">Py_GE</span><span class="p">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">size1</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">size2</span><span class="p">;</span><span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="n">Py_True</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Py_False</span><span class="p">;</span>
<span class="w"> </span><span class="n">Py_INCREF</span><span class="p">(</span><span class="n">result</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">result</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
</pre></div>
</div>
</section>
<section id="abstract-protocol-support">
<h2><span class="section-number">3.5. </span>Abstract Protocol Support<a class="headerlink" href="#abstract-protocol-support" title="Link to this heading"></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-<code class="docutils literal notranslate"><span class="pre">NULL</span></code>. 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="w"> </span><span class="o">*</span><span class="n">tp_as_number</span><span class="p">;</span>
<span class="n">PySequenceMethods</span><span class="w"> </span><span class="o">*</span><span class="n">tp_as_sequence</span><span class="p">;</span>
<span class="n">PyMappingMethods</span><span class="w"> </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="w"> </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="w"> </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="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">Py_hash_t</span><span class="w"> </span><span class="n">result</span><span class="p">;</span>
<span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">some_size</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">32767</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">obj</span><span class="o">-&gt;</span><span class="n">some_number</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">result</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">-1</span><span class="p">)</span>
<span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-2</span><span class="p">;</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">result</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p><a class="reference internal" href="../c-api/hash.html#c.Py_hash_t" title="Py_hash_t"><code class="xref c c-type docutils literal notranslate"><span class="pre">Py_hash_t</span></code></a> 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="w"> </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-<code class="docutils literal notranslate"><span class="pre">NULL</span></code> 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-<code class="docutils literal notranslate"><span class="pre">NULL</span></code>, 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="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
<span class="nf">newdatatype_call</span><span class="p">(</span><span class="n">newdatatypeobject</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">,</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">kwds</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">result</span><span class="p">;</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">arg1</span><span class="p">;</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">arg2</span><span class="p">;</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">arg3</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </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="w"> </span><span class="s">&quot;sss:call&quot;</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">arg1</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">arg2</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">arg3</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyUnicode_FromFormat</span><span class="p">(</span>
<span class="w"> </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="w"> </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="w"> </span><span class="n">arg1</span><span class="p">,</span><span class="w"> </span><span class="n">arg2</span><span class="p">,</span><span class="w"> </span><span class="n">arg3</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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="w"> </span><span class="n">tp_iter</span><span class="p">;</span>
<span class="n">iternextfunc</span><span class="w"> </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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>. <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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code> 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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>; 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 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>.</p>
</section>
<section id="weak-reference-support">
<span id="weakref-support"></span><h2><span class="section-number">3.6. </span>Weak Reference Support<a class="headerlink" href="#weak-reference-support" title="Link to this heading"></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 referenceable, the extension type must set the
<code class="docutils literal notranslate"><span class="pre">Py_TPFLAGS_MANAGED_WEAKREF</span></code> bit of the <a class="reference internal" href="../c-api/typeobj.html#c.PyTypeObject.tp_flags" title="PyTypeObject.tp_flags"><code class="xref c c-member docutils literal notranslate"><span class="pre">tp_flags</span></code></a>
field. The legacy <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> field should
be left as zero.</p>
<p>Concretely, here is how the statically declared type object would look:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="n">PyTypeObject</span><span class="w"> </span><span class="n">TrivialType</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">PyVarObject_HEAD_INIT</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="cm">/* ... other members omitted for brevity ... */</span>
<span class="w"> </span><span class="p">.</span><span class="n">tp_flags</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Py_TPFLAGS_MANAGED_WEAKREF</span><span class="w"> </span><span class="o">|</span><span class="w"> </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 <a class="reference internal" href="../c-api/weakref.html#c.PyObject_ClearWeakRefs" title="PyObject_ClearWeakRefs"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_ClearWeakRefs()</span></code></a>):</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">void</span>
<span class="nf">Trivial_dealloc</span><span class="p">(</span><span class="n">TrivialObject</span><span class="w"> </span><span class="o">*</span><span class="n">self</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="cm">/* Clear weakrefs first before calling any destructors */</span>
<span class="w"> </span><span class="n">PyObject_ClearWeakRefs</span><span class="p">((</span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="n">self</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* ... remainder of destruction code omitted for brevity ... */</span>
<span class="w"> </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="w"> </span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="n">self</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
<section id="more-suggestions">
<h2><span class="section-number">3.7. </span>More Suggestions<a class="headerlink" href="#more-suggestions" title="Link to this heading"></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="w"> </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="w"> </span><span class="o">&amp;</span><span class="n">MyType</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">PyErr_SetString</span><span class="p">(</span><span class="n">PyExc_TypeError</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;arg #1 not a mything&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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>
</section>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<div>
<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>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="newtypes_tutorial.html"
title="previous chapter"><span class="section-number">2. </span>Defining Extension Types: Tutorial</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="building.html"
title="next chapter"><span class="section-number">4. </span>Building C and C++ Extensions</a></p>
</div>
<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/main/Doc/extending/newtypes.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</div>
<div id="sidebarbutton" title="Collapse sidebar">
<span>«</span>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.13.3 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="nav-item nav-item-this"><a href=""><span class="section-number">3. </span>Defining Extension Types: Assorted Topics</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="footer">
&copy;
<a href="../copyright.html">
Copyright
</a>
2001-2025, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
See <a href="/license.html">History and License</a> for more information.<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
Last updated on Apr 08, 2025 (14:33 UTC).
<a href="/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,432 @@
<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:title" content="5. Building C and C++ Extensions on Windows" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://docs.python.org/3/extending/windows.html" />
<meta property="og:site_name" content="Python documentation" />
<meta property="og:description" content="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 ..." />
<meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
<meta property="og:image:alt" content="Python documentation" />
<meta name="description" content="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 ..." />
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="theme-color" content="#3776ab">
<title>5. Building C and C++ Extensions on Windows &#8212; Python 3.13.3 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
<link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=23252803" />
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />
<script src="../_static/documentation_options.js?v=5d57ca2d"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="Search within Python 3.13.3 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="canonical" href="https://docs.python.org/3/extending/windows.html">
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
<script type="text/javascript" src="../_static/search-focus.js"></script>
<script type="text/javascript" src="../_static/themetoggle.js"></script>
<script type="text/javascript" src="../_static/rtd_switcher.js"></script>
<meta name="readthedocs-addons-api-version" content="1">
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<nav class="nav-content" role="navigation">
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<span class="nav-items-wrapper">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Python logo"/>
</a>
<span class="version_switcher_placeholder"></span>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
<input type="submit" value="Go"/>
</form>
</span>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label>
<div>
<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>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="building.html"
title="previous chapter"><span class="section-number">4. </span>Building C and C++ Extensions</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="embedding.html"
title="next chapter"><span class="section-number">1. </span>Embedding Python in Another Application</a></p>
</div>
<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/main/Doc/extending/windows.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.13.3 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="nav-item nav-item-this"><a href=""><span class="section-number">5. </span>Building C and C++ Extensions on Windows</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="building-c-and-c-extensions-on-windows">
<span id="building-on-windows"></span><h1><span class="section-number">5. </span>Building C and C++ Extensions on Windows<a class="headerlink" href="#building-c-and-c-extensions-on-windows" title="Link to this heading"></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>
<section id="a-cookbook-approach">
<span id="win-cookbook"></span><h2><span class="section-number">5.1. </span>A Cookbook Approach<a class="headerlink" href="#a-cookbook-approach" title="Link to this heading"></a></h2>
<p>There are two approaches to building extension modules on Windows, just as there
are on Unix: use the <code class="docutils literal notranslate"><span class="pre">setuptools</span></code> package to control the build process, or
do things manually. The setuptools approach works well for most extensions;
documentation on using <code class="docutils literal notranslate"><span class="pre">setuptools</span></code> to build and package extension modules
is available in <a class="reference internal" href="building.html#setuptools-index"><span class="std std-ref">Building C and C++ Extensions with setuptools</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="extlink-source reference external" href="https://github.com/python/cpython/tree/3.13/PCbuild/winsound.vcxproj">winsound</a> standard library module.</p>
</section>
<section id="differences-between-unix-and-windows">
<span id="dynamic-linking"></span><h2><span class="section-number">5.2. </span>Differences Between Unix and Windows<a class="headerlink" href="#differences-between-unix-and-windows" title="Link to this heading"></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>
</section>
<section id="using-dlls-in-practice">
<span id="win-dlls"></span><h2><span class="section-number">5.3. </span>Using DLLs in Practice<a class="headerlink" href="#using-dlls-in-practice" title="Link to this heading"></a></h2>
<p>Windows Python is built in Microsoft Visual C++; using other compilers may or
may not work. 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="w"> </span><span class="o">/</span><span class="n">LD</span><span class="w"> </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="w"> </span><span class="n">spam</span><span class="p">.</span><span class="n">c</span><span class="w"> </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="w"> </span><span class="o">/</span><span class="n">LD</span><span class="w"> </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="w"> </span><span class="n">ni</span><span class="p">.</span><span class="n">c</span><span class="w"> </span><span class="n">spam</span><span class="p">.</span><span class="n">lib</span><span class="w"> </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">msvcrt</span><em><span class="pre">xx</span></em><span class="pre">.lib</span></code> to the list of libraries.</p>
</section>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<div>
<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>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="building.html"
title="previous chapter"><span class="section-number">4. </span>Building C and C++ Extensions</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="embedding.html"
title="next chapter"><span class="section-number">1. </span>Embedding Python in Another Application</a></p>
</div>
<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/main/Doc/extending/windows.rst"
rel="nofollow">Show Source
</a>
</li>
</ul>
</div>
</div>
<div id="sidebarbutton" title="Collapse sidebar">
<span>«</span>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.13.3 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="nav-item nav-item-this"><a href=""><span class="section-number">5. </span>Building C and C++ Extensions on Windows</a></li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
<input type="submit" value="Go" />
</form>
</div>
|
</li>
<li class="right">
<label class="theme-selector-label">
Theme
<select class="theme-selector" oninput="activateTheme(this.value)">
<option value="auto" selected>Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</label> |</li>
</ul>
</div>
<div class="footer">
&copy;
<a href="../copyright.html">
Copyright
</a>
2001-2025, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
See <a href="/license.html">History and License</a> for more information.<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
Last updated on Apr 08, 2025 (14:33 UTC).
<a href="/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>