summaryrefslogtreecommitdiff
blob: fb052e572827727a5de3422bb5801f49d8e83e2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
<!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>distutils-r1 legacy concepts &#8212; 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/alabaster.css?v=12dfc556" />
    <script src="_static/documentation_options.js?v=5929fcd5"></script>
    <script src="_static/doctools.js?v=9a2dae69"></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="pypi — helper eclass for PyPI archives" href="pypi.html" />
    <link rel="prev" title="Tests in Python packages" href="test.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="distutils-r1-legacy-concepts">
<h1>distutils-r1 legacy concepts<a class="headerlink" href="#distutils-r1-legacy-concepts" title="Link to this heading"></a></h1>
<p>This section describes concepts specific to the legacy mode
of the <code class="docutils literal notranslate"><span class="pre">distutils-r1</span></code> eclass.  When using the modern PEP 517 mode,
none of the features described here are available.</p>
<section id="different-build-system-variations">
<span id="index-0"></span><h2>Different build system variations<a class="headerlink" href="#different-build-system-variations" title="Link to this heading"></a></h2>
<p>The commonly used build systems specific to Python packages can be
classified for eclass support into following groups:</p>
<ol class="arabic simple">
<li><p>Plain distutils (built-in in Python).</p></li>
<li><p>Setuptools and its direct derivatives (e.g. pbr).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code>-based build systems (Flit, Poetry).</p></li>
</ol>
<p>The eclass supports the first two directly.  Support for Flit and Poetry
is provided through the <code class="docutils literal notranslate"><span class="pre">dev-python/pyproject2setuppy</span></code> package that
converts the package’s metadata to setuptools call.</p>
<p>In addition to being a build system, setuptools provides runtime
facilities via the <code class="docutils literal notranslate"><span class="pre">pkg_resources</span></code> module.  If these facilities
are used, the package needs to have a runtime dependency
on <code class="docutils literal notranslate"><span class="pre">dev-python/setuptools</span></code>.  Otherwise, a build-time dependency
is sufficient.</p>
<section id="distutils-use-setuptools">
<h3>DISTUTILS_USE_SETUPTOOLS<a class="headerlink" href="#distutils-use-setuptools" title="Link to this heading"></a></h3>
<p>The most common case right now is a package using setuptools as a build
system, and therefore needing a build-time dependency only.  This
is the eclass’ default.  If your package does not fit this profile,
you can set <code class="docutils literal notranslate"><span class="pre">DISTUTILS_USE_SETUPTOOLS</span></code> variable to one
of the supported values:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">no</span></code> — pure distutils use (no extra dependencies).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">bdepend</span></code> — build-time use of setuptools (<code class="docutils literal notranslate"><span class="pre">BDEPEND</span></code>
on <code class="docutils literal notranslate"><span class="pre">dev-python/setuptools</span></code>).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">rdepend</span></code> — build- and runtime use of setuptools (<code class="docutils literal notranslate"><span class="pre">BDEPEND</span></code>
and <code class="docutils literal notranslate"><span class="pre">RDEPEND</span></code> on <code class="docutils literal notranslate"><span class="pre">dev-python/setuptools</span></code>).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> — use of Flit or Poetry (<code class="docutils literal notranslate"><span class="pre">BDEPEND</span></code>
on <code class="docutils literal notranslate"><span class="pre">dev-python/pyproject2toml</span></code> and <code class="docutils literal notranslate"><span class="pre">dev-python/setuptools</span></code>).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">manual</span></code> — special value indicating that the eclass logic misbehaves
and the dependency needs to be specified manually.  Strongly
discouraged, please report a bug and/or fix the package instead.</p></li>
</ul>
<p>The cases for particular values are explained in subsequent sections.</p>
<p>The Gentoo repository includes a post-install QA check that verifies
whether the value of <code class="docutils literal notranslate"><span class="pre">DISTUTILS_USE_SETUPTOOLS</span></code> is correct,
and reports if it is most likely incorrect.  This is why it is important
to use the variable rather than specifying the dependency directly.
An example report is:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>*<span class="w"> </span>DISTUTILS_USE_SETUPTOOLS<span class="w"> </span>value<span class="w"> </span>is<span class="w"> </span>probably<span class="w"> </span>incorrect
*<span class="w">   </span>have:<span class="w">     </span><span class="nv">DISTUTILS_USE_SETUPTOOLS</span><span class="o">=</span>bdepend<span class="w"> </span><span class="o">(</span>or<span class="w"> </span><span class="nb">unset</span><span class="o">)</span>
*<span class="w">   </span>expected:<span class="w"> </span><span class="nv">DISTUTILS_USE_SETUPTOOLS</span><span class="o">=</span>rdepend
</pre></div>
</div>
<p>The value needs to be set before inheriting the eclass:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="c1"># Copyright 1999-2020 Gentoo Authors</span>
<span class="w"> </span><span class="c1"># Distributed under the terms of the GNU General Public License v2</span>

<span class="w"> </span><span class="nv">EAPI</span><span class="o">=</span><span class="m">7</span>

<span class="w"> </span><span class="nv">PYTHON_COMPAT</span><span class="o">=(</span><span class="w"> </span>python2_7<span class="w"> </span>python3_<span class="o">{</span><span class="m">6</span>,7,8<span class="o">}</span><span class="w"> </span>pypy3<span class="w"> </span><span class="o">)</span>
<span class="hll"><span class="w"> </span><span class="nv">DISTUTILS_USE_SETUPTOOLS</span><span class="o">=</span>rdepend
</span>
<span class="w"> </span>inherit<span class="w"> </span>distutils-r1

<span class="w"> </span><span class="nv">DESCRIPTION</span><span class="o">=</span><span class="s2">&quot;A configurable sidebar-enabled Sphinx theme&quot;</span>
<span class="w"> </span><span class="nv">HOMEPAGE</span><span class="o">=</span><span class="s2">&quot;https://github.com/bitprophet/alabaster&quot;</span>
<span class="w"> </span><span class="nv">SRC_URI</span><span class="o">=</span><span class="s2">&quot;mirror://pypi/</span><span class="si">${</span><span class="nv">PN</span><span class="p">:</span><span class="nv">0</span><span class="p">:</span><span class="nv">1</span><span class="si">}</span><span class="s2">/</span><span class="si">${</span><span class="nv">PN</span><span class="si">}</span><span class="s2">/</span><span class="si">${</span><span class="nv">P</span><span class="si">}</span><span class="s2">.tar.gz&quot;</span>

<span class="w"> </span><span class="nv">LICENSE</span><span class="o">=</span><span class="s2">&quot;BSD&quot;</span>
<span class="w"> </span><span class="nv">KEYWORDS</span><span class="o">=</span><span class="s2">&quot;~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~x64-solaris&quot;</span>
<span class="w"> </span><span class="nv">SLOT</span><span class="o">=</span><span class="s2">&quot;0&quot;</span>
</pre></div>
</div>
</section>
<section id="distutils-and-setuptools-build-systems">
<h3>distutils and setuptools build systems<a class="headerlink" href="#distutils-and-setuptools-build-systems" title="Link to this heading"></a></h3>
<p>Distutils and setuptools are the two most common build systems
for Python packages right now.  Their common feature is that they use
a <code class="docutils literal notranslate"><span class="pre">setup.py</span></code> script that interfaces with the build system.  Generally,
you can determine which of the two build systems are being used
by looking at the imports in <code class="docutils literal notranslate"><span class="pre">setup.py</span></code>, in particular from which
module the <code class="docutils literal notranslate"><span class="pre">setup</span></code> function is imported.</p>
<p>Distutils-based packages (<code class="docutils literal notranslate"><span class="pre">DISTUTILS_USE_SETUPTOOLS=no</span></code>) use e.g.:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">distutils</span> <span class="kn">import</span> <span class="n">setup</span>
</pre></div>
</div>
<p>Setuptools-based package (<code class="docutils literal notranslate"><span class="pre">DISTUTILS_USE_SETUPTOOLS=bdepend</span></code>, unset
or possibly <code class="docutils literal notranslate"><span class="pre">rdepend</span></code> as indicated by the subsequent sections) use:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">setuptools</span> <span class="kn">import</span> <span class="n">setup</span>
</pre></div>
</div>
<p>In some cases, upstreams find it convenient to alternatively support
both setuptools and distutils.  A commonly used snippet is:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">setuptools</span> <span class="kn">import</span> <span class="n">setup</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">distutils</span> <span class="kn">import</span> <span class="n">setup</span>
</pre></div>
</div>
<p>However, non-fixed build system choice can be problematic to Gentoo
users.  This is because pure distutils installs egg-info data as a
single file, while setuptools install the same data as a directory
(using the same path).  Therefore, if you rebuild the same version
of the package with a different build system than before, you end up
trying to replace a file with a directory or the other way around.
This is not permitted by the PMS and not handled cleanly by the package
managers.</p>
<p>You must always ensure that a single build system will be used
unconditionally.  In the case of the condition presented above, it is
sufficient to leave <code class="docutils literal notranslate"><span class="pre">DISTUTILS_USE_SETUPTOOLS</span></code> at its default value
as that will ensure that setuptools is installed and therefore
the fallback will never take place.  However, patching <code class="docutils literal notranslate"><span class="pre">setup.py</span></code> may
be necessary if you want to force distutils (e.g. to enable clean
bootstrap) or the upstream condition requiers that.</p>
</section>
<section id="setuptools-entry-points">
<h3>Setuptools’ entry points<a class="headerlink" href="#setuptools-entry-points" title="Link to this heading"></a></h3>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>With removal of Python 3.7, the correct <code class="docutils literal notranslate"><span class="pre">DISTUTILS_USE_SETUPTOOLS</span></code>
value for packages using entry points changed to <code class="docutils literal notranslate"><span class="pre">bdepend</span></code>.</p>
</div>
<p><em>Entry points</em> provide the ability to expose some of the package’s
Python functions to other packages.  They are commonly used to implement
plugin systems and by setuptools themselves to implement wrapper scripts
for starting programs.</p>
<p>Entry points are defined as <code class="docutils literal notranslate"><span class="pre">entry_points</span></code> argument to the <code class="docutils literal notranslate"><span class="pre">setup()</span></code>
function, or <code class="docutils literal notranslate"><span class="pre">entry_points</span></code> section in <code class="docutils literal notranslate"><span class="pre">setup.cfg</span></code>.  They are
installed in the package’s egg-info as <code class="docutils literal notranslate"><span class="pre">entry_points.txt</span></code>.  In both
cases, they are grouped by entry point type, and defined as a dictionary
mapping entry points names to the relevant functions.</p>
<p>For our purposes, we are only interested in entry points used to define
wrapper scripts, the <code class="docutils literal notranslate"><span class="pre">console_scripts</span></code> and <code class="docutils literal notranslate"><span class="pre">gui_scripts</span></code> groups,
as they are installed with the package itself.  As for plugin systems,
it is reasonable to assume that the installed plugins are only
meaningful to the package using them, and therefore that the package
using them will depend on the appropriate metadata provider.</p>
<p>Old versions of setuptools used to implement the script wrappers using
<code class="docutils literal notranslate"><span class="pre">pkg_resources</span></code> package.  Modern versions of setuptools use
the following logic:</p>
<ol class="arabic simple">
<li><p>If <code class="docutils literal notranslate"><span class="pre">importlib.metadata</span></code> module is available (Python 3.8+), use it.
In this case, no external dependencies are necessary.</p></li>
<li><p>If <code class="docutils literal notranslate"><span class="pre">importlib_metadata</span></code> backport is available, use it.  It is
provided by <code class="docutils literal notranslate"><span class="pre">dev-python/importlib_metadata</span></code>.</p></li>
<li><p>Otherwise, fall back to <code class="docutils literal notranslate"><span class="pre">pkg_resources</span></code>.  It is provided
by <code class="docutils literal notranslate"><span class="pre">dev-python/setuptools</span></code>.</p></li>
</ol>
<p>Since Python 3.7 is no longer present in Gentoo (we are not considering
PyPy3.7 correctness important for the time being), new ebuilds do not
need any additional dependencies for entry points and should use
the default value (i.e. remove <code class="docutils literal notranslate"><span class="pre">DISTUTILS_USE_SETUPTOOLS</span></code>).</p>
<p>For the time being, the QA check for incorrect values is accepting
both the new value and the old <code class="docutils literal notranslate"><span class="pre">rdepend</span></code> value.  If you wish to be
reminded about the update, you can add the following variable to your
<code class="docutils literal notranslate"><span class="pre">make.conf</span></code>:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="nv">DISTUTILS_STRICT_ENTRY_POINTS</span><span class="o">=</span><span class="m">1</span>
</pre></div>
</div>
<p>Please note that in some cases <code class="docutils literal notranslate"><span class="pre">rdepend</span></code> can still be the correct
value, if there are <a class="reference internal" href="#other-runtime-uses-of-setuptools">other runtime uses of setuptools</a>.  In some cases
the QA check will also trigger the wrong value because of leftover
explicit dependencies on setuptools.</p>
</section>
<section id="other-runtime-uses-of-setuptools">
<h3>Other runtime uses of setuptools<a class="headerlink" href="#other-runtime-uses-of-setuptools" title="Link to this heading"></a></h3>
<p>Besides the generated wrapper scripts, the package code itself may use
the <code class="docutils literal notranslate"><span class="pre">setuptools</span></code> or <code class="docutils literal notranslate"><span class="pre">pkg_resources</span></code> packages.  The common cases
for this include getting package metadata and resource files.  This
could also be a case for plugin managers and derived build systems.</p>
<p>As a rule of thumb, if any installed Python file imports <code class="docutils literal notranslate"><span class="pre">setuptools</span></code>
or <code class="docutils literal notranslate"><span class="pre">pkg_resources</span></code>, the package needs to use the value of <code class="docutils literal notranslate"><span class="pre">rdepend</span></code>.</p>
<p>The QA check determines that this is the case by looking at the upstream
dependencies (<code class="docutils literal notranslate"><span class="pre">install_requires</span></code>) installed by the package.  It is
quite common for packages to miss the dependency, or have a leftover
dependency.  If <code class="docutils literal notranslate"><span class="pre">install_requires</span></code> does not match actual imports
in the installed modules, please submit a patch upstream.</p>
</section>
<section id="pyproject-toml-based-projects">
<h3>pyproject.toml-based projects<a class="headerlink" href="#pyproject-toml-based-projects" title="Link to this heading"></a></h3>
<p>The newer build systems used for Python packages avoid supplying
<code class="docutils literal notranslate"><span class="pre">setup.py</span></code> and instead declare package’s metadata and build system
information in <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code>.  Examples of these build systems
are Flit and Poetry.</p>
<p>These build systems are generally very heavy and do not support plain
installation to a directory.  For this reason, Gentoo is using
<code class="docutils literal notranslate"><span class="pre">dev-python/pyproject2setuppy</span></code> to provide a thin wrapper for
installing these packages using setuptools.</p>
<p>To enable the necessary eclass logic and add appropriate build-time
dependencies, specify the value of <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code>
to <code class="docutils literal notranslate"><span class="pre">DISTUTILS_USE_SETUPTOOLS</span></code>.</p>
<p>Strictly speaking, both Flit and Poetry do support entry points,
and therefore some packages actually need a runtime dependency
on setuptools.  This is a known limitation, and it will probably
not be addressed for the same reason as the logic for setuptools’ entry
points is not updated.</p>
</section>
</section>
<section id="in-source-vs-out-of-source-builds">
<span id="index-1"></span><h2>In-source vs out-of-source builds<a class="headerlink" href="#in-source-vs-out-of-source-builds" title="Link to this heading"></a></h2>
<p>In the general definition, an <em>out-of-source build</em> is a build where
output files are placed in a directory separate from source files.
By default, distutils and its derivatives always do out-of-source builds
and place output files in subdirectories of <code class="docutils literal notranslate"><span class="pre">build</span></code> directory.</p>
<p>Conversely, an <em>in-source build</em> happens when the output files are
interspersed with source files.  The closest distutils equivalent
of an in-source build is the <code class="docutils literal notranslate"><span class="pre">--inplace</span></code> option of <code class="docutils literal notranslate"><span class="pre">build_ext</span></code>
that places compiled C extensions alongside Python module sources.</p>
<p><code class="docutils literal notranslate"><span class="pre">distutils-r1</span></code> shifts this concept a little.  When performing
an out-of-source build (the default), it creates a dedicated output
directory for every Python interpreter enabled, and then uses it
throughout all build and install steps.</p>
<p>It should be noted that unlike build systems such as autotools or CMake,
out-of-source builds in distutils are not executed from the build
directory.  Instead, the setup script is executed from source directory
and passed path to build directory.</p>
<p>Sometimes out-of-source builds are incompatible with custom hacks used
upstream.  This could be a case if the setup script is writing
implementation-specific changes to the source files (e.g. using <code class="docutils literal notranslate"><span class="pre">2to3</span></code>
to convert them to Python 3) or relying on specific build paths.
For better compatibility with those cases, the eclass provides
an in-source build mode enabled via <code class="docutils literal notranslate"><span class="pre">DISTUTILS_IN_SOURCE_BUILD</span></code>.</p>
<p>In this mode, the eclass creates a separate copy of the source directory
for each Python implementation, and then runs the build and install
steps inside that copy.  As a result, any changes done to the source
files are contained within the copy used for the current interpreter.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="c1"># Copyright 1999-2020 Gentoo Authors</span>
<span class="w"> </span><span class="c1"># Distributed under the terms of the GNU General Public License v2</span>

<span class="w"> </span><span class="nv">EAPI</span><span class="o">=</span><span class="m">7</span>
<span class="w"> </span><span class="nv">DISTUTILS_USE_SETUPTOOLS</span><span class="o">=</span>no
<span class="w"> </span><span class="nv">PYTHON_COMPAT</span><span class="o">=(</span><span class="w"> </span>python3_<span class="o">{</span><span class="m">6</span>,7,8<span class="o">}</span><span class="w"> </span>pypy3<span class="w"> </span><span class="o">)</span>
<span class="w"> </span><span class="nv">PYTHON_REQ_USE</span><span class="o">=</span><span class="s2">&quot;xml(+)&quot;</span>

<span class="w"> </span>inherit<span class="w"> </span>distutils-r1

<span class="w"> </span><span class="nv">DESCRIPTION</span><span class="o">=</span><span class="s2">&quot;Collection of extensions to Distutils&quot;</span>
<span class="w"> </span><span class="nv">HOMEPAGE</span><span class="o">=</span><span class="s2">&quot;https://github.com/pypa/setuptools https://pypi.org/project/setuptools/&quot;</span>
<span class="w"> </span><span class="nv">SRC_URI</span><span class="o">=</span><span class="s2">&quot;mirror://pypi/</span><span class="si">${</span><span class="nv">PN</span><span class="p">:</span><span class="nv">0</span><span class="p">:</span><span class="nv">1</span><span class="si">}</span><span class="s2">/</span><span class="si">${</span><span class="nv">PN</span><span class="si">}</span><span class="s2">/</span><span class="si">${</span><span class="nv">P</span><span class="si">}</span><span class="s2">.zip&quot;</span>

<span class="w"> </span><span class="nv">LICENSE</span><span class="o">=</span><span class="s2">&quot;MIT&quot;</span>
<span class="w"> </span><span class="nv">SLOT</span><span class="o">=</span><span class="s2">&quot;0&quot;</span>
<span class="w"> </span><span class="nv">KEYWORDS</span><span class="o">=</span><span class="s2">&quot;~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sh ~sparc ~x86 ~x64-cygwin ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris&quot;</span>

<span class="w"> </span><span class="c1"># Force in-source build because build system modifies sources.</span>
<span class="hll"><span class="w"> </span><span class="nv">DISTUTILS_IN_SOURCE_BUILD</span><span class="o">=</span><span class="m">1</span>
</span></pre></div>
</div>
</section>
<section id="installing-the-package-before-testing">
<span id="index-2"></span><h2>Installing the package before testing<a class="headerlink" href="#installing-the-package-before-testing" title="Link to this heading"></a></h2>
<p>The tests are executed in <code class="docutils literal notranslate"><span class="pre">src_test</span></code> phase, after <code class="docutils literal notranslate"><span class="pre">src_compile</span></code>
installed package files into the build directory.  The eclass
automatically adds appropriate <code class="docutils literal notranslate"><span class="pre">PYTHONPATH</span></code> so that the installed
Python modules and extensions are used during testing.  This works
for the majority of packages.</p>
<p>However, some test suites will not work correctly unless the package
has been properly installed via <code class="docutils literal notranslate"><span class="pre">setup.py</span> <span class="pre">install</span></code>.  This may apply
specifically to packages calling their executables that are created
via entry points, various plugin systems or the use of package metadata.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">distutils_install_for_testing</span></code> function runs <code class="docutils literal notranslate"><span class="pre">setup.py</span> <span class="pre">install</span></code>
into a temporary directory, and adds the appropriate paths to <code class="docutils literal notranslate"><span class="pre">PATH</span></code>
and <code class="docutils literal notranslate"><span class="pre">PYTHONPATH</span></code>.</p>
<p>This function currently supports two install layouts:</p>
<ul class="simple">
<li><p>the standard <em>root directory</em> layout that is enabled
via <code class="docutils literal notranslate"><span class="pre">--via-root</span></code>,</p></li>
<li><p>a virtualenv-alike <em>venv</em> layout that is enabled via <code class="docutils literal notranslate"><span class="pre">--via-venv</span></code>.</p></li>
</ul>
<p>The eclass defaults to the root directory layout that is consistent
with the layout used for the actual install.  This ensures that
the package’s scripts are found on <code class="docutils literal notranslate"><span class="pre">PATH</span></code>, and the package metadata
is found via <code class="docutils literal notranslate"><span class="pre">importlib.metadata</span></code> / <code class="docutils literal notranslate"><span class="pre">pkg_resources</span></code>.  It should
be sufficient to resolve the most common test problems.</p>
<p>In some cases, particularly packages that do not preserve <code class="docutils literal notranslate"><span class="pre">PYTHONPATH</span></code>
correctly, the virtualenv-alike layout (<code class="docutils literal notranslate"><span class="pre">--via-venv</span></code>) is better.
Through wrapping the Python interpreter itself, it guarantees that
the packages installed in the test environment are found independently
of <code class="docutils literal notranslate"><span class="pre">PYTHONPATH</span></code> (just like a true venv).  It should cover the few
extreme cases.</p>
<p>In EAPIs prior to 8, an additional legacy <code class="docutils literal notranslate"><span class="pre">--via-home</span></code> layout used
to be supported.  It historically used to be necessary to fix problems
with some packages.  However, the underlying issues probably went away
along with old versions of Python, and the <a class="reference external" href="https://github.com/pypa/setuptools/commit/91213fb2e7eecde9f5d7582de485398f546e7aa8">removal of site.py hack</a>
has broken it for most of the consumers.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>python_test<span class="o">()</span><span class="w"> </span><span class="o">{</span>
<span class="w">    </span>distutils_install_for_testing
<span class="w">    </span>epytest<span class="w"> </span>--no-network
<span class="o">}</span>
</pre></div>
</div>
</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>








<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"><a class="reference internal" href="eclass.html">Choosing between Python eclasses</a></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 current"><a class="current reference internal" href="#">distutils-r1 legacy concepts</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#different-build-system-variations">Different build system variations</a></li>
<li class="toctree-l2"><a class="reference internal" href="#in-source-vs-out-of-source-builds">In-source vs out-of-source builds</a></li>
<li class="toctree-l2"><a class="reference internal" href="#installing-the-package-before-testing">Installing the package before testing</a></li>
</ul>
</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="test.html" title="previous chapter">Tests in Python packages</a></li>
      <li>Next: <a href="pypi.html" title="next chapter">pypi — helper eclass for PyPI archives</a></li>
  </ul></li>
</ul>
</div>
<search id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <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"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>








        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="footer">
      &#169;2020, Michał Górny, license: CC BY 4.0.
      
      |
      Powered by <a href="https://www.sphinx-doc.org/">Sphinx 7.4.7</a>
      &amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
      
      |
      <a href="_sources/distutils-legacy.rst.txt"
          rel="nofollow">Page source</a>
    </div>

    

    
  </body>
</html>