1# Python {#python}
2
3## Reference {#reference}
4
5### Interpreters {#interpreters}
6
7| Package | Aliases | Interpreter |
8|------------|-----------------|-------------|
9| python27 | python2, python | CPython 2.7 |
10| python39 | | CPython 3.9 |
11| python310 | | CPython 3.10 |
12| python311 | python3 | CPython 3.11 |
13| python312 | | CPython 3.12 |
14| python313 | | CPython 3.13 |
15| pypy27 | pypy2, pypy | PyPy2.7 |
16| pypy39 | pypy3 | PyPy 3.9 |
17
18The Nix expressions for the interpreters can be found in
19`pkgs/development/interpreters/python`.
20
21All packages depending on any Python interpreter get appended
22`out/{python.sitePackages}` to `$PYTHONPATH` if such directory
23exists.
24
25#### Missing `tkinter` module standard library {#missing-tkinter-module-standard-library}
26
27To reduce closure size the `Tkinter`/`tkinter` is available as a separate package, `pythonPackages.tkinter`.
28
29#### Attributes on interpreters packages {#attributes-on-interpreters-packages}
30
31Each interpreter has the following attributes:
32
33- `libPrefix`. Name of the folder in `${python}/lib/` for corresponding interpreter.
34- `interpreter`. Alias for `${python}/bin/${executable}`.
35- `buildEnv`. Function to build python interpreter environments with extra packages bundled together. See [](#python.buildenv-function) for usage and documentation.
36- `withPackages`. Simpler interface to `buildEnv`. See [](#python.withpackages-function) for usage and documentation.
37- `sitePackages`. Alias for `lib/${libPrefix}/site-packages`.
38- `executable`. Name of the interpreter executable, e.g. `python3.10`.
39- `pkgs`. Set of Python packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing `packageOverrides`.
40
41### Building packages and applications {#building-packages-and-applications}
42
43Python libraries and applications that use `setuptools` or
44`distutils` are typically built with respectively the [`buildPythonPackage`](#buildpythonpackage-function) and
45[`buildPythonApplication`](#buildpythonapplication-function) functions. These two functions also support installing a `wheel`.
46
47All Python packages reside in `pkgs/top-level/python-packages.nix` and all
48applications elsewhere. In case a package is used as both a library and an
49application, then the package should be in `pkgs/top-level/python-packages.nix`
50since only those packages are made available for all interpreter versions. The
51preferred location for library expressions is in
52`pkgs/development/python-modules`. It is important that these packages are
53called from `pkgs/top-level/python-packages.nix` and not elsewhere, to guarantee
54the right version of the package is built.
55
56Based on the packages defined in `pkgs/top-level/python-packages.nix` an
57attribute set is created for each available Python interpreter. The available
58sets are
59
60* `pkgs.python27Packages`
61* `pkgs.python3Packages`
62* `pkgs.python39Packages`
63* `pkgs.python310Packages`
64* `pkgs.python311Packages`
65* `pkgs.python312Packages`
66* `pkgs.python313Packages`
67* `pkgs.pypyPackages`
68
69and the aliases
70
71* `pkgs.python2Packages` pointing to `pkgs.python27Packages`
72* `pkgs.python3Packages` pointing to `pkgs.python311Packages`
73* `pkgs.pythonPackages` pointing to `pkgs.python2Packages`
74
75#### `buildPythonPackage` function {#buildpythonpackage-function}
76
77The `buildPythonPackage` function has its name binding in
78`pkgs/development/interpreters/python/python-packages-base.nix` and is
79implemented in `pkgs/development/interpreters/python/mk-python-derivation.nix`
80using setup hooks.
81
82The following is an example:
83
84```nix
85{ lib
86, buildPythonPackage
87, fetchPypi
88
89# build-system
90, setuptools-scm
91
92# dependencies
93, attrs
94, pluggy
95, py
96, setuptools
97, six
98
99# tests
100, hypothesis
101 }:
102
103buildPythonPackage rec {
104 pname = "pytest";
105 version = "3.3.1";
106 pyproject = true;
107
108 src = fetchPypi {
109 inherit pname version;
110 hash = "sha256-z4Q23FnYaVNG/NOrKW3kZCXsqwDWQJbOvnn7Ueyy65M=";
111 };
112
113 postPatch = ''
114 # don't test bash builtins
115 rm testing/test_argcomplete.py
116 '';
117
118 build-system = [
119 setuptools-scm
120 ];
121
122 dependencies = [
123 attrs
124 py
125 setuptools
126 six
127 pluggy
128 ];
129
130 nativeCheckInputs = [
131 hypothesis
132 ];
133
134 meta = {
135 changelog = "https://github.com/pytest-dev/pytest/releases/tag/${version}";
136 description = "Framework for writing tests";
137 homepage = "https://github.com/pytest-dev/pytest";
138 license = lib.licenses.mit;
139 maintainers = with lib.maintainers; [ domenkozar lovek323 madjar lsix ];
140 };
141}
142```
143
144The `buildPythonPackage` mainly does four things:
145
146* In the [`buildPhase`](#build-phase), it calls `${python.pythonOnBuildForHost.interpreter} setup.py bdist_wheel` to
147 build a wheel binary zipfile.
148* In the [`installPhase`](#ssec-install-phase), it installs the wheel file using `pip install *.whl`.
149* In the [`postFixup`](#var-stdenv-postFixup) phase, the `wrapPythonPrograms` bash function is called to
150 wrap all programs in the `$out/bin/*` directory to include `$PATH`
151 environment variable and add dependent libraries to script's `sys.path`.
152* In the [`installCheck`](#ssec-installCheck-phase) phase, `${python.interpreter} setup.py test` is run.
153
154By default tests are run because [`doCheck = true`](#var-stdenv-doCheck). Test dependencies, like
155e.g. the test runner, should be added to [`nativeCheckInputs`](#var-stdenv-nativeCheckInputs).
156
157By default `meta.platforms` is set to the same value
158as the interpreter unless overridden otherwise.
159
160##### `buildPythonPackage` parameters {#buildpythonpackage-parameters}
161
162All parameters from [`stdenv.mkDerivation`](#sec-using-stdenv) function are still supported. The
163following are specific to `buildPythonPackage`:
164
165* `catchConflicts ? true`: If `true`, abort package build if a package name
166 appears more than once in dependency tree. Default is `true`.
167* `disabled ? false`: If `true`, package is not built for the particular Python
168 interpreter version.
169* `dontWrapPythonPrograms ? false`: Skip wrapping of Python programs.
170* `permitUserSite ? false`: Skip setting the `PYTHONNOUSERSITE` environment
171 variable in wrapped programs.
172* `pyproject`: Whether the pyproject format should be used. When set to `true`,
173 `pypaBuildHook` will be used, and you can add the required build dependencies
174 from `build-system.requires` to `build-system`. Note that the pyproject
175 format falls back to using `setuptools`, so you can use `pyproject = true`
176 even if the package only has a `setup.py`. When set to `false`, you can
177 use the existing [hooks](#setup-hooks) or provide your own logic to build the
178 package. This can be useful for packages that don't support the pyproject
179 format. When unset, the legacy `setuptools` hooks are used for backwards
180 compatibility.
181* `makeWrapperArgs ? []`: A list of strings. Arguments to be passed to
182 [`makeWrapper`](#fun-makeWrapper), which wraps generated binaries. By default, the arguments to
183 [`makeWrapper`](#fun-makeWrapper) set `PATH` and `PYTHONPATH` environment variables before calling
184 the binary. Additional arguments here can allow a developer to set environment
185 variables which will be available when the binary is run. For example,
186 `makeWrapperArgs = ["--set FOO BAR" "--set BAZ QUX"]`.
187* `namePrefix`: Prepends text to `${name}` parameter. In case of libraries, this
188 defaults to `"python3.8-"` for Python 3.8, etc., and in case of applications to `""`.
189* `pipInstallFlags ? []`: A list of strings. Arguments to be passed to `pip
190 install`. To pass options to `python setup.py install`, use
191 `--install-option`. E.g., `pipInstallFlags=["--install-option='--cpp_implementation'"]`.
192* `pipBuildFlags ? []`: A list of strings. Arguments to be passed to `pip wheel`.
193* `pypaBuildFlags ? []`: A list of strings. Arguments to be passed to `python -m build --wheel`.
194* `pythonPath ? []`: List of packages to be added into `$PYTHONPATH`. Packages
195 in `pythonPath` are not propagated (contrary to [`propagatedBuildInputs`](#var-stdenv-propagatedBuildInputs)).
196* `preShellHook`: Hook to execute commands before `shellHook`.
197* `postShellHook`: Hook to execute commands after `shellHook`.
198* `removeBinByteCode ? true`: Remove bytecode from `/bin`. Bytecode is only
199 created when the filenames end with `.py`.
200* `setupPyGlobalFlags ? []`: List of flags passed to `setup.py` command.
201* `setupPyBuildFlags ? []`: List of flags passed to `setup.py build_ext` command.
202
203The [`stdenv.mkDerivation`](#sec-using-stdenv) function accepts various parameters for describing
204build inputs (see "Specifying dependencies"). The following are of special
205interest for Python packages, either because these are primarily used, or
206because their behaviour is different:
207
208* `nativeBuildInputs ? []`: Build-time only dependencies. Typically executables.
209* `build-system ? []`: Build-time only Python dependencies. Items listed in `build-system.requires`/`setup_requires`.
210* `buildInputs ? []`: Build and/or run-time dependencies that need to be
211 compiled for the host machine. Typically non-Python libraries which are being
212 linked.
213* `nativeCheckInputs ? []`: Dependencies needed for running the [`checkPhase`](#ssec-check-phase). These
214 are added to [`nativeBuildInputs`](#var-stdenv-nativeBuildInputs) when [`doCheck = true`](#var-stdenv-doCheck). Items listed in
215 `tests_require` go here.
216* `dependencies ? []`: Aside from propagating dependencies,
217 `buildPythonPackage` also injects code into and wraps executables with the
218 paths included in this list. Items listed in `install_requires` go here.
219* `optional-dependencies ? { }`: Optional feature flagged dependencies. Items listed in `extras_requires` go here.
220
221Aside from propagating dependencies,
222 `buildPythonPackage` also injects code into and wraps executables with the
223 paths included in this list. Items listed in `extras_requires` go here.
224
225##### Overriding Python packages {#overriding-python-packages}
226
227The `buildPythonPackage` function has a `overridePythonAttrs` method that can be
228used to override the package. In the following example we create an environment
229where we have the `blaze` package using an older version of `pandas`. We
230override first the Python interpreter and pass `packageOverrides` which contains
231the overrides for packages in the package set.
232
233```nix
234with import <nixpkgs> {};
235
236(let
237 python = let
238 packageOverrides = self: super: {
239 pandas = super.pandas.overridePythonAttrs(old: rec {
240 version = "0.19.1";
241 src = fetchPypi {
242 pname = "pandas";
243 inherit version;
244 hash = "sha256-JQn+rtpy/OA2deLszSKEuxyttqBzcAil50H+JDHUdCE=";
245 };
246 });
247 };
248 in pkgs.python3.override {inherit packageOverrides; self = python;};
249
250in python.withPackages(ps: [ ps.blaze ])).env
251```
252
253The next example shows a non trivial overriding of the `blas` implementation to
254be used through out all of the Python package set:
255
256```nix
257{
258 python3MyBlas = pkgs.python3.override {
259 packageOverrides = self: super: {
260 # We need toPythonModule for the package set to evaluate this
261 blas = super.toPythonModule(super.pkgs.blas.override {
262 blasProvider = super.pkgs.mkl;
263 });
264 lapack = super.toPythonModule(super.pkgs.lapack.override {
265 lapackProvider = super.pkgs.mkl;
266 });
267 };
268 };
269}
270```
271
272This is particularly useful for numpy and scipy users who want to gain speed with other blas implementations.
273Note that using `scipy = super.scipy.override { blas = super.pkgs.mkl; };` will likely result in
274compilation issues, because scipy dependencies need to use the same blas implementation as well.
275
276#### `buildPythonApplication` function {#buildpythonapplication-function}
277
278The [`buildPythonApplication`](#buildpythonapplication-function) function is practically the same as
279[`buildPythonPackage`](#buildpythonpackage-function). The main purpose of this function is to build a Python
280package where one is interested only in the executables, and not importable
281modules. For that reason, when adding this package to a [`python.buildEnv`](#python.buildenv-function), the
282modules won't be made available.
283
284Another difference is that [`buildPythonPackage`](#buildpythonpackage-function) by default prefixes the names of
285the packages with the version of the interpreter. Because this is irrelevant for
286applications, the prefix is omitted.
287
288When packaging a Python application with [`buildPythonApplication`](#buildpythonapplication-function), it should be
289called with `callPackage` and passed `python3` or `python3Packages` (possibly
290specifying an interpreter version), like this:
291
292```nix
293{ lib
294, python3Packages
295, fetchPypi
296}:
297
298python3Packages.buildPythonApplication rec {
299 pname = "luigi";
300 version = "2.7.9";
301 pyproject = true;
302
303 src = fetchPypi {
304 inherit pname version;
305 hash = "sha256-Pe229rT0aHwA98s+nTHQMEFKZPo/yw6sot8MivFDvAw=";
306 };
307
308 build-system = with python3Packages; [
309 setuptools
310 wheel
311 ];
312
313 dependencies = with python3Packages; [
314 tornado
315 python-daemon
316 ];
317
318 meta = {
319 # ...
320 };
321}
322```
323
324This is then added to `all-packages.nix` just as any other application would be.
325
326```nix
327{
328 luigi = callPackage ../applications/networking/cluster/luigi { };
329}
330```
331
332Since the package is an application, a consumer doesn't need to care about
333Python versions or modules, which is why they don't go in `python3Packages`.
334
335#### `toPythonApplication` function {#topythonapplication-function}
336
337A distinction is made between applications and libraries, however, sometimes a
338package is used as both. In this case the package is added as a library to
339`python-packages.nix` and as an application to `all-packages.nix`. To reduce
340duplication the `toPythonApplication` can be used to convert a library to an
341application.
342
343The Nix expression shall use [`buildPythonPackage`](#buildpythonpackage-function) and be called from
344`python-packages.nix`. A reference shall be created from `all-packages.nix` to
345the attribute in `python-packages.nix`, and the `toPythonApplication` shall be
346applied to the reference:
347
348```nix
349{
350 youtube-dl = with python3Packages; toPythonApplication youtube-dl;
351}
352```
353
354#### `toPythonModule` function {#topythonmodule-function}
355
356In some cases, such as bindings, a package is created using
357[`stdenv.mkDerivation`](#sec-using-stdenv) and added as attribute in `all-packages.nix`. The Python
358bindings should be made available from `python-packages.nix`. The
359`toPythonModule` function takes a derivation and makes certain Python-specific
360modifications.
361
362```nix
363{
364 opencv = toPythonModule (pkgs.opencv.override {
365 enablePython = true;
366 pythonPackages = self;
367 });
368}
369```
370
371Do pay attention to passing in the right Python version!
372
373#### `python.buildEnv` function {#python.buildenv-function}
374
375Python environments can be created using the low-level `pkgs.buildEnv` function.
376This example shows how to create an environment that has the Pyramid Web Framework.
377Saving the following as `default.nix`
378
379```nix
380with import <nixpkgs> {};
381
382python3.buildEnv.override {
383 extraLibs = [ python3Packages.pyramid ];
384 ignoreCollisions = true;
385}
386```
387
388and running `nix-build` will create
389
390```
391/nix/store/cf1xhjwzmdki7fasgr4kz6di72ykicl5-python-2.7.8-env
392```
393
394with wrapped binaries in `bin/`.
395
396You can also use the `env` attribute to create local environments with needed
397packages installed. This is somewhat comparable to `virtualenv`. For example,
398running `nix-shell` with the following `shell.nix`
399
400```nix
401with import <nixpkgs> {};
402
403(python3.buildEnv.override {
404 extraLibs = with python3Packages; [
405 numpy
406 requests
407 ];
408}).env
409```
410
411will drop you into a shell where Python will have the
412specified packages in its path.
413
414##### `python.buildEnv` arguments {#python.buildenv-arguments}
415
416
417* `extraLibs`: List of packages installed inside the environment.
418* `postBuild`: Shell command executed after the build of environment.
419* `ignoreCollisions`: Ignore file collisions inside the environment (default is `false`).
420* `permitUserSite`: Skip setting the `PYTHONNOUSERSITE` environment variable in
421 wrapped binaries in the environment.
422
423#### `python.withPackages` function {#python.withpackages-function}
424
425The [`python.withPackages`](#python.withpackages-function) function provides a simpler interface to the [`python.buildEnv`](#python.buildenv-function) functionality.
426It takes a function as an argument that is passed the set of python packages and returns the list
427of the packages to be included in the environment. Using the [`withPackages`](#python.withpackages-function) function, the previous
428example for the Pyramid Web Framework environment can be written like this:
429
430```nix
431with import <nixpkgs> {};
432
433python.withPackages (ps: [ ps.pyramid ])
434```
435
436[`withPackages`](#python.withpackages-function) passes the correct package set for the specific interpreter
437version as an argument to the function. In the above example, `ps` equals
438`pythonPackages`. But you can also easily switch to using python3:
439
440```nix
441with import <nixpkgs> {};
442
443python3.withPackages (ps: [ ps.pyramid ])
444```
445
446Now, `ps` is set to `python3Packages`, matching the version of the interpreter.
447
448As [`python.withPackages`](#python.withpackages-function) uses [`python.buildEnv`](#python.buildenv-function) under the hood, it also
449supports the `env` attribute. The `shell.nix` file from the previous section can
450thus be also written like this:
451
452```nix
453with import <nixpkgs> {};
454
455(python3.withPackages (ps: with ps; [
456 numpy
457 requests
458])).env
459```
460
461In contrast to [`python.buildEnv`](#python.buildenv-function), [`python.withPackages`](#python.withpackages-function) does not support the
462more advanced options such as `ignoreCollisions = true` or `postBuild`. If you
463need them, you have to use [`python.buildEnv`](#python.buildenv-function).
464
465Python 2 namespace packages may provide `__init__.py` that collide. In that case
466[`python.buildEnv`](#python.buildenv-function) should be used with `ignoreCollisions = true`.
467
468#### Setup hooks {#setup-hooks}
469
470The following are setup hooks specifically for Python packages. Most of these
471are used in [`buildPythonPackage`](#buildpythonpackage-function).
472
473- `eggUnpackhook` to move an egg to the correct folder so it can be installed
474 with the `eggInstallHook`
475- `eggBuildHook` to skip building for eggs.
476- `eggInstallHook` to install eggs.
477- `pipBuildHook` to build a wheel using `pip` and PEP 517. Note a build system
478 (e.g. `setuptools` or `flit`) should still be added as `build-system`.
479- `pypaBuildHook` to build a wheel using
480 [`pypa/build`](https://pypa-build.readthedocs.io/en/latest/index.html) and
481 PEP 517/518. Note a build system (e.g. `setuptools` or `flit`) should still
482 be added as `build-system`.
483- `pipInstallHook` to install wheels.
484- `pytestCheckHook` to run tests with `pytest`. See [example usage](#using-pytestcheckhook).
485- `pythonCatchConflictsHook` to fail if the package depends on two different versions of the same dependency.
486- `pythonImportsCheckHook` to check whether importing the listed modules works.
487- `pythonRelaxDepsHook` will relax Python dependencies restrictions for the package.
488 See [example usage](#using-pythonrelaxdepshook).
489- `pythonRemoveBinBytecode` to remove bytecode from the `/bin` folder.
490- `setuptoolsBuildHook` to build a wheel using `setuptools`.
491- `setuptoolsCheckHook` to run tests with `python setup.py test`.
492- `sphinxHook` to build documentation and manpages using Sphinx.
493- `venvShellHook` to source a Python 3 `venv` at the `venvDir` location. A
494 `venv` is created if it does not yet exist. `postVenvCreation` can be used to
495 to run commands only after venv is first created.
496- `wheelUnpackHook` to move a wheel to the correct folder so it can be installed
497 with the `pipInstallHook`.
498- `unittestCheckHook` will run tests with `python -m unittest discover`. See [example usage](#using-unittestcheckhook).
499
500## User Guide {#user-guide}
501
502### Using Python {#using-python}
503
504#### Overview {#overview}
505
506Several versions of the Python interpreter are available on Nix, as well as a
507high amount of packages. The attribute `python3` refers to the default
508interpreter, which is currently CPython 3.11. The attribute `python` refers to
509CPython 2.7 for backwards-compatibility. It is also possible to refer to
510specific versions, e.g. `python311` refers to CPython 3.11, and `pypy` refers to
511the default PyPy interpreter.
512
513Python is used a lot, and in different ways. This affects also how it is
514packaged. In the case of Python on Nix, an important distinction is made between
515whether the package is considered primarily an application, or whether it should
516be used as a library, i.e., of primary interest are the modules in
517`site-packages` that should be importable.
518
519In the Nixpkgs tree Python applications can be found throughout, depending on
520what they do, and are called from the main package set. Python libraries,
521however, are in separate sets, with one set per interpreter version.
522
523The interpreters have several common attributes. One of these attributes is
524`pkgs`, which is a package set of Python libraries for this specific
525interpreter. E.g., the `toolz` package corresponding to the default interpreter
526is `python3.pkgs.toolz`, and the CPython 3.11 version is `python311.pkgs.toolz`.
527The main package set contains aliases to these package sets, e.g.
528`pythonPackages` refers to `python.pkgs` and `python311Packages` to
529`python311.pkgs`.
530
531#### Installing Python and packages {#installing-python-and-packages}
532
533The Nix and NixOS manuals explain how packages are generally installed. In the
534case of Python and Nix, it is important to make a distinction between whether the
535package is considered an application or a library.
536
537Applications on Nix are typically installed into your user profile imperatively
538using `nix-env -i`, and on NixOS declaratively by adding the package name to
539`environment.systemPackages` in `/etc/nixos/configuration.nix`. Dependencies
540such as libraries are automatically installed and should not be installed
541explicitly.
542
543The same goes for Python applications. Python applications can be installed in
544your profile, and will be wrapped to find their exact library dependencies,
545without impacting other applications or polluting your user environment.
546
547But Python libraries you would like to use for development cannot be installed,
548at least not individually, because they won't be able to find each other
549resulting in import errors. Instead, it is possible to create an environment
550with [`python.buildEnv`](#python.buildenv-function) or [`python.withPackages`](#python.withpackages-function) where the interpreter and other
551executables are wrapped to be able to find each other and all of the modules.
552
553In the following examples we will start by creating a simple, ad-hoc environment
554with a nix-shell that has `numpy` and `toolz` in Python 3.11; then we will create
555a re-usable environment in a single-file Python script; then we will create a
556full Python environment for development with this same environment.
557
558Philosophically, this should be familiar to users who are used to a `venv` style
559of development: individual projects create their own Python environments without
560impacting the global environment or each other.
561
562#### Ad-hoc temporary Python environment with `nix-shell` {#ad-hoc-temporary-python-environment-with-nix-shell}
563
564The simplest way to start playing with the way nix wraps and sets up Python
565environments is with `nix-shell` at the cmdline. These environments create a
566temporary shell session with a Python and a *precise* list of packages (plus
567their runtime dependencies), with no other Python packages in the Python
568interpreter's scope.
569
570To create a Python 3.11 session with `numpy` and `toolz` available, run:
571
572```sh
573$ nix-shell -p 'python311.withPackages(ps: with ps; [ numpy toolz ])'
574```
575
576By default `nix-shell` will start a `bash` session with this interpreter in our
577`PATH`, so if we then run:
578
579```Python console
580[nix-shell:~/src/nixpkgs]$ python3
581Python 3.11.3 (main, Apr 4 2023, 22:36:41) [GCC 12.2.0] on linux
582Type "help", "copyright", "credits" or "license" for more information.
583>>> import numpy; import toolz
584```
585
586Note that no other modules are in scope, even if they were imperatively
587installed into our user environment as a dependency of a Python application:
588
589```Python console
590>>> import requests
591Traceback (most recent call last):
592 File "<stdin>", line 1, in <module>
593ModuleNotFoundError: No module named 'requests'
594```
595
596We can add as many additional modules onto the `nix-shell` as we need, and we
597will still get 1 wrapped Python interpreter. We can start the interpreter
598directly like so:
599
600```sh
601$ nix-shell -p "python311.withPackages (ps: with ps; [ numpy toolz requests ])" --run python3
602this derivation will be built:
603 /nix/store/r19yf5qgfiakqlhkgjahbg3zg79549n4-python3-3.11.2-env.drv
604building '/nix/store/r19yf5qgfiakqlhkgjahbg3zg79549n4-python3-3.11.2-env.drv'...
605created 273 symlinks in user environment
606Python 3.11.2 (main, Feb 7 2023, 13:52:42) [GCC 12.2.0] on linux
607Type "help", "copyright", "credits" or "license" for more information.
608>>> import requests
609>>>
610```
611
612Notice that this time it built a new Python environment, which now includes
613`requests`. Building an environment just creates wrapper scripts that expose the
614selected dependencies to the interpreter while re-using the actual modules. This
615means if any other env has installed `requests` or `numpy` in a different
616context, we don't need to recompile them -- we just recompile the wrapper script
617that sets up an interpreter pointing to them. This matters much more for "big"
618modules like `pytorch` or `tensorflow`.
619
620Module names usually match their names on [pypi.org](https://pypi.org/), but
621you can use the [Nixpkgs search website](https://nixos.org/nixos/packages.html)
622to find them as well (along with non-python packages).
623
624At this point we can create throwaway experimental Python environments with
625arbitrary dependencies. This is a good way to get a feel for how the Python
626interpreter and dependencies work in Nix and NixOS, but to do some actual
627development, we'll want to make it a bit more persistent.
628
629##### Running Python scripts and using `nix-shell` as shebang {#running-python-scripts-and-using-nix-shell-as-shebang}
630
631Sometimes, we have a script whose header looks like this:
632
633```python
634#!/usr/bin/env python3
635import numpy as np
636a = np.array([1,2])
637b = np.array([3,4])
638print(f"The dot product of {a} and {b} is: {np.dot(a, b)}")
639```
640
641Executing this script requires a `python3` that has `numpy`. Using what we learned
642in the previous section, we could startup a shell and just run it like so:
643
644```ShellSession
645$ nix-shell -p 'python311.withPackages (ps: with ps; [ numpy ])' --run 'python3 foo.py'
646The dot product of [1 2] and [3 4] is: 11
647```
648
649But if we maintain the script ourselves, and if there are more dependencies, it
650may be nice to encode those dependencies in source to make the script re-usable
651without that bit of knowledge. That can be done by using `nix-shell` as a
652[shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)), like so:
653
654```python
655#!/usr/bin/env nix-shell
656#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.numpy ])"
657import numpy as np
658a = np.array([1,2])
659b = np.array([3,4])
660print(f"The dot product of {a} and {b} is: {np.dot(a, b)}")
661```
662
663Then we execute it, without requiring any environment setup at all!
664
665```sh
666$ ./foo.py
667The dot product of [1 2] and [3 4] is: 11
668```
669
670If the dependencies are not available on the host where `foo.py` is executed, it
671will build or download them from a Nix binary cache prior to starting up, prior
672that it is executed on a machine with a multi-user nix installation.
673
674This provides a way to ship a self bootstrapping Python script, akin to a
675statically linked binary, where it can be run on any machine (provided nix is
676installed) without having to assume that `numpy` is installed globally on the
677system.
678
679By default it is pulling the import checkout of Nixpkgs itself from our nix
680channel, which is nice as it cache aligns with our other package builds, but we
681can make it fully reproducible by pinning the `nixpkgs` import:
682
683```python
684#!/usr/bin/env nix-shell
685#!nix-shell -i python3 -p "python3.withPackages (ps: [ ps.numpy ])"
686#!nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/e51209796c4262bfb8908e3d6d72302fe4e96f5f.tar.gz
687import numpy as np
688a = np.array([1,2])
689b = np.array([3,4])
690print(f"The dot product of {a} and {b} is: {np.dot(a, b)}")
691```
692
693This will execute with the exact same versions of Python 3.10, numpy, and system
694dependencies a year from now as it does today, because it will always use
695exactly git commit `e51209796c4262bfb8908e3d6d72302fe4e96f5f` of Nixpkgs for all
696of the package versions.
697
698This is also a great way to ensure the script executes identically on different
699servers.
700
701##### Load environment from `.nix` expression {#load-environment-from-.nix-expression}
702
703We've now seen how to create an ad-hoc temporary shell session, and how to
704create a single script with Python dependencies, but in the course of normal
705development we're usually working in an entire package repository.
706
707As explained [in the `nix-shell` section](https://nixos.org/manual/nix/stable/command-ref/nix-shell) of the Nix manual, `nix-shell` can also load an expression from a `.nix` file.
708Say we want to have Python 3.11, `numpy` and `toolz`, like before,
709in an environment. We can add a `shell.nix` file describing our dependencies:
710
711```nix
712with import <nixpkgs> {};
713(python311.withPackages (ps: with ps; [
714 numpy
715 toolz
716])).env
717```
718
719And then at the command line, just typing `nix-shell` produces the same
720environment as before. In a normal project, we'll likely have many more
721dependencies; this can provide a way for developers to share the environments
722with each other and with CI builders.
723
724What's happening here?
725
7261. We begin with importing the Nix Packages collections. `import <nixpkgs>`
727 imports the `<nixpkgs>` function, `{}` calls it and the `with` statement
728 brings all attributes of `nixpkgs` in the local scope. These attributes form
729 the main package set.
7302. Then we create a Python 3.11 environment with the [`withPackages`](#python.withpackages-function) function, as before.
7313. The [`withPackages`](#python.withpackages-function) function expects us to provide a function as an argument
732 that takes the set of all Python packages and returns a list of packages to
733 include in the environment. Here, we select the packages `numpy` and `toolz`
734 from the package set.
735
736To combine this with `mkShell` you can:
737
738```nix
739with import <nixpkgs> {};
740let
741 pythonEnv = python311.withPackages (ps: [
742 ps.numpy
743 ps.toolz
744 ]);
745in mkShell {
746 packages = [
747 pythonEnv
748
749 black
750 mypy
751
752 libffi
753 openssl
754 ];
755}
756```
757
758This will create a unified environment that has not just our Python interpreter
759and its Python dependencies, but also tools like `black` or `mypy` and libraries
760like `libffi` the `openssl` in scope. This is generic and can span any number of
761tools or languages across the Nixpkgs ecosystem.
762
763##### Installing environments globally on the system {#installing-environments-globally-on-the-system}
764
765Up to now, we've been creating environments scoped to an ad-hoc shell session,
766or a single script, or a single project. This is generally advisable, as it
767avoids pollution across contexts.
768
769However, sometimes we know we will often want a Python with some basic packages,
770and want this available without having to enter into a shell or build context.
771This can be useful to have things like vim/emacs editors and plugins or shell
772tools "just work" without having to set them up, or when running other software
773that expects packages to be installed globally.
774
775To create your own custom environment, create a file in `~/.config/nixpkgs/overlays/`
776that looks like this:
777
778```nix
779# ~/.config/nixpkgs/overlays/myEnv.nix
780self: super: {
781 myEnv = super.buildEnv {
782 name = "myEnv";
783 paths = [
784 # A Python 3 interpreter with some packages
785 (self.python3.withPackages (
786 ps: with ps; [
787 pyflakes
788 pytest
789 black
790 ]
791 ))
792
793 # Some other packages we'd like as part of this env
794 self.mypy
795 self.black
796 self.ripgrep
797 self.tmux
798 ];
799 };
800}
801```
802
803You can then build and install this to your profile with:
804
805```sh
806nix-env -iA myEnv
807```
808
809One limitation of this is that you can only have 1 Python env installed
810globally, since they conflict on the `python` to load out of your `PATH`.
811
812If you get a conflict or prefer to keep the setup clean, you can have `nix-env`
813atomically *uninstall* all other imperatively installed packages and replace
814your profile with just `myEnv` by using the `--replace` flag.
815
816##### Environment defined in `/etc/nixos/configuration.nix` {#environment-defined-in-etcnixosconfiguration.nix}
817
818For the sake of completeness, here's how to install the environment system-wide
819on NixOS.
820
821```nix
822{ # ...
823
824 environment.systemPackages = with pkgs; [
825 (python310.withPackages(ps: with ps; [ numpy toolz ]))
826 ];
827}
828```
829
830### Developing with Python {#developing-with-python}
831
832Above, we were mostly just focused on use cases and what to do to get started
833creating working Python environments in nix.
834
835Now that you know the basics to be up and running, it is time to take a step
836back and take a deeper look at how Python packages are packaged on Nix.
837
838#### Python library packages in Nixpkgs {#python-library-packages-in-nixpkgs}
839
840With Nix all packages are built by functions. The main function in Nix for
841building Python libraries is [`buildPythonPackage`](#buildpythonpackage-function). Let's see how we can build the
842`toolz` package.
843
844```nix
845{ lib
846, buildPythonPackage
847, fetchPypi
848, setuptools
849, wheel
850}:
851
852buildPythonPackage rec {
853 pname = "toolz";
854 version = "0.10.0";
855 pyproject = true;
856
857 src = fetchPypi {
858 inherit pname version;
859 hash = "sha256-CP3V73yWSArRHBLUct4hrNMjWZlvaaUlkpm1QP66RWA=";
860 };
861
862 build-system = [
863 setuptools
864 wheel
865 ];
866
867 # has no tests
868 doCheck = false;
869
870 pythonImportsCheck = [
871 "toolz.itertoolz"
872 "toolz.functoolz"
873 "toolz.dicttoolz"
874 ];
875
876 meta = {
877 changelog = "https://github.com/pytoolz/toolz/releases/tag/${version}";
878 homepage = "https://github.com/pytoolz/toolz";
879 description = "List processing tools and functional utilities";
880 license = lib.licenses.bsd3;
881 };
882}
883```
884
885What happens here? The function [`buildPythonPackage`](#buildpythonpackage-function) is called and as argument
886it accepts a set. In this case the set is a recursive set, `rec`. One of the
887arguments is the name of the package, which consists of a basename (generally
888following the name on PyPi) and a version. Another argument, `src` specifies the
889source, which in this case is fetched from PyPI using the helper function
890`fetchPypi`. The argument `doCheck` is used to set whether tests should be run
891when building the package. Since there are no tests, we rely on [`pythonImportsCheck`](#using-pythonimportscheck)
892to test whether the package can be imported. Furthermore, we specify some meta
893information. The output of the function is a derivation.
894
895An expression for `toolz` can be found in the Nixpkgs repository. As explained
896in the introduction of this Python section, a derivation of `toolz` is available
897for each interpreter version, e.g. `python311.pkgs.toolz` refers to the `toolz`
898derivation corresponding to the CPython 3.11 interpreter.
899
900The above example works when you're directly working on
901`pkgs/top-level/python-packages.nix` in the Nixpkgs repository. Often though,
902you will want to test a Nix expression outside of the Nixpkgs tree.
903
904The following expression creates a derivation for the `toolz` package,
905and adds it along with a `numpy` package to a Python environment.
906
907```nix
908with import <nixpkgs> {};
909
910( let
911 my_toolz = python311.pkgs.buildPythonPackage rec {
912 pname = "toolz";
913 version = "0.10.0";
914 pyproject = true;
915
916 src = fetchPypi {
917 inherit pname version;
918 hash = "sha256-CP3V73yWSArRHBLUct4hrNMjWZlvaaUlkpm1QP66RWA=";
919 };
920
921 build-system = [
922 python311.pkgs.setuptools
923 python311.pkgs.wheel
924 ];
925
926 # has no tests
927 doCheck = false;
928
929 meta = {
930 homepage = "https://github.com/pytoolz/toolz/";
931 description = "List processing tools and functional utilities";
932 # [...]
933 };
934 };
935
936 in python311.withPackages (ps: with ps; [
937 numpy
938 my_toolz
939 ])
940).env
941```
942
943Executing `nix-shell` will result in an environment in which you can use
944Python 3.11 and the `toolz` package. As you can see we had to explicitly mention
945for which Python version we want to build a package.
946
947So, what did we do here? Well, we took the Nix expression that we used earlier
948to build a Python environment, and said that we wanted to include our own
949version of `toolz`, named `my_toolz`. To introduce our own package in the scope
950of [`withPackages`](#python.withpackages-function) we used a `let` expression. You can see that we used
951`ps.numpy` to select numpy from the nixpkgs package set (`ps`). We did not take
952`toolz` from the Nixpkgs package set this time, but instead took our own version
953that we introduced with the `let` expression.
954
955#### Handling dependencies {#handling-dependencies}
956
957Our example, `toolz`, does not have any dependencies on other Python packages or system libraries.
958[`buildPythonPackage`](#buildpythonpackage-function) uses the the following arguments in the following circumstances:
959
960- `dependencies` - For Python runtime dependencies.
961- `build-system` - For Python build-time requirements.
962- [`buildInputs`](#var-stdenv-buildInputs) - For non-Python build-time requirements.
963- [`nativeCheckInputs`](#var-stdenv-nativeCheckInputs) - For test dependencies
964
965Dependencies can belong to multiple arguments, for example if something is both a build time requirement & a runtime dependency.
966
967The following example shows which arguments are given to [`buildPythonPackage`](#buildpythonpackage-function) in
968order to build [`datashape`](https://github.com/blaze/datashape).
969
970```nix
971{ lib
972, buildPythonPackage
973, fetchPypi
974
975# build dependencies
976, setuptools, wheel
977
978# dependencies
979, numpy, multipledispatch, python-dateutil
980
981# tests
982, pytest
983}:
984
985buildPythonPackage rec {
986 pname = "datashape";
987 version = "0.4.7";
988 pyproject = true;
989
990 src = fetchPypi {
991 inherit pname version;
992 hash = "sha256-FLLvdm1MllKrgTGC6Gb0k0deZeVYvtCCLji/B7uhong=";
993 };
994
995 build-system = [
996 setuptools
997 wheel
998 ];
999
1000 dependencies = [
1001 multipledispatch
1002 numpy
1003 python-dateutil
1004 ];
1005
1006 nativeCheckInputs = [
1007 pytest
1008 ];
1009
1010 meta = {
1011 changelog = "https://github.com/blaze/datashape/releases/tag/${version}";
1012 homepage = "https://github.com/ContinuumIO/datashape";
1013 description = "A data description language";
1014 license = lib.licenses.bsd2;
1015 };
1016}
1017```
1018
1019We can see several runtime dependencies, `numpy`, `multipledispatch`, and
1020`python-dateutil`. Furthermore, we have [`nativeCheckInputs`](#var-stdenv-nativeCheckInputs) with `pytest`.
1021`pytest` is a test runner and is only used during the [`checkPhase`](#ssec-check-phase) and is
1022therefore not added to `dependencies`.
1023
1024In the previous case we had only dependencies on other Python packages to consider.
1025Occasionally you have also system libraries to consider. E.g., `lxml` provides
1026Python bindings to `libxml2` and `libxslt`. These libraries are only required
1027when building the bindings and are therefore added as [`buildInputs`](#var-stdenv-buildInputs).
1028
1029```nix
1030{ lib
1031, buildPythonPackage
1032, fetchPypi
1033, setuptools
1034, wheel
1035, libxml2
1036, libxslt
1037}:
1038
1039buildPythonPackage rec {
1040 pname = "lxml";
1041 version = "3.4.4";
1042 pyproject = true;
1043
1044 src = fetchPypi {
1045 inherit pname version;
1046 hash = "sha256-s9NiusRxFydHzaNRMjjxFcvWxfi45jGb9ql6eJJyQJk=";
1047 };
1048
1049 build-system = [
1050 setuptools
1051 wheel
1052 ];
1053
1054 buildInputs = [
1055 libxml2
1056 libxslt
1057 ];
1058
1059 meta = {
1060 changelog = "https://github.com/lxml/lxml/releases/tag/lxml-${version}";
1061 description = "Pythonic binding for the libxml2 and libxslt libraries";
1062 homepage = "https://lxml.de";
1063 license = lib.licenses.bsd3;
1064 maintainers = with lib.maintainers; [ sjourdois ];
1065 };
1066}
1067```
1068
1069In this example `lxml` and Nix are able to work out exactly where the relevant
1070files of the dependencies are. This is not always the case.
1071
1072The example below shows bindings to The Fastest Fourier Transform in the West,
1073commonly known as FFTW. On Nix we have separate packages of FFTW for the
1074different types of floats (`"single"`, `"double"`, `"long-double"`). The
1075bindings need all three types, and therefore we add all three as [`buildInputs`](#var-stdenv-buildInputs).
1076The bindings don't expect to find each of them in a different folder, and
1077therefore we have to set `LDFLAGS` and `CFLAGS`.
1078
1079```nix
1080{ lib
1081, buildPythonPackage
1082, fetchPypi
1083
1084# build dependencies
1085, setuptools
1086, wheel
1087
1088# dependencies
1089, fftw
1090, fftwFloat
1091, fftwLongDouble
1092, numpy
1093, scipy
1094}:
1095
1096buildPythonPackage rec {
1097 pname = "pyFFTW";
1098 version = "0.9.2";
1099 pyproject = true;
1100
1101 src = fetchPypi {
1102 inherit pname version;
1103 hash = "sha256-9ru2r6kwhUCaskiFoaPNuJCfCVoUL01J40byvRt4kHQ=";
1104 };
1105
1106 build-system = [
1107 setuptools
1108 wheel
1109 ];
1110
1111 buildInputs = [
1112 fftw
1113 fftwFloat
1114 fftwLongDouble
1115 ];
1116
1117 dependencies = [
1118 numpy
1119 scipy
1120 ];
1121
1122 preConfigure = ''
1123 export LDFLAGS="-L${fftw.dev}/lib -L${fftwFloat.out}/lib -L${fftwLongDouble.out}/lib"
1124 export CFLAGS="-I${fftw.dev}/include -I${fftwFloat.dev}/include -I${fftwLongDouble.dev}/include"
1125 '';
1126
1127 # Tests cannot import pyfftw. pyfftw works fine though.
1128 doCheck = false;
1129
1130 meta = {
1131 changelog = "https://github.com/pyFFTW/pyFFTW/releases/tag/v${version}";
1132 description = "A pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms";
1133 homepage = "http://hgomersall.github.com/pyFFTW";
1134 license = with lib.licenses; [ bsd2 bsd3 ];
1135 };
1136}
1137```
1138
1139Note also the line [`doCheck = false;`](#var-stdenv-doCheck), we explicitly disabled running the test-suite.
1140
1141#### Testing Python Packages {#testing-python-packages}
1142
1143It is highly encouraged to have testing as part of the package build. This
1144helps to avoid situations where the package was able to build and install,
1145but is not usable at runtime. Currently, all packages will use the `test`
1146command provided by the setup.py (i.e. `python setup.py test`). However,
1147this is currently deprecated https://github.com/pypa/setuptools/pull/1878
1148and your package should provide its own [`checkPhase`](#ssec-check-phase).
1149
1150::: {.note}
1151The [`checkPhase`](#ssec-check-phase) for python maps to the `installCheckPhase` on a
1152normal derivation. This is due to many python packages not behaving well
1153to the pre-installed version of the package. Version info, and natively
1154compiled extensions generally only exist in the install directory, and
1155thus can cause issues when a test suite asserts on that behavior.
1156:::
1157
1158::: {.note}
1159Tests should only be disabled if they don't agree with nix
1160(e.g. external dependencies, network access, flakey tests), however,
1161as many tests should be enabled as possible. Failing tests can still be
1162a good indication that the package is not in a valid state.
1163:::
1164
1165#### Using pytest {#using-pytest}
1166
1167Pytest is the most common test runner for python repositories. A trivial
1168test run would be:
1169
1170```nix
1171{
1172 nativeCheckInputs = [ pytest ];
1173 checkPhase = ''
1174 runHook preCheck
1175
1176 pytest
1177
1178 runHook postCheck
1179 '';
1180}
1181```
1182
1183However, many repositories' test suites do not translate well to nix's build
1184sandbox, and will generally need many tests to be disabled.
1185
1186To filter tests using pytest, one can do the following:
1187
1188```nix
1189{
1190 nativeCheckInputs = [ pytest ];
1191 # avoid tests which need additional data or touch network
1192 checkPhase = ''
1193 runHook preCheck
1194
1195 pytest tests/ --ignore=tests/integration -k 'not download and not update' --ignore=tests/test_failing.py
1196
1197 runHook postCheck
1198 '';
1199}
1200```
1201
1202`--ignore` will tell pytest to ignore that file or directory from being
1203collected as part of a test run. This is useful is a file uses a package
1204which is not available in nixpkgs, thus skipping that test file is much
1205easier than having to create a new package.
1206
1207`-k` is used to define a predicate for test names. In this example, we are
1208filtering out tests which contain `download` or `update` in their test case name.
1209Only one `-k` argument is allowed, and thus a long predicate should be concatenated
1210with “\\” and wrapped to the next line.
1211
1212::: {.note}
1213In pytest==6.0.1, the use of “\\” to continue a line (e.g. `-k 'not download \'`) has
1214been removed, in this case, it's recommended to use `pytestCheckHook`.
1215:::
1216
1217#### Using pytestCheckHook {#using-pytestcheckhook}
1218
1219`pytestCheckHook` is a convenient hook which will substitute the setuptools
1220`test` command for a [`checkPhase`](#ssec-check-phase) which runs `pytest`. This is also beneficial
1221when a package may need many items disabled to run the test suite.
1222
1223Using the example above, the analogous `pytestCheckHook` usage would be:
1224
1225```nix
1226{
1227 nativeCheckInputs = [
1228 pytestCheckHook
1229 ];
1230
1231 # requires additional data
1232 pytestFlagsArray = [
1233 "tests/"
1234 "--ignore=tests/integration"
1235 ];
1236
1237 disabledTests = [
1238 # touches network
1239 "download"
1240 "update"
1241 ];
1242
1243 disabledTestPaths = [
1244 "tests/test_failing.py"
1245 ];
1246}
1247```
1248
1249This is especially useful when tests need to be conditionally disabled,
1250for example:
1251
1252```nix
1253{
1254 disabledTests = [
1255 # touches network
1256 "download"
1257 "update"
1258 ] ++ lib.optionals (pythonAtLeast "3.8") [
1259 # broken due to python3.8 async changes
1260 "async"
1261 ] ++ lib.optionals stdenv.isDarwin [
1262 # can fail when building with other packages
1263 "socket"
1264 ];
1265}
1266```
1267
1268Trying to concatenate the related strings to disable tests in a regular
1269[`checkPhase`](#ssec-check-phase) would be much harder to read. This also enables us to comment on
1270why specific tests are disabled.
1271
1272#### Using pythonImportsCheck {#using-pythonimportscheck}
1273
1274Although unit tests are highly preferred to validate correctness of a package, not
1275all packages have test suites that can be run easily, and some have none at all.
1276To help ensure the package still works, [`pythonImportsCheck`](#using-pythonimportscheck) can attempt to import
1277the listed modules.
1278
1279```nix
1280{
1281 pythonImportsCheck = [
1282 "requests"
1283 "urllib"
1284 ];
1285}
1286```
1287
1288roughly translates to:
1289
1290```nix
1291{
1292 postCheck = ''
1293 PYTHONPATH=$out/${python.sitePackages}:$PYTHONPATH
1294 python -c "import requests; import urllib"
1295 '';
1296}
1297```
1298
1299However, this is done in its own phase, and not dependent on whether [`doCheck = true;`](#var-stdenv-doCheck).
1300
1301This can also be useful in verifying that the package doesn't assume commonly
1302present packages (e.g. `setuptools`).
1303
1304#### Using pythonRelaxDepsHook {#using-pythonrelaxdepshook}
1305
1306It is common for upstream to specify a range of versions for its package
1307dependencies. This makes sense, since it ensures that the package will be built
1308with a subset of packages that is well tested. However, this commonly causes
1309issues when packaging in Nixpkgs, because the dependencies that this package
1310may need are too new or old for the package to build correctly. We also cannot
1311package multiple versions of the same package since this may cause conflicts
1312in `PYTHONPATH`.
1313
1314One way to side step this issue is to relax the dependencies. This can be done
1315by either removing the package version range or by removing the package
1316declaration entirely. This can be done using the `pythonRelaxDepsHook` hook. For
1317example, given the following `requirements.txt` file:
1318
1319```
1320pkg1<1.0
1321pkg2
1322pkg3>=1.0,<=2.0
1323```
1324
1325we can do:
1326
1327```nix
1328{
1329 nativeBuildInputs = [
1330 pythonRelaxDepsHook
1331 ];
1332 pythonRelaxDeps = [
1333 "pkg1"
1334 "pkg3"
1335 ];
1336 pythonRemoveDeps = [
1337 "pkg2"
1338 ];
1339}
1340```
1341
1342which would result in the following `requirements.txt` file:
1343
1344```
1345pkg1
1346pkg3
1347```
1348
1349Another option is to pass `true`, that will relax/remove all dependencies, for
1350example:
1351
1352```nix
1353{
1354 nativeBuildInputs = [ pythonRelaxDepsHook ];
1355 pythonRelaxDeps = true;
1356}
1357```
1358
1359which would result in the following `requirements.txt` file:
1360
1361```
1362pkg1
1363pkg2
1364pkg3
1365```
1366
1367In general you should always use `pythonRelaxDeps`, because `pythonRemoveDeps`
1368will convert build errors into runtime errors. However `pythonRemoveDeps` may
1369still be useful in exceptional cases, and also to remove dependencies wrongly
1370declared by upstream (for example, declaring `black` as a runtime dependency
1371instead of a dev dependency).
1372
1373Keep in mind that while the examples above are done with `requirements.txt`,
1374`pythonRelaxDepsHook` works by modifying the resulting wheel file, so it should
1375work with any of the [existing hooks](#setup-hooks).
1376
1377#### Using unittestCheckHook {#using-unittestcheckhook}
1378
1379`unittestCheckHook` is a hook which will substitute the setuptools `test` command for a [`checkPhase`](#ssec-check-phase) which runs `python -m unittest discover`:
1380
1381```nix
1382{
1383 nativeCheckInputs = [
1384 unittestCheckHook
1385 ];
1386
1387 unittestFlagsArray = [
1388 "-s" "tests" "-v"
1389 ];
1390}
1391```
1392
1393#### Using sphinxHook {#using-sphinxhook}
1394
1395The `sphinxHook` is a helpful tool to build documentation and manpages
1396using the popular Sphinx documentation generator.
1397It is setup to automatically find common documentation source paths and
1398render them using the default `html` style.
1399
1400```nix
1401{
1402 outputs = [
1403 "out"
1404 "doc"
1405 ];
1406
1407 nativeBuildInputs = [
1408 sphinxHook
1409 ];
1410}
1411```
1412
1413The hook will automatically build and install the artifact into the
1414`doc` output, if it exists. It also provides an automatic diversion
1415for the artifacts of the `man` builder into the `man` target.
1416
1417```nix
1418{
1419 outputs = [
1420 "out"
1421 "doc"
1422 "man"
1423 ];
1424
1425 # Use multiple builders
1426 sphinxBuilders = [
1427 "singlehtml"
1428 "man"
1429 ];
1430}
1431```
1432
1433Overwrite `sphinxRoot` when the hook is unable to find your
1434documentation source root.
1435
1436```nix
1437{
1438 # Configure sphinxRoot for uncommon paths
1439 sphinxRoot = "weird/docs/path";
1440}
1441```
1442
1443The hook is also available to packages outside the python ecosystem by
1444referencing it using `sphinxHook` from top-level.
1445
1446### Organising your packages {#organising-your-packages}
1447
1448So far we discussed how you can use Python on Nix, and how you can develop with
1449it. We've looked at how you write expressions to package Python packages, and we
1450looked at how you can create environments in which specified packages are
1451available.
1452
1453At some point you'll likely have multiple packages which you would
1454like to be able to use in different projects. In order to minimise unnecessary
1455duplication we now look at how you can maintain a repository with your
1456own packages. The important functions here are `import` and `callPackage`.
1457
1458### Including a derivation using `callPackage` {#including-a-derivation-using-callpackage}
1459
1460Earlier we created a Python environment using [`withPackages`](#python.withpackages-function), and included the
1461`toolz` package via a `let` expression.
1462Let's split the package definition from the environment definition.
1463
1464We first create a function that builds `toolz` in `~/path/to/toolz/release.nix`
1465
1466```nix
1467{ lib
1468, buildPythonPackage
1469, fetchPypi
1470, setuptools
1471, wheel
1472}:
1473
1474buildPythonPackage rec {
1475 pname = "toolz";
1476 version = "0.10.0";
1477 pyproject = true;
1478
1479 src = fetchPypi {
1480 inherit pname version;
1481 hash = "sha256-CP3V73yWSArRHBLUct4hrNMjWZlvaaUlkpm1QP66RWA=";
1482 };
1483
1484 build-system = [
1485 setuptools
1486 wheel
1487 ];
1488
1489 meta = {
1490 changelog = "https://github.com/pytoolz/toolz/releases/tag/${version}";
1491 homepage = "https://github.com/pytoolz/toolz/";
1492 description = "List processing tools and functional utilities";
1493 license = lib.licenses.bsd3;
1494 };
1495}
1496```
1497
1498It takes an argument [`buildPythonPackage`](#buildpythonpackage-function). We now call this function using
1499`callPackage` in the definition of our environment
1500
1501```nix
1502with import <nixpkgs> {};
1503
1504( let
1505 toolz = callPackage /path/to/toolz/release.nix {
1506 buildPythonPackage = python310
1507Packages.buildPythonPackage;
1508 };
1509 in python310.withPackages (ps: [
1510 ps.numpy
1511 toolz
1512 ])
1513).env
1514```
1515
1516Important to remember is that the Python version for which the package is made
1517depends on the `python` derivation that is passed to [`buildPythonPackage`](#buildpythonpackage-function). Nix
1518tries to automatically pass arguments when possible, which is why generally you
1519don't explicitly define which `python` derivation should be used. In the above
1520example we use [`buildPythonPackage`](#buildpythonpackage-function) that is part of the set `python3Packages`,
1521and in this case the `python3` interpreter is automatically used.
1522
1523## FAQ {#faq}
1524
1525### How to solve circular dependencies? {#how-to-solve-circular-dependencies}
1526
1527Consider the packages `A` and `B` that depend on each other. When packaging `B`,
1528a solution is to override package `A` not to depend on `B` as an input. The same
1529should also be done when packaging `A`.
1530
1531### How to override a Python package? {#how-to-override-a-python-package}
1532
1533We can override the interpreter and pass `packageOverrides`. In the following
1534example we rename the `pandas` package and build it.
1535
1536```nix
1537with import <nixpkgs> {};
1538
1539(let
1540 python = let
1541 packageOverrides = self: super: {
1542 pandas = super.pandas.overridePythonAttrs(old: {name="foo";});
1543 };
1544 in pkgs.python310.override {
1545 inherit packageOverrides;
1546 };
1547
1548in python.withPackages (ps: [
1549 ps.pandas
1550])).env
1551```
1552
1553Using `nix-build` on this expression will build an environment that contains the
1554package `pandas` but with the new name `foo`.
1555
1556All packages in the package set will use the renamed package. A typical use case
1557is to switch to another version of a certain package. For example, in the
1558Nixpkgs repository we have multiple versions of `django` and `scipy`. In the
1559following example we use a different version of `scipy` and create an
1560environment that uses it. All packages in the Python package set will now use
1561the updated `scipy` version.
1562
1563```nix
1564with import <nixpkgs> {};
1565
1566( let
1567 packageOverrides = self: super: {
1568 scipy = super.scipy_0_17;
1569 };
1570 in (pkgs.python310.override {
1571 inherit packageOverrides;
1572 }).withPackages (ps: [
1573 ps.blaze
1574 ])
1575).env
1576```
1577
1578The requested package `blaze` depends on `pandas` which itself depends on `scipy`.
1579
1580If you want the whole of Nixpkgs to use your modifications, then you can use
1581`overlays` as explained in this manual. In the following example we build a
1582`inkscape` using a different version of `numpy`.
1583
1584```nix
1585let
1586 pkgs = import <nixpkgs> {};
1587 newpkgs = import pkgs.path { overlays = [ (self: super: {
1588 python310 = let
1589 packageOverrides = python-self: python-super: {
1590 numpy = python-super.numpy_1_18;
1591 };
1592 in super.python310.override {inherit packageOverrides;};
1593 } ) ]; };
1594in newpkgs.inkscape
1595```
1596
1597### `python setup.py bdist_wheel` cannot create .whl {#python-setup.py-bdist_wheel-cannot-create-.whl}
1598
1599Executing `python setup.py bdist_wheel` in a `nix-shell`fails with
1600
1601```
1602ValueError: ZIP does not support timestamps before 1980
1603```
1604
1605This is because files from the Nix store (which have a timestamp of the UNIX
1606epoch of January 1, 1970) are included in the .ZIP, but .ZIP archives follow the
1607DOS convention of counting timestamps from 1980.
1608
1609The command `bdist_wheel` reads the `SOURCE_DATE_EPOCH` environment variable,
1610which `nix-shell` sets to 1. Unsetting this variable or giving it a value
1611corresponding to 1980 or later enables building wheels.
1612
1613Use 1980 as timestamp:
1614
1615```shell
1616nix-shell --run "SOURCE_DATE_EPOCH=315532800 python3 setup.py bdist_wheel"
1617```
1618
1619or the current time:
1620
1621```shell
1622nix-shell --run "SOURCE_DATE_EPOCH=$(date +%s) python3 setup.py bdist_wheel"
1623```
1624
1625or unset `SOURCE_DATE_EPOCH`:
1626
1627```shell
1628nix-shell --run "unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"
1629```
1630
1631### `install_data` / `data_files` problems {#install_data-data_files-problems}
1632
1633If you get the following error:
1634
1635```
1636could not create '/nix/store/6l1bvljpy8gazlsw2aw9skwwp4pmvyxw-python-2.7.8/etc':
1637Permission denied
1638```
1639
1640This is a [known bug](https://github.com/pypa/setuptools/issues/130) in
1641`setuptools`. Setuptools `install_data` does not respect `--prefix`. An example
1642of such package using the feature is `pkgs/tools/X11/xpra/default.nix`.
1643
1644As workaround install it as an extra `preInstall` step:
1645
1646```shell
1647${python.pythonOnBuildForHost.interpreter} setup.py install_data --install-dir=$out --root=$out
1648sed -i '/ = data\_files/d' setup.py
1649```
1650
1651### Rationale of non-existent global site-packages {#rationale-of-non-existent-global-site-packages}
1652
1653On most operating systems a global `site-packages` is maintained. This however
1654becomes problematic if you want to run multiple Python versions or have multiple
1655versions of certain libraries for your projects. Generally, you would solve such
1656issues by creating virtual environments using `virtualenv`.
1657
1658On Nix each package has an isolated dependency tree which, in the case of
1659Python, guarantees the right versions of the interpreter and libraries or
1660packages are available. There is therefore no need to maintain a global `site-packages`.
1661
1662If you want to create a Python environment for development, then the recommended
1663method is to use `nix-shell`, either with or without the [`python.buildEnv`](#python.buildenv-function)
1664function.
1665
1666### How to consume Python modules using pip in a virtual environment like I am used to on other Operating Systems? {#how-to-consume-python-modules-using-pip-in-a-virtual-environment-like-i-am-used-to-on-other-operating-systems}
1667
1668While this approach is not very idiomatic from Nix perspective, it can still be
1669useful when dealing with pre-existing projects or in situations where it's not
1670feasible or desired to write derivations for all required dependencies.
1671
1672This is an example of a `default.nix` for a `nix-shell`, which allows to consume
1673a virtual environment created by `venv`, and install Python modules through
1674`pip` the traditional way.
1675
1676Create this `default.nix` file, together with a `requirements.txt` and
1677execute `nix-shell`.
1678
1679```nix
1680with import <nixpkgs> { };
1681
1682let
1683 pythonPackages = python3Packages;
1684in pkgs.mkShell rec {
1685 name = "impurePythonEnv";
1686 venvDir = "./.venv";
1687 buildInputs = [
1688 # A Python interpreter including the 'venv' module is required to bootstrap
1689 # the environment.
1690 pythonPackages.python
1691
1692 # This executes some shell code to initialize a venv in $venvDir before
1693 # dropping into the shell
1694 pythonPackages.venvShellHook
1695
1696 # Those are dependencies that we would like to use from nixpkgs, which will
1697 # add them to PYTHONPATH and thus make them accessible from within the venv.
1698 pythonPackages.numpy
1699 pythonPackages.requests
1700
1701 # In this particular example, in order to compile any binary extensions they may
1702 # require, the Python modules listed in the hypothetical requirements.txt need
1703 # the following packages to be installed locally:
1704 taglib
1705 openssl
1706 git
1707 libxml2
1708 libxslt
1709 libzip
1710 zlib
1711 ];
1712
1713 # Run this command, only after creating the virtual environment
1714 postVenvCreation = ''
1715 unset SOURCE_DATE_EPOCH
1716 pip install -r requirements.txt
1717 '';
1718
1719 # Now we can execute any commands within the virtual environment.
1720 # This is optional and can be left out to run pip manually.
1721 postShellHook = ''
1722 # allow pip to install wheels
1723 unset SOURCE_DATE_EPOCH
1724 '';
1725
1726}
1727```
1728
1729In case the supplied venvShellHook is insufficient, or when Python 2 support is
1730needed, you can define your own shell hook and adapt to your needs like in the
1731following example:
1732
1733```nix
1734with import <nixpkgs> { };
1735
1736let
1737 venvDir = "./.venv";
1738 pythonPackages = python3Packages;
1739in pkgs.mkShell rec {
1740 name = "impurePythonEnv";
1741 buildInputs = [
1742 pythonPackages.python
1743 # Needed when using python 2.7
1744 # pythonPackages.virtualenv
1745 # ...
1746 ];
1747
1748 # This is very close to how venvShellHook is implemented, but
1749 # adapted to use 'virtualenv'
1750 shellHook = ''
1751 SOURCE_DATE_EPOCH=$(date +%s)
1752
1753 if [ -d "${venvDir}" ]; then
1754 echo "Skipping venv creation, '${venvDir}' already exists"
1755 else
1756 echo "Creating new venv environment in path: '${venvDir}'"
1757 # Note that the module venv was only introduced in python 3, so for 2.7
1758 # this needs to be replaced with a call to virtualenv
1759 ${pythonPackages.python.interpreter} -m venv "${venvDir}"
1760 fi
1761
1762 # Under some circumstances it might be necessary to add your virtual
1763 # environment to PYTHONPATH, which you can do here too;
1764 # PYTHONPATH=$PWD/${venvDir}/${pythonPackages.python.sitePackages}/:$PYTHONPATH
1765
1766 source "${venvDir}/bin/activate"
1767
1768 # As in the previous example, this is optional.
1769 pip install -r requirements.txt
1770 '';
1771}
1772```
1773
1774Note that the `pip install` is an imperative action. So every time `nix-shell`
1775is executed it will attempt to download the Python modules listed in
1776requirements.txt. However these will be cached locally within the `virtualenv`
1777folder and not downloaded again.
1778
1779### How to override a Python package from `configuration.nix`? {#how-to-override-a-python-package-from-configuration.nix}
1780
1781If you need to change a package's attribute(s) from `configuration.nix` you could do:
1782
1783```nix
1784{
1785 nixpkgs.config.packageOverrides = super: {
1786 python3 = super.python3.override {
1787 packageOverrides = python-self: python-super: {
1788 twisted = python-super.twisted.overridePythonAttrs (oldAttrs: {
1789 src = super.fetchPypi {
1790 pname = "Twisted";
1791 version = "19.10.0";
1792 hash = "sha256-c5S6fycq5yKnTz2Wnc9Zm8TvCTvDkgOHSKSQ8XJKUV0=";
1793 extension = "tar.bz2";
1794 };
1795 });
1796 };
1797 };
1798 };
1799}
1800```
1801
1802`python3Packages.twisted` is now globally overridden.
1803All packages and also all NixOS services that reference `twisted`
1804(such as `services.buildbot-worker`) now use the new definition.
1805Note that `python-super` refers to the old package set and `python-self`
1806to the new, overridden version.
1807
1808To modify only a Python package set instead of a whole Python derivation, use
1809this snippet:
1810
1811```nix
1812{
1813 myPythonPackages = python3Packages.override {
1814 overrides = self: super: {
1815 twisted = <...>;
1816 };
1817 };
1818}
1819```
1820
1821### How to override a Python package using overlays? {#how-to-override-a-python-package-using-overlays}
1822
1823Use the following overlay template:
1824
1825```nix
1826self: super: {
1827 python = super.python.override {
1828 packageOverrides = python-self: python-super: {
1829 twisted = python-super.twisted.overrideAttrs (oldAttrs: {
1830 src = super.fetchPypi {
1831 pname = "Twisted";
1832 version = "19.10.0";
1833 hash = "sha256-c5S6fycq5yKnTz2Wnc9Zm8TvCTvDkgOHSKSQ8XJKUV0=";
1834 extension = "tar.bz2";
1835 };
1836 });
1837 };
1838 };
1839}
1840```
1841
1842### How to override a Python package for all Python versions using extensions? {#how-to-override-a-python-package-for-all-python-versions-using-extensions}
1843
1844The following overlay overrides the call to [`buildPythonPackage`](#buildpythonpackage-function) for the
1845`foo` package for all interpreters by appending a Python extension to the
1846`pythonPackagesExtensions` list of extensions.
1847
1848```nix
1849final: prev: {
1850 pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
1851 (
1852 python-final: python-prev: {
1853 foo = python-prev.foo.overridePythonAttrs (oldAttrs: {
1854 # ...
1855 });
1856 }
1857 )
1858 ];
1859}
1860```
1861
1862### How to use Intel’s MKL with numpy and scipy? {#how-to-use-intels-mkl-with-numpy-and-scipy}
1863
1864MKL can be configured using an overlay. See the section "[Using overlays to
1865configure alternatives](#sec-overlays-alternatives-blas-lapack)".
1866
1867### What inputs do `setup_requires`, `install_requires` and `tests_require` map to? {#what-inputs-do-setup_requires-install_requires-and-tests_require-map-to}
1868
1869In a `setup.py` or `setup.cfg` it is common to declare dependencies:
1870
1871* `setup_requires` corresponds to `build-system`
1872* `install_requires` corresponds to `dependencies`
1873* `tests_require` corresponds to [`nativeCheckInputs`](#var-stdenv-nativeCheckInputs)
1874
1875### How to enable interpreter optimizations? {#optimizations}
1876
1877The Python interpreters are by default not built with optimizations enabled, because
1878the builds are in that case not reproducible. To enable optimizations, override the
1879interpreter of interest, e.g using
1880
1881```nix
1882let
1883 pkgs = import ./. {};
1884 mypython = pkgs.python3.override {
1885 enableOptimizations = true;
1886 reproducibleBuild = false;
1887 self = mypython;
1888 };
1889in mypython
1890```
1891
1892### How to add optional dependencies? {#python-optional-dependencies}
1893
1894Some packages define optional dependencies for additional features. With
1895`setuptools` this is called `extras_require` and `flit` calls it
1896`extras-require`, while PEP 621 calls these `optional-dependencies`.
1897
1898```nix
1899{
1900 optional-dependencies = {
1901 complete = [ distributed ];
1902 };
1903}
1904```
1905
1906and letting the package requiring the extra add the list to its dependencies
1907
1908```nix
1909{
1910 dependencies = [
1911 # ...
1912 ] ++ dask.optional-dependencies.complete;
1913}
1914```
1915
1916This method is using `passthru`, meaning that changing `optional-dependencies` of a package won't cause it to rebuild.
1917
1918Note this method is preferred over adding parameters to builders, as that can
1919result in packages depending on different variants and thereby causing
1920collisions.
1921
1922### How to contribute a Python package to nixpkgs? {#tools}
1923
1924Packages inside nixpkgs must use the [`buildPythonPackage`](#buildpythonpackage-function) or [`buildPythonApplication`](#buildpythonapplication-function) function directly,
1925because we can only provide security support for non-vendored dependencies.
1926
1927We recommend [nix-init](https://github.com/nix-community/nix-init) for creating new python packages within nixpkgs,
1928as it already prefetches the source, parses dependencies for common formats and prefills most things in `meta`.
1929
1930### Are Python interpreters built deterministically? {#deterministic-builds}
1931
1932The Python interpreters are now built deterministically. Minor modifications had
1933to be made to the interpreters in order to generate deterministic bytecode. This
1934has security implications and is relevant for those using Python in a
1935`nix-shell`.
1936
1937When the environment variable `DETERMINISTIC_BUILD` is set, all bytecode will
1938have timestamp 1. The [`buildPythonPackage`](#buildpythonpackage-function) function sets `DETERMINISTIC_BUILD=1`
1939and [PYTHONHASHSEED=0](https://docs.python.org/3.11/using/cmdline.html#envvar-PYTHONHASHSEED).
1940Both are also exported in `nix-shell`.
1941
1942### How to provide automatic tests to Python packages? {#automatic-tests}
1943
1944It is recommended to test packages as part of the build process.
1945Source distributions (`sdist`) often include test files, but not always.
1946
1947By default the command `python setup.py test` is run as part of the
1948[`checkPhase`](#ssec-check-phase), but often it is necessary to pass a custom [`checkPhase`](#ssec-check-phase). An
1949example of such a situation is when `py.test` is used.
1950
1951#### Common issues {#common-issues}
1952
1953* Non-working tests can often be deselected. By default [`buildPythonPackage`](#buildpythonpackage-function)
1954 runs `python setup.py test`. which is deprecated. Most Python modules however
1955 do follow the standard test protocol where the pytest runner can be used
1956 instead. `pytest` supports the `-k` and `--ignore` parameters to ignore test
1957 methods or classes as well as whole files. For `pytestCheckHook` these are
1958 conveniently exposed as `disabledTests` and `disabledTestPaths` respectively.
1959
1960 ```nix
1961 buildPythonPackage {
1962 # ...
1963 nativeCheckInputs = [
1964 pytestCheckHook
1965 ];
1966
1967 disabledTests = [
1968 "function_name"
1969 "other_function"
1970 ];
1971
1972 disabledTestPaths = [
1973 "this/file.py"
1974 ];
1975 }
1976 ```
1977
1978* Tests that attempt to access `$HOME` can be fixed by using the following
1979 work-around before running tests (e.g. `preCheck`): `export HOME=$(mktemp -d)`
1980* Compiling with Cython causes tests to fail with a `ModuleNotLoadedError`.
1981 This can be fixed with two changes in the derivation: 1) replacing `pytest` with
1982 `pytestCheckHook` and 2) adding a `preCheck` containing `cd $out` to run
1983 tests within the built output.
1984
1985## Contributing {#contributing}
1986
1987### Contributing guidelines {#contributing-guidelines}
1988
1989The following rules are desired to be respected:
1990
1991* Python libraries are called from `python-packages.nix` and packaged with
1992 [`buildPythonPackage`](#buildpythonpackage-function). The expression of a library should be in
1993 `pkgs/development/python-modules/<name>/default.nix`.
1994* Python applications live outside of `python-packages.nix` and are packaged
1995 with [`buildPythonApplication`](#buildpythonapplication-function).
1996* Make sure libraries build for all Python interpreters.
1997* By default we enable tests. Make sure the tests are found and, in the case of
1998 libraries, are passing for all interpreters. If certain tests fail they can be
1999 disabled individually. Try to avoid disabling the tests altogether. In any
2000 case, when you disable tests, leave a comment explaining why.
2001* Commit names of Python libraries should reflect that they are Python
2002 libraries, so write for example `python311Packages.numpy: 1.11 -> 1.12`.
2003 It is highly recommended to specify the current default version to enable
2004 automatic build by ofborg.
2005* Attribute names in `python-packages.nix` as well as `pname`s should match the
2006 library's name on PyPI, but be normalized according to [PEP
2007 0503](https://www.python.org/dev/peps/pep-0503/#normalized-names). This means
2008 that characters should be converted to lowercase and `.` and `_` should be
2009 replaced by a single `-` (foo-bar-baz instead of Foo__Bar.baz).
2010 If necessary, `pname` has to be given a different value within `fetchPypi`.
2011* Packages from sources such as GitHub and GitLab that do not exist on PyPI
2012 should not use a name that is already used on PyPI. When possible, they should
2013 use the package repository name prefixed with the owner (e.g. organization) name
2014 and using a `-` as delimiter.
2015* Attribute names in `python-packages.nix` should be sorted alphanumerically to
2016 avoid merge conflicts and ease locating attributes.
2017
2018## Package set maintenance {#python-package-set-maintenance}
2019
2020The whole Python package set has a lot of packages that do not see regular
2021updates, because they either are a very fragile component in the Python
2022ecosystem, like for example the `hypothesis` package, or packages that have
2023no maintainer, so maintenance falls back to the package set maintainers.
2024
2025### Updating packages in bulk {#python-package-bulk-updates}
2026
2027There is a tool to update alot of python libraries in bulk, it exists at
2028`maintainers/scripts/update-python-libraries` with this repository.
2029
2030It can quickly update minor or major versions for all packages selected
2031and create update commits, and supports the `fetchPypi`, `fetchurl` and
2032`fetchFromGitHub` fetchers. When updating lots of packages that are
2033hosted on GitHub, exporting a `GITHUB_API_TOKEN` is highly recommended.
2034
2035Updating packages in bulk leads to lots of breakages, which is why a
2036stabilization period on the `python-updates` branch is required.
2037
2038If a package is fragile and often breaks during these bulks updates, it
2039may be reasonable to set `passthru.skipBulkUpdate = true` in the
2040derivation. This decision should not be made on a whim and should
2041always be supported by a qualifying comment.
2042
2043Once the branch is sufficiently stable it should normally be merged
2044into the `staging` branch.
2045
2046An exemplary call to update all python libraries between minor versions
2047would be:
2048
2049```ShellSession
2050$ maintainers/scripts/update-python-libraries --target minor --commit --use-pkgs-prefix pkgs/development/python-modules/**/default.nix
2051```
2052
2053## CPython Update Schedule {#python-cpython-update-schedule}
2054
2055With [PEP 602](https://www.python.org/dev/peps/pep-0602/), CPython now
2056follows a yearly release cadence. In nixpkgs, all supported interpreters
2057are made available, but only the most recent two
2058interpreters package sets are built; this is a compromise between being
2059the latest interpreter, and what the majority of the Python packages support.
2060
2061New CPython interpreters are released in October. Generally, it takes some
2062time for the majority of active Python projects to support the latest stable
2063interpreter. To help ease the migration for Nixpkgs users
2064between Python interpreters the schedule below will be used:
2065
2066| When | Event |
2067| --- | --- |
2068| After YY.11 Release | Bump CPython package set window. The latest and previous latest stable should now be built. |
2069| After YY.05 Release | Bump default CPython interpreter to latest stable. |
2070
2071In practice, this means that the Python community will have had a stable interpreter
2072for ~2 months before attempting to update the package set. And this will
2073allow for ~7 months for Python applications to support the latest interpreter.