summaryrefslogtreecommitdiff
blob: 8b014f9ae18dde4edce7cb234377988899f68183 (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
<!DOCTYPE html>

<html lang="en">
  <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>QA checks and warnings &#8212; Gentoo Python Guide  documentation</title>
    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
    <link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
    <script src="_static/doctools.js"></script>
    <script src="_static/sphinx_highlight.js"></script>
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="Python package maintenance" href="package-maintenance.html" />
    <link rel="prev" title="Migration guides" href="migration.html" />
   
  <link rel="stylesheet" href="_static/custom.css" type="text/css" />
  
  
  <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />

  </head><body>
  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          

          <div class="body" role="main">
            
  <section id="qa-checks-and-warnings">
<h1>QA checks and warnings<a class="headerlink" href="#qa-checks-and-warnings" title="Permalink to this heading"></a></h1>
<p>This section explains Python-related QA checks and the resulting QA
warnings that can be output while running the package manager or related
tooling.</p>
<section id="improved-qa-warning-reporting-in-portage">
<h2>Improved QA warning reporting in Portage<a class="headerlink" href="#improved-qa-warning-reporting-in-portage" title="Permalink to this heading"></a></h2>
<p>Normally, Portage outputs QA warnings at specific phases of the build
process.  They are usually interspersed with other verbose output,
and they are easy to miss, especially when building multiple packages
in a single batch.</p>
<p>To make them easier to catch, Portage’s elog system can be used
to repeat all the QA warnings once emerge exits.  The required “echo”
module is already enabled by default, however it skips QA warnings
by default.  To change that, set in 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">PORTAGE_ELOG_CLASSES</span><span class="o">=</span><span class="s2">&quot;log warn error qa&quot;</span>
</pre></div>
</div>
<p>For more information on using Portage’s elog system, please refer
to <a class="reference external" href="https://gitweb.gentoo.org/proj/portage.git/tree/cnf/make.conf.example#n330">make.conf.example</a> included in the Portage distribution.</p>
</section>
<section id="compiled-bytecode-related-warnings">
<h2>Compiled bytecode-related warnings<a class="headerlink" href="#compiled-bytecode-related-warnings" title="Permalink to this heading"></a></h2>
<p>To improve performance, the Python interpreter compiles Python sources
into bytecode.  CPython and PyPy3 feature three optimization levels
that impact the bytecode size:</p>
<ol class="arabic simple">
<li><p>no optimizations (the default)</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">-O</span></code> that removes assert statements from code</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">-OO</span></code> that removes assert statements and docstrings</p></li>
</ol>
<p>Normally, the compiled bytecode is stored on disk in <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> files
(historically, Python 2 has also used <code class="docutils literal notranslate"><span class="pre">.pyo</span></code> files).
When these files are present and up-to-date, Python loads
the precompiled bytecode from them rather than creating it from
the source code, improving module loading time.  When they are missing,
Python normally creates them automatically if it has write permissions
to the respective directory.</p>
<p>In Gentoo, we aim for packages to always byte-compile all their Python
files to all supported optimization levels.  Besides improving module
loading performance, it ensures that the Python interpreters will not
attempt to write compiled bytecode themselves, effectively creating
files that are not monitored by the package manager (and therefore e.g.
are not removed when the respective package is uninstalled) or causing
sandbox violations while building other packages.</p>
<p>The Gentoo repository features a QA check to ensure that all installed
Python modules are byte-compiled for all optimization levels supported
by the respective Python interpreter, and that no stray compiled files
exist.  This check is implemented using an auxiliary command found
in <code class="docutils literal notranslate"><span class="pre">app-portage/gpep517-7</span></code> and newer.  This check can also be run
manually (with machine-readable output) using e.g.:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>$ python3.10 -m gpep517 verify-pyc --destdir=/tmp/portage/dev-python/trimesh-3.12.9/image
missing:/usr/lib/python3.10/site-packages/trimesh/resources/templates/__pycache__/blender_boolean.cpython-310.opt-1.pyc:/usr/lib/python3.10/site-packages/trimesh/resources/templates/blender_boolean.py
missing:/usr/lib/python3.10/site-packages/trimesh/resources/templates/__pycache__/blender_boolean.cpython-310.opt-2.pyc:/usr/lib/python3.10/site-packages/trimesh/resources/templates/blender_boolean.py
missing:/usr/lib/python3.10/site-packages/trimesh/resources/templates/__pycache__/blender_boolean.cpython-310.pyc:/usr/lib/python3.10/site-packages/trimesh/resources/templates/blender_boolean.py
</pre></div>
</div>
<section id="modules-are-not-byte-compiled">
<h3>Modules are not byte-compiled<a class="headerlink" href="#modules-are-not-byte-compiled" title="Permalink to this heading"></a></h3>
<p>The most common QA warning that can be noticed while building packages
indicates that at least some of the expected <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> files are missing.
For example:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>* QA Notice: This package installs one or more Python modules that are
* not byte-compiled.
* The following files are missing:
*
*   /usr/lib/python3.10/site-packages/trimesh/resources/templates/__pycache__/blender_boolean.cpython-310.opt-1.pyc
*   /usr/lib/python3.10/site-packages/trimesh/resources/templates/__pycache__/blender_boolean.cpython-310.opt-2.pyc
*   /usr/lib/python3.10/site-packages/trimesh/resources/templates/__pycache__/blender_boolean.cpython-310.pyc

* QA Notice: This package installs one or more Python modules that are
* not byte-compiled.
* The following files are missing:
*
*   /usr/lib/python3.10/site-packages/blueman/__pycache__/Constants.cpython-310.opt-2.pyc
*   /usr/lib/python3.10/site-packages/blueman/__pycache__/DeviceClass.cpython-310.opt-2.pyc
*   /usr/lib/python3.10/site-packages/blueman/__pycache__/Functions.cpython-310.opt-2.pyc
*   /usr/lib/python3.10/site-packages/blueman/__pycache__/Sdp.cpython-310.opt-2.pyc
[...]
</pre></div>
</div>
<p>There are three common causes for these warnings:</p>
<ol class="arabic simple">
<li><p>The package’s build system nor the ebuild do not byte-compile
installed Python modules — the warning lists all optimization levels
for all installed modules.</p></li>
<li><p>The package’s build system byte-compiles installed modules only for
a subset of optimization levels — the warning lists all modules
but only for a subset of levels (the second example in the example
snippet).</p></li>
<li><p>The package installs <code class="docutils literal notranslate"><span class="pre">.py</span></code> files with incorrect syntax that can not
be byte-compiled and usually trigger syntax errors during the install
phase (the first example in the above snippet).</p></li>
</ol>
<p>For the first two cases, the better solution is to patch the respective
build system to perform byte-compilation for all optimization levels.
An acceptable workaround is to call <code class="docutils literal notranslate"><span class="pre">python_optimize</span></code> from the ebuild
(note that in PEP517 mode, distutils-r1 does that unconditionally).</p>
<p>For the third case, the only real solution is to submit a fix upstream
that renames files that do not contain valid Python modules to use
another suffix.  For example, the template triggering the QA warning
in trimesh package could be renamed from <code class="docutils literal notranslate"><span class="pre">.py</span></code> to <code class="docutils literal notranslate"><span class="pre">.py.tmpl</span></code>.</p>
</section>
<section id="stray-compiled-bytecode">
<h3>Stray compiled bytecode<a class="headerlink" href="#stray-compiled-bytecode" title="Permalink to this heading"></a></h3>
<p>The following QA warning indicates that there are stray <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> files
that are not clearly matching any installed Python module-implementation
pair:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>* QA Notice: This package installs one or more compiled Python modules
* that do not match installed modules (or their implementation).
* The following files are stray:
*
*   /usr/lib/python3.10/site-packages/SCons/Tool/docbook/__pycache__/__init__.cpython-35.pyc
*   /usr/lib/python3.10/site-packages/SCons/Tool/docbook/__pycache__/__init__.cpython-36.pyc
*   /usr/lib/python3.10/site-packages/SCons/Tool/docbook/__pycache__/__init__.cpython-38.pyc
</pre></div>
</div>
<p>There are two common causes for this:</p>
<ol class="arabic simple">
<li><p>The package is shipping precompiled <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> files and installing
them along with <code class="docutils literal notranslate"><span class="pre">.py</span></code> modules.  The ebuild should remove the stray
files in <code class="docutils literal notranslate"><span class="pre">src_prepare</span></code> then.</p></li>
<li><p>The ebuild is attempting to remove some <code class="docutils literal notranslate"><span class="pre">.py</span></code> files after they have
been byte-compiled.  It needs to be modified to either remove them
prior to the byte-compilation stage, or to fix the build system
not to install them in the first place.</p></li>
</ol>
</section>
</section>
<section id="stray-top-level-files-in-site-packages">
<h2>Stray top-level files in site-packages<a class="headerlink" href="#stray-top-level-files-in-site-packages" title="Permalink to this heading"></a></h2>
<p>distutils-r1 checks for the common mistake of installing unexpected
files that are installed top-level into the site-packages directory.
An example error due to that looks like the following:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>* The following unexpected files/directories were found top-level
* in the site-packages directory:
*
*   /usr/lib/python3.10/site-packages/README.md
*   /usr/lib/python3.10/site-packages/LICENSE
*   /usr/lib/python3.10/site-packages/CHANGELOG
*
* This is most likely a bug in the build system.  More information
* can be found in the Python Guide:
* https://projects.gentoo.org/python/guide/qawarn.html#stray-top-level-files-in-site-packages
</pre></div>
</div>
<p>In general, it is desirable to prepare a fix for the build system
and submit it upstream.  However, it is acceptable to remove the files
locally in the ebuild while waiting for a release with the fix.</p>
<p>The subsequent sections describe the common causes and the suggested
fixes.</p>
<section id="example-or-test-packages-installed-by-setuptools">
<h3>Example or test packages installed by setuptools<a class="headerlink" href="#example-or-test-packages-installed-by-setuptools" title="Permalink to this heading"></a></h3>
<p>Many packages using the setuptools build system utilize the convenient
<code class="docutils literal notranslate"><span class="pre">find_packages()</span></code> method to locate the Python sources.  In some cases,
this method also wrongly grabs top-level test directories or other files
that were not intended to be installed.</p>
<p>For example, the following invocation will install everything that looks
like a Python package from the source tree:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">setup</span><span class="p">(</span>
    <span class="n">packages</span><span class="o">=</span><span class="n">find_packages</span><span class="p">())</span>
</pre></div>
</div>
<p>The correct fix for this problem is to add an <code class="docutils literal notranslate"><span class="pre">exclude</span></code> parameter
that restricts the installed package list, for example:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">setup</span><span class="p">(</span>
    <span class="n">packages</span><span class="o">=</span><span class="n">find_packages</span><span class="p">(</span><span class="n">exclude</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;tests&quot;</span><span class="p">,</span> <span class="s2">&quot;tests.*&quot;</span><span class="p">]))</span>
</pre></div>
</div>
<p>Note that if the top-level <code class="docutils literal notranslate"><span class="pre">tests</span></code> package has any subpackages, both
<code class="docutils literal notranslate"><span class="pre">tests</span></code> and <code class="docutils literal notranslate"><span class="pre">tests.*</span></code> need to be listed.</p>
<p>If <code class="docutils literal notranslate"><span class="pre">setup.cfg</span></code> is used instead, the excludes are specified as follows:</p>
<div class="highlight-ini notranslate"><div class="highlight"><pre><span></span><span class="k">[options.packages.find]</span>
<span class="na">exclude</span><span class="w"> </span><span class="o">=</span>
<span class="w">    </span><span class="na">tests</span>
<span class="w">    </span><span class="na">tests.*</span>
</pre></div>
</div>
<p>If <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> is used:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="k">[tool.setuptools.packages.find]</span>
<span class="n">exclude</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span>
<span class="w">    </span><span class="s">&quot;tests&quot;</span><span class="p">,</span>
<span class="w">    </span><span class="s">&quot;tests.*&quot;</span><span class="p">,</span>
<span class="p">]</span>
</pre></div>
</div>
<p>For reference, see <a class="reference external" href="https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#custom-discovery">custom discovery in setuptools documentation</a>.</p>
</section>
<section id="documentation-files-installed-by-poetry">
<h3>Documentation files installed by Poetry<a class="headerlink" href="#documentation-files-installed-by-poetry" title="Permalink to this heading"></a></h3>
<p>It is a relatively common problem that packages using the Poetry build
system are installing documentation files (such as <code class="docutils literal notranslate"><span class="pre">README</span></code>)
to the site-packages directory.  This is because of incorrect
<code class="docutils literal notranslate"><span class="pre">include</span></code> use in <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code>.  For example, consider
the following configuration:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="n">include</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span>
<span class="w">    </span><span class="s">&quot;CHANGELOG&quot;</span><span class="p">,</span>
<span class="w">    </span><span class="s">&quot;README.md&quot;</span><span class="p">,</span>
<span class="w">    </span><span class="s">&quot;LICENSE&quot;</span>
<span class="p">]</span>
</pre></div>
</div>
<p>The author meant to include these files in the source distribution
packages.  However, the <code class="docutils literal notranslate"><span class="pre">include</span></code> key applies to wheels as well,
effectively including them in files installed into <code class="docutils literal notranslate"><span class="pre">site-packages</span></code>.</p>
<p>To fix that, you need to specify file formats explicitly, for every
entry:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="n">include</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="w"> </span><span class="n">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;CHANGELOG&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">format</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;sdist&quot;</span><span class="w"> </span><span class="p">},</span>
<span class="w">    </span><span class="p">{</span><span class="w"> </span><span class="n">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;README.md&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">format</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;sdist&quot;</span><span class="w"> </span><span class="p">},</span>
<span class="w">    </span><span class="p">{</span><span class="w"> </span><span class="n">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;LICENSE&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">format</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;sdist&quot;</span><span class="w"> </span><span class="p">},</span>
<span class="p">]</span>
</pre></div>
</div>
<p>For reference, see <a class="reference external" href="https://python-poetry.org/docs/pyproject/#include-and-exclude">include and exclude in Poetry documentation</a>.</p>
</section>
</section>
<section id="deprecated-pep-517-backends">
<h2>Deprecated PEP 517 backends<a class="headerlink" href="#deprecated-pep-517-backends" title="Permalink to this heading"></a></h2>
<section id="flit-buildapi">
<h3>flit.buildapi<a class="headerlink" href="#flit-buildapi" title="Permalink to this heading"></a></h3>
<p>Some packages are still found using the historical flit build backend.
Their <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> files contain a section similar
to the following:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="k">[build-system]</span>
<span class="n">requires</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">&quot;flit&quot;</span><span class="p">]</span>
<span class="n">build-backend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;flit.buildapi&quot;</span>
</pre></div>
</div>
<p>This backend requires installing the complete flit package manager.
Instead, the package should be fixed upstream to use flit_core
per <a class="reference external" href="https://flit.readthedocs.io/en/latest/pyproject_toml.html#build-system-section">flit build system section documentation</a> instead:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="k">[build-system]</span>
<span class="n">requires</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">&quot;flit_core&quot;</span><span class="p">]</span>
<span class="n">build-backend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;flit_core.buildapi&quot;</span>
</pre></div>
</div>
<p>flit_core produces identical artifacts to flit.  At the same time, it
reduces the build-time dependency footprint and therefore makes isolated
PEP 517 builds faster.</p>
</section>
<section id="poetry-masonry-api">
<h3>poetry.masonry.api<a class="headerlink" href="#poetry-masonry-api" title="Permalink to this heading"></a></h3>
<p>A similar problem applies to the packages using poetry.  The respective
<code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> files contain:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="k">[build-system]</span>
<span class="n">requires</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">&quot;poetry&gt;=0.12&quot;</span><span class="p">]</span>
<span class="n">build-backend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;poetry.masonry.api&quot;</span>
</pre></div>
</div>
<p>Instead, the lightweight poetry-core module should be used per <a class="reference external" href="https://python-poetry.org/docs/pyproject/#poetry-and-pep-517">poetry
PEP-517 documentation</a>:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="k">[build-system]</span>
<span class="n">requires</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">&quot;poetry_core&gt;=1.0.0&quot;</span><span class="p">]</span>
<span class="n">build-backend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;poetry.core.masonry.api&quot;</span>
</pre></div>
</div>
<p>poetry-core produces identical artifacts to poetry.  It has smaller
dependency footprint and makes isolated builds much faster.</p>
</section>
<section id="setuptools-build-meta-legacy">
<h3>setuptools.build_meta:__legacy__<a class="headerlink" href="#setuptools-build-meta-legacy" title="Permalink to this heading"></a></h3>
<p>Some packages using setuptools specify the following:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="k">[build-system]</span>
<span class="n">requires</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">&quot;setuptools&gt;=40.8.0&quot;</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;wheel&quot;</span><span class="p">]</span>
<span class="n">build-backend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;setuptools.build_meta:__legacy__&quot;</span>
</pre></div>
</div>
<p>This is incorrect, as the legacy backend is intended to be used only
as an implicit fallback.  All packages should be using the regular
backend instead:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="k">[build-system]</span>
<span class="n">requires</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s">&quot;setuptools&gt;=40.8.0&quot;</span><span class="p">]</span>
<span class="n">build-backend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;setuptools.build_meta&quot;</span>
</pre></div>
</div>
<p>Please also note that the <code class="docutils literal notranslate"><span class="pre">wheel</span></code> package should <em>not</em> be listed
as a dependency, as it is an implementation detail and it was always
implicitly returned by the backend.  Unfortunately, due to prolonged
documentation error, a very large number of packages still specifies it,
and other packages tend to copy that mistake.</p>
</section>
</section>
</section>


          </div>
          
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <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"><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 current"><a class="current reference internal" href="#">QA checks and warnings</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#improved-qa-warning-reporting-in-portage">Improved QA warning reporting in Portage</a></li>
<li class="toctree-l2"><a class="reference internal" href="#compiled-bytecode-related-warnings">Compiled bytecode-related warnings</a></li>
<li class="toctree-l2"><a class="reference internal" href="#stray-top-level-files-in-site-packages">Stray top-level files in site-packages</a></li>
<li class="toctree-l2"><a class="reference internal" href="#deprecated-pep-517-backends">Deprecated PEP 517 backends</a></li>
</ul>
</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="migration.html" title="previous chapter">Migration guides</a></li>
      <li>Next: <a href="package-maintenance.html" title="next chapter">Python package maintenance</a></li>
  </ul></li>
</ul>
</div>
<div 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>
</div>
<script>document.getElementById('searchbox').style.display = "block"</script>








        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="footer">
      &copy;2020, Michał Górny, license: CC BY 4.0.
      
      |
      Powered by <a href="http://sphinx-doc.org/">Sphinx 7.0.1</a>
      &amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.13</a>
      
      |
      <a href="_sources/qawarn.rst.txt"
          rel="nofollow">Page source</a>
    </div>

    

    
  </body>
</html>