<!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" /> <title>Choosing between Python eclasses — Gentoo Python Guide documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=d1102ebc" /> <link rel="stylesheet" type="text/css" href="_static/basic.css?v=686e5160" /> <link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=27fed22d" /> <script src="_static/documentation_options.js?v=5929fcd5"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> <link rel="next" title="Common basics" href="basic.html" /> <link rel="prev" title="Python interpreters" href="interpreter.html" /> <link rel="stylesheet" href="_static/custom.css" type="text/css" /> </head><body> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body" role="main"> <section id="choosing-between-python-eclasses"> <h1>Choosing between Python eclasses<a class="headerlink" href="#choosing-between-python-eclasses" title="Link to this heading">¶</a></h1> <section id="overview"> <h2>Overview<a class="headerlink" href="#overview" title="Link to this heading">¶</a></h2> <p>The python-r1 eclass suite features 5 eclasses in total:</p> <ol class="arabic simple"> <li><p><code class="docutils literal notranslate"><span class="pre">python-utils-r1.eclass</span></code> that provides utility functions common to all eclasses. This eclass is rarely inherited directly.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">python-any-r1.eclass</span></code> that is suitable for packages using Python purely at build time.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">python-single-r1.eclass</span></code> that provides a base for simpler packages installing Python scripts and alike.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">python-r1.eclass</span></code> that provides a base for more complex packages, particularly these installing Python modules.</p></li> <li><p><code class="docutils literal notranslate"><span class="pre">distutils-r1.eclass</span></code> that provides convenient phase functions and helpers for packages that primarily involve installing Python files.</p></li> </ol> <figure class="align-default" id="id1"> <img alt="_images/eclass.svg" src="_images/eclass.svg" /> <figcaption> <p><span class="caption-text">Inheritance graph of python-r1 suite eclasses.</span><a class="headerlink" href="#id1" title="Link to this image">¶</a></p> </figcaption> </figure> <p>As a rule of thumb, the best eclass to use is the one that makes the ebuild the simplest while meeting its requirements. A more detailed process involves:</p> <ol class="arabic simple"> <li><p>Determining whether Python is used purely at build time, or at runtime as well. In the former case, <code class="docutils literal notranslate"><span class="pre">python-any-r1</span></code> is the right choice.</p></li> <li><p>Determining whether single-impl or multi-impl approach is more appropriate. For the former, <code class="docutils literal notranslate"><span class="pre">python-single-r1</span></code> is the correct base eclass. For the latter, <code class="docutils literal notranslate"><span class="pre">python-r1</span></code>.</p></li> <li><p>Determining whether the ebuild benefits from using <code class="docutils literal notranslate"><span class="pre">distutils-r1</span></code>. If it does, this eclass should be use instead (potentially along with <code class="docutils literal notranslate"><span class="pre">DISTUTILS_SINGLE_IMPL</span></code> to switch the underlying eclass).</p></li> </ol> </section> <section id="build-time-vs-runtime-use"> <h2>Build time vs runtime use<a class="headerlink" href="#build-time-vs-runtime-use" title="Link to this heading">¶</a></h2> <p>The first basis for choosing Python eclass is whether Python is used merely at build time or at runtime as well.</p> <p>A runtime use occurs if the package explicitly needs Python to be installed along with it, in order for it to function correctly. This generally happens if the package installs Python modules, extensions, scripts, or executables calling the Python interpreter or linking to libpython. This also applies to bash scripts or other executables that call python inline.</p> <p>A build time use occurs if the package calls the Python interpreter or any kind of aforementioned executables during package’s build (or install) phases.</p> <p>If the package uses Python purely at build time, the <code class="docutils literal notranslate"><span class="pre">python-any-r1</span></code> eclass is appropriate. Otherwise, <code class="docutils literal notranslate"><span class="pre">python-single-r1</span></code>, <code class="docutils literal notranslate"><span class="pre">python-r1</span></code> or <code class="docutils literal notranslate"><span class="pre">distutils-r1</span></code> are to be used.</p> <p>A specific exception to that rule is when the package is only calling external Python scripts directly (i.e. not via <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">/usr/bin/foo</span></code>). If the called executables can be considered fully contained dependency-wise, there is no need to use an eclass.</p> <p>For example, when using <code class="docutils literal notranslate"><span class="pre">dev-util/meson</span></code> to build a package, there is no need to use a Python eclass since Meson abstracts away its Pythonic implementation details and works as a regular executable for your packages. However, <code class="docutils literal notranslate"><span class="pre">dev-util/scons</span></code> requires Python eclass since it loads Python code from the package and a compatible Python version must be enforced.</p> </section> <section id="single-impl-vs-multi-impl"> <h2>Single-impl vs multi-impl<a class="headerlink" href="#single-impl-vs-multi-impl" title="Link to this heading">¶</a></h2> <p>The second important basis for packages using Python at runtime is whether the package in question should support multi-implementation install or not.</p> <p>A <em>single-impl</em> package is a package requiring the user to choose exactly one Python implementation to be built against. This means that the scripts installed by that package will be run via specified Python interpreter, and that the modules and extensions will be importable from it only. The package’s Python reverse dependencies will also have to use the same implementation. Since the package can’t support having more than one implementation enabled, its reverse dependencies have to be simple-impl as well.</p> <p>Single-impl packages use <code class="docutils literal notranslate"><span class="pre">python-single-r1</span></code> eclass. Writing ebuilds for them is easier since it is generally sufficient to call setup function early on, and the upstream build system generally takes care of using selected Python version correctly. Making packages single-impl is recommended when dealing with packages that are not purely written for Python or have single-impl dependencies.</p> <p>A <em>multi-impl</em> package allows user to enable multiple (preferably any number of) implementations. The modules, extensions and scripts installed by the package are installed separately for each enabled implementation, and can therefore be used from any of them. The package can have reverse dependencies enabling only a subset of its implementations.</p> <p>Multi-impl packages use <code class="docutils literal notranslate"><span class="pre">python-r1</span></code> eclass. Ebuilds are more complex since they need to explicitly repeat build and install steps for each enabled implementation. Using this model is recommended for packages providing Python modules or extensions only, or having multi-impl reverse dependencies. In some cases supporting multi-impl build requires applying hacks, e.g. <code class="docutils literal notranslate"><span class="pre">dev-libs/boost[python]</span></code> uses non-standard names to install <code class="docutils literal notranslate"><span class="pre">libboost_python</span></code> for multiple Python versions.</p> <p>The implementation for single-impl packages is selected via <code class="docutils literal notranslate"><span class="pre">PYTHON_SINGLE_TARGET</span></code>, while multi-impl uses <code class="docutils literal notranslate"><span class="pre">PYTHON_TARGETS</span></code>. These USE flag sets can be set independently to provide greater flexibility for developers and end users.</p> <p>Both single-impl and multi-impl installs are supported by the <code class="docutils literal notranslate"><span class="pre">distutils-r1</span></code> eclass.</p> </section> <section id="python-first-packages-distutils-r1-eclass"> <h2>Python-first packages (distutils-r1 eclass)<a class="headerlink" href="#python-first-packages-distutils-r1-eclass" title="Link to this heading">¶</a></h2> <p>The third step in choosing the eclass for runtime use of Python is determining whether the ebuild would benefit from <code class="docutils literal notranslate"><span class="pre">distutils-r1</span></code>. This eclass is especially useful for packages that primarily focus on providing Python content. Its advantages include:</p> <ul class="simple"> <li><p>adding appropriate dependencies and <code class="docutils literal notranslate"><span class="pre">REQUIRED_USE</span></code> by default</p></li> <li><p>a sub-phase function mechanism that makes installing Python modules in multi-impl mode easier</p></li> <li><p>convenient support for building documentation using Sphinx and running tests using common Python test runners</p></li> </ul> <p>In general, <code class="docutils literal notranslate"><span class="pre">distutils-r1</span></code> should be preferred over the other eclasses if:</p> <ul class="simple"> <li><p>the package uses a PEP 517-compliant build system (i.e. has a <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> file with a <code class="docutils literal notranslate"><span class="pre">build-system</span></code> section)</p></li> <li><p>the package uses a legacy distutils or setuptools build system (i.e. has a <code class="docutils literal notranslate"><span class="pre">setup.py</span></code> file)</p></li> <li><p>the package primarily installs Python modules</p></li> </ul> <p>In general, for multi-impl packages <code class="docutils literal notranslate"><span class="pre">distutils-r1</span></code> is preferred over <code class="docutils literal notranslate"><span class="pre">python-r1</span></code> as it usually makes the ebuilds simpler. For single-impl packages, <code class="docutils literal notranslate"><span class="pre">python-single-r1</span></code> can sometimes be simpler.</p> </section> </section> </div> </div> </div> <div class="sphinxsidebar" role="navigation" aria-label="Main"> <div class="sphinxsidebarwrapper"> <h1 class="logo"><a href="index.html">Gentoo Python Guide</a></h1> <search id="searchbox" style="display: none" role="search"> <div class="searchformwrapper"> <form class="search" action="search.html" method="get"> <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/> <input type="submit" value="Go" /> </form> </div> </search> <script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3> <p class="caption" role="heading"><span class="caption-text">Contents:</span></p> <ul class="current"> <li class="toctree-l1"><a class="reference internal" href="preface.html">Preface</a></li> <li class="toctree-l1"><a class="reference internal" href="interpreter.html">Python interpreters</a></li> <li class="toctree-l1 current"><a class="current reference internal" href="#">Choosing between Python eclasses</a><ul> <li class="toctree-l2"><a class="reference internal" href="#overview">Overview</a></li> <li class="toctree-l2"><a class="reference internal" href="#build-time-vs-runtime-use">Build time vs runtime use</a></li> <li class="toctree-l2"><a class="reference internal" href="#single-impl-vs-multi-impl">Single-impl vs multi-impl</a></li> <li class="toctree-l2"><a class="reference internal" href="#python-first-packages-distutils-r1-eclass">Python-first packages (distutils-r1 eclass)</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="basic.html">Common basics</a></li> <li class="toctree-l1"><a class="reference internal" href="any.html">python-any-r1 — build-time dependency</a></li> <li class="toctree-l1"><a class="reference internal" href="single.html">python-single-r1 — single-impl packages</a></li> <li class="toctree-l1"><a class="reference internal" href="multi.html">python-r1 — multi-impl packages</a></li> <li class="toctree-l1"><a class="reference internal" href="distutils.html">distutils-r1 — standard Python build systems</a></li> <li class="toctree-l1"><a class="reference internal" href="test.html">Tests in Python packages</a></li> <li class="toctree-l1"><a class="reference internal" href="distutils-legacy.html">distutils-r1 legacy concepts</a></li> <li class="toctree-l1"><a class="reference internal" href="pypi.html">pypi — helper eclass for PyPI archives</a></li> <li class="toctree-l1"><a class="reference internal" href="helper.html">Common helper functions</a></li> <li class="toctree-l1"><a class="reference internal" href="depend.html">Advanced dependencies</a></li> <li class="toctree-l1"><a class="reference internal" href="pytest.html">pytest recipes</a></li> <li class="toctree-l1"><a class="reference internal" href="concept.html">Advanced concepts</a></li> <li class="toctree-l1"><a class="reference internal" href="expert-multi.html">Expert python-r1 usage</a></li> <li class="toctree-l1"><a class="reference internal" href="buildsys.html">Integration with build systems written in Python</a></li> <li class="toctree-l1"><a class="reference internal" href="porting.html">Porting tips</a></li> <li class="toctree-l1"><a class="reference internal" href="migration.html">Migration guides</a></li> <li class="toctree-l1"><a class="reference internal" href="qawarn.html">QA checks and warnings</a></li> <li class="toctree-l1"><a class="reference internal" href="package-maintenance.html">Python package maintenance</a></li> <li class="toctree-l1"><a class="reference internal" href="interpreter-maintenance.html">Maintenance of Python implementations</a></li> </ul> <div class="relations"> <h3>Related Topics</h3> <ul> <li><a href="index.html">Documentation overview</a><ul> <li>Previous: <a href="interpreter.html" title="previous chapter">Python interpreters</a></li> <li>Next: <a href="basic.html" title="next chapter">Common basics</a></li> </ul></li> </ul> </div> </div> </div> <div class="clearer"></div> </div> <div class="footer"> ©2020, Michał Górny, license: CC BY 4.0. | Powered by <a href="https://www.sphinx-doc.org/">Sphinx 8.1.3</a> & <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a> | <a href="_sources/eclass.rst.txt" rel="nofollow">Page source</a> </div> </body> </html>