1# Python
2
3## User Guide
4
5### Using Python
6
7#### Overview
8
9Several versions of the Python interpreter are available on Nix, as well as a
10high amount of packages. The attribute `python` refers to the default
11interpreter, which is currently CPython 2.7. It is also possible to refer to
12specific versions, e.g. `python38` refers to CPython 3.8, and `pypy` refers to
13the default PyPy interpreter.
14
15Python is used a lot, and in different ways. This affects also how it is
16packaged. In the case of Python on Nix, an important distinction is made between
17whether the package is considered primarily an application, or whether it should
18be used as a library, i.e., of primary interest are the modules in
19`site-packages` that should be importable.
20
21In the Nixpkgs tree Python applications can be found throughout, depending on
22what they do, and are called from the main package set. Python libraries,
23however, are in separate sets, with one set per interpreter version.
24
25The interpreters have several common attributes. One of these attributes is
26`pkgs`, which is a package set of Python libraries for this specific
27interpreter. E.g., the `toolz` package corresponding to the default interpreter
28is `python.pkgs.toolz`, and the CPython 3.8 version is `python38.pkgs.toolz`.
29The main package set contains aliases to these package sets, e.g.
30`pythonPackages` refers to `python.pkgs` and `python38Packages` to
31`python38.pkgs`.
32
33#### Installing Python and packages
34
35The Nix and NixOS manuals explain how packages are generally installed. In the
36case of Python and Nix, it is important to make a distinction between whether the
37package is considered an application or a library.
38
39Applications on Nix are typically installed into your user profile imperatively
40using `nix-env -i`, and on NixOS declaratively by adding the package name to
41`environment.systemPackages` in `/etc/nixos/configuration.nix`. Dependencies
42such as libraries are automatically installed and should not be installed
43explicitly.
44
45The same goes for Python applications. Python applications can be installed in
46your profile, and will be wrapped to find their exact library dependencies,
47without impacting other applications or polluting your user environment.
48
49But Python libraries you would like to use for development cannot be installed,
50at least not individually, because they won't be able to find each other
51resulting in import errors. Instead, it is possible to create an environment
52with `python.buildEnv` or `python.withPackages` where the interpreter and other
53executables are wrapped to be able to find each other and all of the modules.
54
55In the following examples we will start by creating a simple, ad-hoc environment
56with a nix-shell that has `numpy` and `toolz` in Python 3.8; then we will create
57a re-usable environment in a single-file Python script; then we will create a
58full Python environment for development with this same environment.
59
60Philosphically, this should be familiar to users who are used to a `venv` style
61of development: individual projects create their own Python environments without
62impacting the global environment or each other.
63
64#### Ad-hoc temporary Python environment with `nix-shell`
65
66The simplest way to start playing with the way nix wraps and sets up Python
67environments is with `nix-shell` at the cmdline. These environments create a
68temporary shell session with a Python and a *precise* list of packages (plus
69their runtime dependencies), with no other Python packages in the Python
70interpreter's scope.
71
72To create a Python 3.8 session with `numpy` and `toolz` available, run:
73
74```sh
75$ nix-shell -p 'python38.withPackages(ps: with ps; [ numpy toolz ])'
76```
77
78By default `nix-shell` will start a `bash` session with this interpreter in our
79`PATH`, so if we then run:
80
81```
82[nix-shell:~/src/nixpkgs]$ python3
83Python 3.8.1 (default, Dec 18 2019, 19:06:26)
84[GCC 9.2.0] on linux
85Type "help", "copyright", "credits" or "license" for more information.
86>>> import numpy; import toolz
87```
88
89Note that no other modules are in scope, even if they were imperatively
90installed into our user environment as a dependency of a Python application:
91
92```
93>>> import requests
94Traceback (most recent call last):
95 File "<stdin>", line 1, in <module>
96ModuleNotFoundError: No module named 'requests'
97```
98
99We can add as many additional modules onto the `nix-shell` as we need, and we
100will still get 1 wrapped Python interpreter. We can start the interpreter
101directly like so:
102
103```sh
104$ nix-shell -p 'python38.withPackages(ps: with ps; [ numpy toolz requests ])' --run python3
105these derivations will be built:
106 /nix/store/xbdsrqrsfa1yva5s7pzsra8k08gxlbz1-python3-3.8.1-env.drv
107building '/nix/store/xbdsrqrsfa1yva5s7pzsra8k08gxlbz1-python3-3.8.1-env.drv'...
108created 277 symlinks in user environment
109Python 3.8.1 (default, Dec 18 2019, 19:06:26)
110[GCC 9.2.0] on linux
111Type "help", "copyright", "credits" or "license" for more information.
112>>> import requests
113>>>
114```
115
116Notice that this time it built a new Python environment, which now includes
117`requests`. Building an environment just creates wrapper scripts that expose the
118selected dependencies to the interpreter while re-using the actual modules. This
119means if any other env has installed `requests` or `numpy` in a different
120context, we don't need to recompile them -- we just recompile the wrapper script
121that sets up an interpreter pointing to them. This matters much more for "big"
122modules like `pytorch` or `tensorflow`.
123
124Module names usually match their names on [pypi.org](https://pypi.org/), but
125you can use the [Nixpkgs search website](https://nixos.org/nixos/packages.html)
126to find them as well (along with non-python packages).
127
128At this point we can create throwaway experimental Python environments with
129arbitrary dependencies. This is a good way to get a feel for how the Python
130interpreter and dependencies work in Nix and NixOS, but to do some actual
131development, we'll want to make it a bit more persistent.
132
133##### Running Python scripts and using `nix-shell` as shebang
134
135Sometimes, we have a script whose header looks like this:
136
137```python
138#!/usr/bin/env python3
139import numpy as np
140a = np.array([1,2])
141b = np.array([3,4])
142print(f"The dot product of {a} and {b} is: {np.dot(a, b)}")
143```
144
145Executing this script requires a `python3` that has `numpy`. Using what we learned
146in the previous section, we could startup a shell and just run it like so:
147
148```
149nix-shell -p 'python38.withPackages(ps: with ps; [ numpy ])' --run 'python3 foo.py'
150The dot product of [1 2] and [3 4] is: 11
151```
152
153But if we maintain the script ourselves, and if there are more dependencies, it
154may be nice to encode those dependencies in source to make the script re-usable
155without that bit of knowledge. That can be done by using `nix-shell` as a
156[shebang](https://en.wikipedia.org/wiki/Shebang_(Unix), like so:
157
158```python
159#!/usr/bin/env nix-shell
160#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.numpy ])"
161import numpy as np
162a = np.array([1,2])
163b = np.array([3,4])
164print(f"The dot product of {a} and {b} is: {np.dot(a, b)}")
165```
166
167Then we simply execute it, without requiring any environment setup at all!
168
169```sh
170$ ./foo.py
171The dot product of [1 2] and [3 4] is: 11
172```
173
174If the dependencies are not available on the host where `foo.py` is executed, it
175will build or download them from a Nix binary cache prior to starting up, prior
176that it is executed on a machine with a multi-user nix installation.
177
178This provides a way to ship a self bootstrapping Python script, akin to a
179statically linked binary, where it can be run on any machine (provided nix is
180installed) without having to assume that `numpy` is installed globally on the
181system.
182
183By default it is pulling the import checkout of Nixpkgs itself from our nix
184channel, which is nice as it cache aligns with our other package builds, but we
185can make it fully reproducible by pinning the `nixpkgs` import:
186
187```python
188#!/usr/bin/env nix-shell
189#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.numpy ])"
190#!nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/d373d80b1207d52621961b16aa4a3438e4f98167.tar.gz
191import numpy as np
192a = np.array([1,2])
193b = np.array([3,4])
194print(f"The dot product of {a} and {b} is: {np.dot(a, b)}")
195```
196
197This will execute with the exact same versions of Python 3.8, numpy, and system
198dependencies a year from now as it does today, because it will always use
199exactly git commit `d373d80b1207d52621961b16aa4a3438e4f98167` of Nixpkgs for all
200of the package versions.
201
202This is also a great way to ensure the script executes identically on different
203servers.
204
205##### Load environment from `.nix` expression
206
207We've now seen how to create an ad-hoc temporary shell session, and how to
208create a single script with Python dependencies, but in the course of normal
209development we're usually working in an entire package repository.
210
211As explained in the Nix manual, `nix-shell` can also load an expression from a
212`.nix` file. Say we want to have Python 3.8, `numpy` and `toolz`, like before,
213in an environment. We can add a `shell.nix` file describing our dependencies:
214
215```nix
216with import <nixpkgs> {};
217(python38.withPackages (ps: [ps.numpy ps.toolz])).env
218```
219
220And then at the command line, just typing `nix-shell` produces the same
221environment as before. In a normal project, we'll likely have many more
222dependencies; this can provide a way for developers to share the environments
223with each other and with CI builders.
224
225What's happening here?
226
2271. We begin with importing the Nix Packages collections. `import <nixpkgs>`
228 imports the `<nixpkgs>` function, `{}` calls it and the `with` statement
229 brings all attributes of `nixpkgs` in the local scope. These attributes form
230 the main package set.
2312. Then we create a Python 3.8 environment with the `withPackages` function, as before.
2323. The `withPackages` function expects us to provide a function as an argument
233 that takes the set of all Python packages and returns a list of packages to
234 include in the environment. Here, we select the packages `numpy` and `toolz`
235 from the package set.
236
237To combine this with `mkShell` you can:
238
239```nix
240with import <nixpkgs> {};
241let
242 pythonEnv = python38.withPackages (ps: [
243 ps.numpy
244 ps.toolz
245 ]);
246in mkShell {
247 buildInputs = [
248 pythonEnv
249
250 black
251 mypy
252
253 libffi
254 openssl
255 ];
256}
257```
258
259This will create a unified environment that has not just our Python interpreter
260and its Python dependencies, but also tools like `black` or `mypy` and libraries
261like `libffi` the `openssl` in scope. This is generic and can span any number of
262tools or languages across the Nixpkgs ecosystem.
263
264##### Installing environments globally on the system
265
266Up to now, we've been creating environments scoped to an ad-hoc shell session,
267or a single script, or a single project. This is generally advisable, as it
268avoids pollution across contexts.
269
270However, sometimes we know we will often want a Python with some basic packages,
271and want this available without having to enter into a shell or build context.
272This can be useful to have things like vim/emacs editors and plugins or shell
273tools "just work" without having to set them up, or when running other software
274that expects packages to be installed globally.
275
276To create your own custom environment, create a file in `~/.config/nixpkgs/overlays/`
277that looks like this:
278
279```nix
280# ~/.config/nixpkgs/overlays/myEnv.nix
281self: super: {
282 myEnv = super.buildEnv {
283 name = "myEnv";
284 paths = [
285 # A Python 3 interpreter with some packages
286 (self.python3.withPackages (
287 ps: with ps; [
288 pyflakes
289 pytest
290 python-language-server
291 ]
292 ))
293
294 # Some other packages we'd like as part of this env
295 self.mypy
296 self.black
297 self.ripgrep
298 self.tmux
299 ];
300 };
301}
302```
303
304You can then build and install this to your profile with:
305
306```sh
307nix-env -iA myEnv
308```
309
310One limitation of this is that you can only have 1 Python env installed
311globally, since they conflict on the `python` to load out of your `PATH`.
312
313If you get a conflict or prefer to keep the setup clean, you can have `nix-env`
314atomically *uninstall* all other imperatively installed packages and replace
315your profile with just `myEnv` by using the `--replace` flag.
316
317##### Environment defined in `/etc/nixos/configuration.nix`
318
319For the sake of completeness, here's how to install the environment system-wide
320on NixOS.
321
322```nix
323{ # ...
324
325 environment.systemPackages = with pkgs; [
326 (python38.withPackages(ps: with ps; [ numpy toolz ]))
327 ];
328}
329```
330
331### Developing with Python
332
333Above, we were mostly just focused on use cases and what to do to get started
334creating working Python environments in nix.
335
336Now that you know the basics to be up and running, it is time to take a step
337back and take a deeper look at at how Python packages are packaged on Nix. Then,
338we will look at how you can use development mode with your code.
339
340#### Python library packages in Nixpkgs
341
342With Nix all packages are built by functions. The main function in Nix for
343building Python libraries is `buildPythonPackage`. Let's see how we can build the
344`toolz` package.
345
346```nix
347{ lib, buildPythonPackage, fetchPypi }:
348
349buildPythonPackage rec {
350 pname = "toolz";
351 version = "0.10.0";
352
353 src = fetchPypi {
354 inherit pname version;
355 sha256 = "08fdd5ef7c96480ad11c12d472de21acd32359996f69a5259299b540feba4560";
356 };
357
358 doCheck = false;
359
360 meta = with lib; {
361 homepage = "https://github.com/pytoolz/toolz";
362 description = "List processing tools and functional utilities";
363 license = licenses.bsd3;
364 maintainers = with maintainers; [ fridh ];
365 };
366}
367```
368
369What happens here? The function `buildPythonPackage` is called and as argument
370it accepts a set. In this case the set is a recursive set, `rec`. One of the
371arguments is the name of the package, which consists of a basename (generally
372following the name on PyPi) and a version. Another argument, `src` specifies the
373source, which in this case is fetched from PyPI using the helper function
374`fetchPypi`. The argument `doCheck` is used to set whether tests should be run
375when building the package. Furthermore, we specify some (optional) meta
376information. The output of the function is a derivation.
377
378An expression for `toolz` can be found in the Nixpkgs repository. As explained
379in the introduction of this Python section, a derivation of `toolz` is available
380for each interpreter version, e.g. `python38.pkgs.toolz` refers to the `toolz`
381derivation corresponding to the CPython 3.8 interpreter.
382
383The above example works when you're directly working on
384`pkgs/top-level/python-packages.nix` in the Nixpkgs repository. Often though,
385you will want to test a Nix expression outside of the Nixpkgs tree.
386
387The following expression creates a derivation for the `toolz` package,
388and adds it along with a `numpy` package to a Python environment.
389
390```nix
391with import <nixpkgs> {};
392
393( let
394 my_toolz = python38.pkgs.buildPythonPackage rec {
395 pname = "toolz";
396 version = "0.10.0";
397
398 src = python38.pkgs.fetchPypi {
399 inherit pname version;
400 sha256 = "08fdd5ef7c96480ad11c12d472de21acd32359996f69a5259299b540feba4560";
401 };
402
403 doCheck = false;
404
405 meta = {
406 homepage = "https://github.com/pytoolz/toolz/";
407 description = "List processing tools and functional utilities";
408 };
409 };
410
411 in python38.withPackages (ps: [ps.numpy my_toolz])
412).env
413```
414
415Executing `nix-shell` will result in an environment in which you can use
416Python 3.8 and the `toolz` package. As you can see we had to explicitly mention
417for which Python version we want to build a package.
418
419So, what did we do here? Well, we took the Nix expression that we used earlier
420to build a Python environment, and said that we wanted to include our own
421version of `toolz`, named `my_toolz`. To introduce our own package in the scope
422of `withPackages` we used a `let` expression. You can see that we used
423`ps.numpy` to select numpy from the nixpkgs package set (`ps`). We did not take
424`toolz` from the Nixpkgs package set this time, but instead took our own version
425that we introduced with the `let` expression.
426
427#### Handling dependencies
428
429Our example, `toolz`, does not have any dependencies on other Python packages or
430system libraries. According to the manual, `buildPythonPackage` uses the
431arguments `buildInputs` and `propagatedBuildInputs` to specify dependencies. If
432something is exclusively a build-time dependency, then the dependency should be
433included in `buildInputs`, but if it is (also) a runtime dependency, then it
434should be added to `propagatedBuildInputs`. Test dependencies are considered
435build-time dependencies and passed to `checkInputs`.
436
437The following example shows which arguments are given to `buildPythonPackage` in
438order to build [`datashape`](https://github.com/blaze/datashape).
439
440```nix
441{ lib, buildPythonPackage, fetchPypi, numpy, multipledispatch, dateutil, pytest }:
442
443buildPythonPackage rec {
444 pname = "datashape";
445 version = "0.4.7";
446
447 src = fetchPypi {
448 inherit pname version;
449 sha256 = "14b2ef766d4c9652ab813182e866f493475e65e558bed0822e38bf07bba1a278";
450 };
451
452 checkInputs = [ pytest ];
453 propagatedBuildInputs = [ numpy multipledispatch dateutil ];
454
455 meta = with lib; {
456 homepage = "https://github.com/ContinuumIO/datashape";
457 description = "A data description language";
458 license = licenses.bsd2;
459 maintainers = with maintainers; [ fridh ];
460 };
461}
462```
463
464We can see several runtime dependencies, `numpy`, `multipledispatch`, and
465`dateutil`. Furthermore, we have one `checkInputs`, i.e. `pytest`. `pytest` is a
466test runner and is only used during the `checkPhase` and is therefore not added
467to `propagatedBuildInputs`.
468
469In the previous case we had only dependencies on other Python packages to consider.
470Occasionally you have also system libraries to consider. E.g., `lxml` provides
471Python bindings to `libxml2` and `libxslt`. These libraries are only required
472when building the bindings and are therefore added as `buildInputs`.
473
474```nix
475{ lib, pkgs, buildPythonPackage, fetchPypi }:
476
477buildPythonPackage rec {
478 pname = "lxml";
479 version = "3.4.4";
480
481 src = fetchPypi {
482 inherit pname version;
483 sha256 = "16a0fa97hym9ysdk3rmqz32xdjqmy4w34ld3rm3jf5viqjx65lxk";
484 };
485
486 buildInputs = [ pkgs.libxml2 pkgs.libxslt ];
487
488 meta = with lib; {
489 description = "Pythonic binding for the libxml2 and libxslt libraries";
490 homepage = "https://lxml.de";
491 license = licenses.bsd3;
492 maintainers = with maintainers; [ sjourdois ];
493 };
494}
495```
496
497In this example `lxml` and Nix are able to work out exactly where the relevant
498files of the dependencies are. This is not always the case.
499
500The example below shows bindings to The Fastest Fourier Transform in the West,
501commonly known as FFTW. On Nix we have separate packages of FFTW for the
502different types of floats (`"single"`, `"double"`, `"long-double"`). The
503bindings need all three types, and therefore we add all three as `buildInputs`.
504The bindings don't expect to find each of them in a different folder, and
505therefore we have to set `LDFLAGS` and `CFLAGS`.
506
507```nix
508{ lib, pkgs, buildPythonPackage, fetchPypi, numpy, scipy }:
509
510buildPythonPackage rec {
511 pname = "pyFFTW";
512 version = "0.9.2";
513
514 src = fetchPypi {
515 inherit pname version;
516 sha256 = "f6bbb6afa93085409ab24885a1a3cdb8909f095a142f4d49e346f2bd1b789074";
517 };
518
519 buildInputs = [ pkgs.fftw pkgs.fftwFloat pkgs.fftwLongDouble];
520
521 propagatedBuildInputs = [ numpy scipy ];
522
523 # Tests cannot import pyfftw. pyfftw works fine though.
524 doCheck = false;
525
526 preConfigure = ''
527 export LDFLAGS="-L${pkgs.fftw.dev}/lib -L${pkgs.fftwFloat.out}/lib -L${pkgs.fftwLongDouble.out}/lib"
528 export CFLAGS="-I${pkgs.fftw.dev}/include -I${pkgs.fftwFloat.dev}/include -I${pkgs.fftwLongDouble.dev}/include"
529 '';
530
531 meta = with lib; {
532 description = "A pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms";
533 homepage = "http://hgomersall.github.com/pyFFTW";
534 license = with licenses; [ bsd2 bsd3 ];
535 maintainers = with maintainers; [ fridh ];
536 };
537}
538```
539Note also the line `doCheck = false;`, we explicitly disabled running the test-suite.
540
541#### Testing Python Packages
542
543It is highly encouraged to have testing as part of the package build. This
544helps to avoid situations where the package was able to build and install,
545but is not usable at runtime. Currently, all packages will use the `test`
546command provided by the setup.py (i.e. `python setup.py test`). However,
547this is currently deprecated https://github.com/pypa/setuptools/pull/1878
548and your package should provide its own checkPhase.
549
550*NOTE:* The `checkPhase` for python maps to the `installCheckPhase` on a
551normal derivation. This is due to many python packages not behaving well
552to the pre-installed version of the package. Version info, and natively
553compiled extensions generally only exist in the install directory, and
554thus can cause issues when a test suite asserts on that behavior.
555
556*NOTE:* Tests should only be disabled if they don't agree with nix
557(e.g. external dependencies, network access, flakey tests), however,
558as many tests should be enabled as possible. Failing tests can still be
559a good indication that the package is not in a valid state.
560
561#### Using pytest
562
563Pytest is the most common test runner for python repositories. A trivial
564test run would be:
565```
566 checkInputs = [ pytest ];
567 checkPhase = "pytest";
568```
569
570However, many repositories' test suites do not translate well to nix's build
571sandbox, and will generally need many tests to be disabled.
572
573To filter tests using pytest, one can do the following:
574```
575 checkInputs = [ pytest ];
576 # avoid tests which need additional data or touch network
577 checkPhase = ''
578 pytest tests/ --ignore=tests/integration -k 'not download and not update'
579 '';
580```
581
582`--ignore` will tell pytest to ignore that file or directory from being
583collected as part of a test run. This is useful is a file uses a package
584which is not available in nixpkgs, thus skipping that test file is much
585easier than having to create a new package.
586
587`-k` is used to define a predicate for test names. In this example, we are
588filtering out tests which contain `download` or `update` in their test case name.
589Only one `-k` argument is allows, and thus a long predicate should be concatenated
590with "\" and wrapped to the next line.
591
592*NOTE:* In pytest==6.0.1, the use of "\" to continue a line (e.g. `-k 'not download \'`) has
593been removed, in this case, it's recommended to use `pytestCheckHook`.
594
595#### Using pytestCheckHook
596
597`pytestCheckHook` is a convenient hook which will substitute the setuptools
598`test` command for a checkPhase which runs `pytest`. This is also beneficial
599when a package may need many items disabled to run the test suite.
600
601Using the example above, the analagous pytestCheckHook usage would be:
602```
603 checkInputs = [ pytestCheckHook ];
604
605 # requires additional data
606 pytestFlagsArray = [ "tests/" "--ignore=tests/integration" ];
607
608 disabledTests = [
609 # touches network
610 "download"
611 "update"
612 ];
613```
614
615This is expecially useful when tests need to be conditionallydisabled,
616for example:
617
618```
619 disabledTests = [
620 # touches network
621 "download"
622 "update"
623 ] ++ lib.optionals (pythonAtLeast "3.8") [
624 # broken due to python3.8 async changes
625 "async"
626 ] ++ lib.optionals stdenv.isDarwin [
627 # can fail when building with other packages
628 "socket"
629 ];
630```
631Trying to concatenate the related strings to disable tests in a regular checkPhase
632would be much harder to read. This also enables us to comment on why specific tests
633are disabled.
634
635#### Using pythonImportsCheck
636
637Although unit tests are highly prefered to valid correctness of a package. Not
638all packages have test suites that can be ran easily, and some have none at all.
639To help ensure the package still works, `pythonImportsCheck` can attempt to import
640the listed modules.
641
642```
643 pythonImportsCheck = [ "requests" "urllib" ];
644```
645roughly translates to:
646```
647 postCheck = ''
648 PYTHONPATH=$out/${python.sitePackages}:$PYTHONPATH
649 python -c "import requests; import urllib"
650 '';
651```
652However, this is done in it's own phase, and not dependent on whether `doCheck = true;`
653
654This can also be useful in verifying that the package doesn't assume commonly
655present packages (e.g. `setuptools`)
656
657### Develop local package
658
659As a Python developer you're likely aware of [development mode](http://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode)
660(`python setup.py develop`); instead of installing the package this command
661creates a special link to the project code. That way, you can run updated code
662without having to reinstall after each and every change you make. Development
663mode is also available. Let's see how you can use it.
664
665In the previous Nix expression the source was fetched from an url. We can also
666refer to a local source instead using `src = ./path/to/source/tree;`
667
668If we create a `shell.nix` file which calls `buildPythonPackage`, and if `src`
669is a local source, and if the local source has a `setup.py`, then development
670mode is activated.
671
672In the following example we create a simple environment that has a Python 3.8
673version of our package in it, as well as its dependencies and other packages we
674like to have in the environment, all specified with `propagatedBuildInputs`.
675Indeed, we can just add any package we like to have in our environment to
676`propagatedBuildInputs`.
677
678```nix
679with import <nixpkgs> {};
680with python38Packages;
681
682buildPythonPackage rec {
683 name = "mypackage";
684 src = ./path/to/package/source;
685 propagatedBuildInputs = [ pytest numpy pkgs.libsndfile ];
686}
687```
688
689It is important to note that due to how development mode is implemented on Nix
690it is not possible to have multiple packages simultaneously in development mode.
691
692### Organising your packages
693
694So far we discussed how you can use Python on Nix, and how you can develop with
695it. We've looked at how you write expressions to package Python packages, and we
696looked at how you can create environments in which specified packages are
697available.
698
699At some point you'll likely have multiple packages which you would
700like to be able to use in different projects. In order to minimise unnecessary
701duplication we now look at how you can maintain a repository with your
702own packages. The important functions here are `import` and `callPackage`.
703
704### Including a derivation using `callPackage`
705
706Earlier we created a Python environment using `withPackages`, and included the
707`toolz` package via a `let` expression.
708Let's split the package definition from the environment definition.
709
710We first create a function that builds `toolz` in `~/path/to/toolz/release.nix`
711
712```nix
713{ lib, buildPythonPackage }:
714
715buildPythonPackage rec {
716 pname = "toolz";
717 version = "0.10.0";
718
719 src = fetchPypi {
720 inherit pname version;
721 sha256 = "08fdd5ef7c96480ad11c12d472de21acd32359996f69a5259299b540feba4560";
722 };
723
724 meta = with lib; {
725 homepage = "https://github.com/pytoolz/toolz/";
726 description = "List processing tools and functional utilities";
727 license = licenses.bsd3;
728 maintainers = with maintainers; [ fridh ];
729 };
730}
731```
732
733It takes an argument `buildPythonPackage`. We now call this function using
734`callPackage` in the definition of our environment
735
736```nix
737with import <nixpkgs> {};
738
739( let
740 toolz = callPackage /path/to/toolz/release.nix {
741 buildPythonPackage = python38Packages.buildPythonPackage;
742 };
743 in python38.withPackages (ps: [ ps.numpy toolz ])
744).env
745```
746
747Important to remember is that the Python version for which the package is made
748depends on the `python` derivation that is passed to `buildPythonPackage`. Nix
749tries to automatically pass arguments when possible, which is why generally you
750don't explicitly define which `python` derivation should be used. In the above
751example we use `buildPythonPackage` that is part of the set `python38Packages`,
752and in this case the `python38` interpreter is automatically used.
753
754## Reference
755
756### Interpreters
757
758Versions 2.7, 3.6, 3.7, 3.8 and 3.9 of the CPython interpreter are available as
759respectively `python27`, `python36`, `python37`, `python38` and `python39`. The
760aliases `python2` and `python3` correspond to respectively `python27` and
761`python38`. The default interpreter, `python`, maps to `python2`. The PyPy
762interpreters compatible with Python 2.7 and 3 are available as `pypy27` and
763`pypy3`, with aliases `pypy2` mapping to `pypy27` and `pypy` mapping to `pypy2`.
764The Nix expressions for the interpreters can be found in
765`pkgs/development/interpreters/python`.
766
767All packages depending on any Python interpreter get appended
768`out/{python.sitePackages}` to `$PYTHONPATH` if such directory
769exists.
770
771#### Missing `tkinter` module standard library
772
773To reduce closure size the `Tkinter`/`tkinter` is available as a separate package, `pythonPackages.tkinter`.
774
775#### Attributes on interpreters packages
776
777Each interpreter has the following attributes:
778
779- `libPrefix`. Name of the folder in `${python}/lib/` for corresponding interpreter.
780- `interpreter`. Alias for `${python}/bin/${executable}`.
781- `buildEnv`. Function to build python interpreter environments with extra packages bundled together. See section *python.buildEnv function* for usage and documentation.
782- `withPackages`. Simpler interface to `buildEnv`. See section *python.withPackages function* for usage and documentation.
783- `sitePackages`. Alias for `lib/${libPrefix}/site-packages`.
784- `executable`. Name of the interpreter executable, e.g. `python3.8`.
785- `pkgs`. Set of Python packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing `packageOverrides`.
786
787### Building packages and applications
788
789Python libraries and applications that use `setuptools` or
790`distutils` are typically built with respectively the `buildPythonPackage` and
791`buildPythonApplication` functions. These two functions also support installing a `wheel`.
792
793All Python packages reside in `pkgs/top-level/python-packages.nix` and all
794applications elsewhere. In case a package is used as both a library and an
795application, then the package should be in `pkgs/top-level/python-packages.nix`
796since only those packages are made available for all interpreter versions. The
797preferred location for library expressions is in
798`pkgs/development/python-modules`. It is important that these packages are
799called from `pkgs/top-level/python-packages.nix` and not elsewhere, to guarantee
800the right version of the package is built.
801
802Based on the packages defined in `pkgs/top-level/python-packages.nix` an
803attribute set is created for each available Python interpreter. The available
804sets are
805
806* `pkgs.python27Packages`
807* `pkgs.python36Packages`
808* `pkgs.python37Packages`
809* `pkgs.python38Packages`
810* `pkgs.python39Packages`
811* `pkgs.pypyPackages`
812
813and the aliases
814
815* `pkgs.python2Packages` pointing to `pkgs.python27Packages`
816* `pkgs.python3Packages` pointing to `pkgs.python38Packages`
817* `pkgs.pythonPackages` pointing to `pkgs.python2Packages`
818
819#### `buildPythonPackage` function
820
821The `buildPythonPackage` function is implemented in
822`pkgs/development/interpreters/python/mk-python-derivation`
823using setup hooks.
824
825The following is an example:
826
827```nix
828{ lib, buildPythonPackage, fetchPypi, hypothesis, setuptools_scm, attrs, py, setuptools, six, pluggy }:
829
830buildPythonPackage rec {
831 pname = "pytest";
832 version = "3.3.1";
833
834 src = fetchPypi {
835 inherit pname version;
836 sha256 = "cf8436dc59d8695346fcd3ab296de46425ecab00d64096cebe79fb51ecb2eb93";
837 };
838
839 postPatch = ''
840 # don't test bash builtins
841 rm testing/test_argcomplete.py
842 '';
843
844 checkInputs = [ hypothesis ];
845 nativeBuildInputs = [ setuptools_scm ];
846 propagatedBuildInputs = [ attrs py setuptools six pluggy ];
847
848 meta = with lib; {
849 maintainers = with maintainers; [ domenkozar lovek323 madjar lsix ];
850 description = "Framework for writing tests";
851 };
852}
853```
854
855The `buildPythonPackage` mainly does four things:
856
857* In the `buildPhase`, it calls `${python.interpreter} setup.py bdist_wheel` to
858 build a wheel binary zipfile.
859* In the `installPhase`, it installs the wheel file using `pip install *.whl`.
860* In the `postFixup` phase, the `wrapPythonPrograms` bash function is called to
861 wrap all programs in the `$out/bin/*` directory to include `$PATH`
862 environment variable and add dependent libraries to script's `sys.path`.
863* In the `installCheck` phase, `${python.interpreter} setup.py test` is ran.
864
865By default tests are run because `doCheck = true`. Test dependencies, like
866e.g. the test runner, should be added to `checkInputs`.
867
868By default `meta.platforms` is set to the same value
869as the interpreter unless overridden otherwise.
870
871##### `buildPythonPackage` parameters
872
873All parameters from `stdenv.mkDerivation` function are still supported. The
874following are specific to `buildPythonPackage`:
875
876* `catchConflicts ? true`: If `true`, abort package build if a package name
877 appears more than once in dependency tree. Default is `true`.
878* `disabled` ? false: If `true`, package is not built for the particular Python
879 interpreter version.
880* `dontWrapPythonPrograms ? false`: Skip wrapping of Python programs.
881* `permitUserSite ? false`: Skip setting the `PYTHONNOUSERSITE` environment
882 variable in wrapped programs.
883* `format ? "setuptools"`: Format of the source. Valid options are
884 `"setuptools"`, `"pyproject"`, `"flit"`, `"wheel"`, and `"other"`.
885 `"setuptools"` is for when the source has a `setup.py` and `setuptools` is
886 used to build a wheel, `flit`, in case `flit` should be used to build a wheel,
887 and `wheel` in case a wheel is provided. Use `other` when a custom
888 `buildPhase` and/or `installPhase` is needed.
889* `makeWrapperArgs ? []`: A list of strings. Arguments to be passed to
890 `makeWrapper`, which wraps generated binaries. By default, the arguments to
891 `makeWrapper` set `PATH` and `PYTHONPATH` environment variables before calling
892 the binary. Additional arguments here can allow a developer to set environment
893 variables which will be available when the binary is run. For example,
894 `makeWrapperArgs = ["--set FOO BAR" "--set BAZ QUX"]`.
895* `namePrefix`: Prepends text to `${name}` parameter. In case of libraries, this
896 defaults to `"python3.8-"` for Python 3.8, etc., and in case of applications
897 to `""`.
898* `pipInstallFlags ? []`: A list of strings. Arguments to be passed to `pip
899 install`. To pass options to `python setup.py install`, use
900 `--install-option`. E.g., `pipInstallFlags=["--install-option='--cpp_implementation'"]`.
901* `pythonPath ? []`: List of packages to be added into `$PYTHONPATH`. Packages
902 in `pythonPath` are not propagated (contrary to `propagatedBuildInputs`).
903* `preShellHook`: Hook to execute commands before `shellHook`.
904* `postShellHook`: Hook to execute commands after `shellHook`.
905* `removeBinByteCode ? true`: Remove bytecode from `/bin`. Bytecode is only
906 created when the filenames end with `.py`.
907* `setupPyGlobalFlags ? []`: List of flags passed to `setup.py` command.
908* `setupPyBuildFlags ? []`: List of flags passed to `setup.py build_ext` command.
909
910The `stdenv.mkDerivation` function accepts various parameters for describing
911build inputs (see "Specifying dependencies"). The following are of special
912interest for Python packages, either because these are primarily used, or
913because their behaviour is different:
914
915* `nativeBuildInputs ? []`: Build-time only dependencies. Typically executables
916 as well as the items listed in `setup_requires`.
917* `buildInputs ? []`: Build and/or run-time dependencies that need to be be
918 compiled for the host machine. Typically non-Python libraries which are being
919 linked.
920* `checkInputs ? []`: Dependencies needed for running the `checkPhase`. These
921 are added to `nativeBuildInputs` when `doCheck = true`. Items listed in
922 `tests_require` go here.
923* `propagatedBuildInputs ? []`: Aside from propagating dependencies,
924 `buildPythonPackage` also injects code into and wraps executables with the
925 paths included in this list. Items listed in `install_requires` go here.
926
927##### Overriding Python packages
928
929The `buildPythonPackage` function has a `overridePythonAttrs` method that can be
930used to override the package. In the following example we create an environment
931where we have the `blaze` package using an older version of `pandas`. We
932override first the Python interpreter and pass `packageOverrides` which contains
933the overrides for packages in the package set.
934
935```nix
936with import <nixpkgs> {};
937
938(let
939 python = let
940 packageOverrides = self: super: {
941 pandas = super.pandas.overridePythonAttrs(old: rec {
942 version = "0.19.1";
943 src = super.fetchPypi {
944 pname = "pandas";
945 inherit version;
946 sha256 = "08blshqj9zj1wyjhhw3kl2vas75vhhicvv72flvf1z3jvapgw295";
947 };
948 });
949 };
950 in pkgs.python3.override {inherit packageOverrides; self = python;};
951
952in python.withPackages(ps: [ps.blaze])).env
953```
954
955#### `buildPythonApplication` function
956
957The `buildPythonApplication` function is practically the same as
958`buildPythonPackage`. The main purpose of this function is to build a Python
959package where one is interested only in the executables, and not importable
960modules. For that reason, when adding this package to a `python.buildEnv`, the
961modules won't be made available.
962
963Another difference is that `buildPythonPackage` by default prefixes the names of
964the packages with the version of the interpreter. Because this is irrelevant for
965applications, the prefix is omitted.
966
967When packaging a Python application with `buildPythonApplication`, it should be
968called with `callPackage` and passed `python` or `pythonPackages` (possibly
969specifying an interpreter version), like this:
970
971```nix
972{ lib, python3Packages }:
973
974python3Packages.buildPythonApplication rec {
975 pname = "luigi";
976 version = "2.7.9";
977
978 src = python3Packages.fetchPypi {
979 inherit pname version;
980 sha256 = "035w8gqql36zlan0xjrzz9j4lh9hs0qrsgnbyw07qs7lnkvbdv9x";
981 };
982
983 propagatedBuildInputs = with python3Packages; [ tornado_4 python-daemon ];
984
985 meta = with lib; {
986 ...
987 };
988}
989```
990
991This is then added to `all-packages.nix` just as any other application would be.
992
993```nix
994luigi = callPackage ../applications/networking/cluster/luigi { };
995```
996
997Since the package is an application, a consumer doesn't need to care about
998Python versions or modules, which is why they don't go in `pythonPackages`.
999
1000#### `toPythonApplication` function
1001
1002A distinction is made between applications and libraries, however, sometimes a
1003package is used as both. In this case the package is added as a library to
1004`python-packages.nix` and as an application to `all-packages.nix`. To reduce
1005duplication the `toPythonApplication` can be used to convert a library to an
1006application.
1007
1008The Nix expression shall use `buildPythonPackage` and be called from
1009`python-packages.nix`. A reference shall be created from `all-packages.nix` to
1010the attribute in `python-packages.nix`, and the `toPythonApplication` shall be
1011applied to the reference:
1012```nix
1013youtube-dl = with pythonPackages; toPythonApplication youtube-dl;
1014```
1015
1016#### `toPythonModule` function
1017
1018In some cases, such as bindings, a package is created using
1019`stdenv.mkDerivation` and added as attribute in `all-packages.nix`. The Python
1020bindings should be made available from `python-packages.nix`. The
1021`toPythonModule` function takes a derivation and makes certain Python-specific
1022modifications.
1023
1024```nix
1025opencv = toPythonModule (pkgs.opencv.override {
1026 enablePython = true;
1027 pythonPackages = self;
1028});
1029```
1030
1031Do pay attention to passing in the right Python version!
1032
1033#### `python.buildEnv` function
1034
1035Python environments can be created using the low-level `pkgs.buildEnv` function.
1036This example shows how to create an environment that has the Pyramid Web Framework.
1037Saving the following as `default.nix`
1038
1039```nix
1040with import <nixpkgs> {};
1041
1042python.buildEnv.override {
1043 extraLibs = [ pythonPackages.pyramid ];
1044 ignoreCollisions = true;
1045}
1046```
1047
1048and running `nix-build` will create
1049
1050```
1051/nix/store/cf1xhjwzmdki7fasgr4kz6di72ykicl5-python-2.7.8-env
1052```
1053
1054with wrapped binaries in `bin/`.
1055
1056You can also use the `env` attribute to create local environments with needed
1057packages installed. This is somewhat comparable to `virtualenv`. For example,
1058running `nix-shell` with the following `shell.nix`
1059
1060```nix
1061with import <nixpkgs> {};
1062
1063(python3.buildEnv.override {
1064 extraLibs = with python3Packages; [ numpy requests ];
1065}).env
1066```
1067
1068will drop you into a shell where Python will have the
1069specified packages in its path.
1070
1071
1072##### `python.buildEnv` arguments
1073
1074* `extraLibs`: List of packages installed inside the environment.
1075* `postBuild`: Shell command executed after the build of environment.
1076* `ignoreCollisions`: Ignore file collisions inside the environment (default is `false`).
1077* `permitUserSite`: Skip setting the `PYTHONNOUSERSITE` environment variable in
1078 wrapped binaries in the environment.
1079
1080#### `python.withPackages` function
1081
1082The `python.withPackages` function provides a simpler interface to the `python.buildEnv` functionality.
1083It takes a function as an argument that is passed the set of python packages and returns the list
1084of the packages to be included in the environment. Using the `withPackages` function, the previous
1085example for the Pyramid Web Framework environment can be written like this:
1086
1087```nix
1088with import <nixpkgs> {};
1089
1090python.withPackages (ps: [ps.pyramid])
1091```
1092
1093`withPackages` passes the correct package set for the specific interpreter
1094version as an argument to the function. In the above example, `ps` equals
1095`pythonPackages`. But you can also easily switch to using python3:
1096
1097```nix
1098with import <nixpkgs> {};
1099
1100python3.withPackages (ps: [ps.pyramid])
1101```
1102
1103Now, `ps` is set to `python3Packages`, matching the version of the interpreter.
1104
1105As `python.withPackages` simply uses `python.buildEnv` under the hood, it also
1106supports the `env` attribute. The `shell.nix` file from the previous section can
1107thus be also written like this:
1108
1109```nix
1110with import <nixpkgs> {};
1111
1112(python38.withPackages (ps: [ps.numpy ps.requests])).env
1113```
1114
1115In contrast to `python.buildEnv`, `python.withPackages` does not support the
1116more advanced options such as `ignoreCollisions = true` or `postBuild`. If you
1117need them, you have to use `python.buildEnv`.
1118
1119Python 2 namespace packages may provide `__init__.py` that collide. In that case
1120`python.buildEnv` should be used with `ignoreCollisions = true`.
1121
1122#### Setup hooks
1123
1124The following are setup hooks specifically for Python packages. Most of these
1125are used in `buildPythonPackage`.
1126
1127- `eggUnpackhook` to move an egg to the correct folder so it can be installed
1128 with the `eggInstallHook`
1129- `eggBuildHook` to skip building for eggs.
1130- `eggInstallHook` to install eggs.
1131- `flitBuildHook` to build a wheel using `flit`.
1132- `pipBuildHook` to build a wheel using `pip` and PEP 517. Note a build system
1133 (e.g. `setuptools` or `flit`) should still be added as `nativeBuildInput`.
1134- `pipInstallHook` to install wheels.
1135- `pytestCheckHook` to run tests with `pytest`. See [example usage](#using-pytestcheckhook).
1136- `pythonCatchConflictsHook` to check whether a Python package is not already existing.
1137- `pythonImportsCheckHook` to check whether importing the listed modules works.
1138- `pythonRemoveBinBytecode` to remove bytecode from the `/bin` folder.
1139- `setuptoolsBuildHook` to build a wheel using `setuptools`.
1140- `setuptoolsCheckHook` to run tests with `python setup.py test`.
1141- `venvShellHook` to source a Python 3 `venv` at the `venvDir` location. A
1142 `venv` is created if it does not yet exist. `postVenvCreation` can be used to
1143 to run commands only after venv is first created.
1144- `wheelUnpackHook` to move a wheel to the correct folder so it can be installed
1145 with the `pipInstallHook`.
1146
1147### Development mode
1148
1149Development or editable mode is supported. To develop Python packages
1150`buildPythonPackage` has additional logic inside `shellPhase` to run `pip
1151install -e . --prefix $TMPDIR/`for the package.
1152
1153Warning: `shellPhase` is executed only if `setup.py` exists.
1154
1155Given a `default.nix`:
1156```nix
1157with import <nixpkgs> {};
1158
1159pythonPackages.buildPythonPackage {
1160 name = "myproject";
1161 buildInputs = with pythonPackages; [ pyramid ];
1162
1163 src = ./.;
1164}
1165```
1166
1167Running `nix-shell` with no arguments should give you the environment in which
1168the package would be built with `nix-build`.
1169
1170Shortcut to setup environments with C headers/libraries and Python packages:
1171
1172```shell
1173nix-shell -p pythonPackages.pyramid zlib libjpeg git
1174```
1175
1176Note: There is a boolean value `lib.inNixShell` set to `true` if nix-shell is invoked.
1177
1178### Tools
1179
1180Packages inside nixpkgs are written by hand. However many tools exist in
1181community to help save time. No tool is preferred at the moment.
1182
1183- [pypi2nix](https://github.com/nix-community/pypi2nix): Generate Nix
1184 expressions for your Python project. Note that [sharing derivations from
1185 pypi2nix with nixpkgs is possible but not
1186 encouraged](https://github.com/nix-community/pypi2nix/issues/222#issuecomment-443497376).
1187- [python2nix](https://github.com/proger/python2nix) by Vladimir Kirillov.
1188
1189### Deterministic builds
1190
1191The Python interpreters are now built deterministically. Minor modifications had
1192to be made to the interpreters in order to generate deterministic bytecode. This
1193has security implications and is relevant for those using Python in a
1194`nix-shell`.
1195
1196When the environment variable `DETERMINISTIC_BUILD` is set, all bytecode will
1197have timestamp 1. The `buildPythonPackage` function sets `DETERMINISTIC_BUILD=1`
1198and [PYTHONHASHSEED=0](https://docs.python.org/3.8/using/cmdline.html#envvar-PYTHONHASHSEED).
1199Both are also exported in `nix-shell`.
1200
1201### Automatic tests
1202
1203It is recommended to test packages as part of the build process.
1204Source distributions (`sdist`) often include test files, but not always.
1205
1206By default the command `python setup.py test` is run as part of the
1207`checkPhase`, but often it is necessary to pass a custom `checkPhase`. An
1208example of such a situation is when `py.test` is used.
1209
1210#### Common issues
1211
1212* Non-working tests can often be deselected. By default `buildPythonPackage`
1213 runs `python setup.py test`. Most Python modules follows the standard test
1214 protocol where the pytest runner can be used instead. `py.test` supports a
1215 `-k` parameter to ignore test methods or classes:
1216
1217 ```nix
1218 buildPythonPackage {
1219 # ...
1220 # assumes the tests are located in tests
1221 checkInputs = [ pytest ];
1222 checkPhase = ''
1223 py.test -k 'not function_name and not other_function' tests
1224 '';
1225 }
1226 ```
1227* Tests that attempt to access `$HOME` can be fixed by using the following
1228 work-around before running tests (e.g. `preCheck`): `export HOME=$(mktemp -d)`
1229
1230## FAQ
1231
1232### How to solve circular dependencies?
1233
1234Consider the packages `A` and `B` that depend on each other. When packaging `B`,
1235a solution is to override package `A` not to depend on `B` as an input. The same
1236should also be done when packaging `A`.
1237
1238### How to override a Python package?
1239
1240We can override the interpreter and pass `packageOverrides`. In the following
1241example we rename the `pandas` package and build it.
1242
1243```nix
1244with import <nixpkgs> {};
1245
1246(let
1247 python = let
1248 packageOverrides = self: super: {
1249 pandas = super.pandas.overridePythonAttrs(old: {name="foo";});
1250 };
1251 in pkgs.python38.override {inherit packageOverrides;};
1252
1253in python.withPackages(ps: [ps.pandas])).env
1254```
1255
1256Using `nix-build` on this expression will build an environment that contains the
1257package `pandas` but with the new name `foo`.
1258
1259All packages in the package set will use the renamed package. A typical use case
1260is to switch to another version of a certain package. For example, in the
1261Nixpkgs repository we have multiple versions of `django` and `scipy`. In the
1262following example we use a different version of `scipy` and create an
1263environment that uses it. All packages in the Python package set will now use
1264the updated `scipy` version.
1265
1266```nix
1267with import <nixpkgs> {};
1268
1269( let
1270 packageOverrides = self: super: {
1271 scipy = super.scipy_0_17;
1272 };
1273 in (pkgs.python38.override {inherit packageOverrides;}).withPackages (ps: [ps.blaze])
1274).env
1275```
1276
1277The requested package `blaze` depends on `pandas` which itself depends on `scipy`.
1278
1279If you want the whole of Nixpkgs to use your modifications, then you can use
1280`overlays` as explained in this manual. In the following example we build a
1281`inkscape` using a different version of `numpy`.
1282
1283```nix
1284let
1285 pkgs = import <nixpkgs> {};
1286 newpkgs = import pkgs.path { overlays = [ (self: super: {
1287 python38 = let
1288 packageOverrides = python-self: python-super: {
1289 numpy = python-super.numpy_1_18;
1290 };
1291 in super.python38.override {inherit packageOverrides;};
1292 } ) ]; };
1293in newpkgs.inkscape
1294```
1295
1296### `python setup.py bdist_wheel` cannot create .whl
1297
1298Executing `python setup.py bdist_wheel` in a `nix-shell `fails with
1299```
1300ValueError: ZIP does not support timestamps before 1980
1301```
1302
1303This is because files from the Nix store (which have a timestamp of the UNIX
1304epoch of January 1, 1970) are included in the .ZIP, but .ZIP archives follow the
1305DOS convention of counting timestamps from 1980.
1306
1307The command `bdist_wheel` reads the `SOURCE_DATE_EPOCH` environment variable,
1308which `nix-shell` sets to 1. Unsetting this variable or giving it a value
1309corresponding to 1980 or later enables building wheels.
1310
1311Use 1980 as timestamp:
1312
1313```shell
1314nix-shell --run "SOURCE_DATE_EPOCH=315532800 python3 setup.py bdist_wheel"
1315```
1316
1317or the current time:
1318
1319```shell
1320nix-shell --run "SOURCE_DATE_EPOCH=$(date +%s) python3 setup.py bdist_wheel"
1321```
1322
1323or unset `SOURCE_DATE_EPOCH`:
1324
1325```shell
1326nix-shell --run "unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"
1327```
1328
1329### `install_data` / `data_files` problems
1330
1331If you get the following error:
1332
1333```
1334could not create '/nix/store/6l1bvljpy8gazlsw2aw9skwwp4pmvyxw-python-2.7.8/etc':
1335Permission denied
1336```
1337
1338This is a [known bug](https://github.com/pypa/setuptools/issues/130) in
1339`setuptools`. Setuptools `install_data` does not respect `--prefix`. An example
1340of such package using the feature is `pkgs/tools/X11/xpra/default.nix`.
1341
1342As workaround install it as an extra `preInstall` step:
1343
1344```shell
1345${python.interpreter} setup.py install_data --install-dir=$out --root=$out
1346sed -i '/ = data\_files/d' setup.py
1347```
1348
1349### Rationale of non-existent global site-packages
1350
1351On most operating systems a global `site-packages` is maintained. This however
1352becomes problematic if you want to run multiple Python versions or have multiple
1353versions of certain libraries for your projects. Generally, you would solve such
1354issues by creating virtual environments using `virtualenv`.
1355
1356On Nix each package has an isolated dependency tree which, in the case of
1357Python, guarantees the right versions of the interpreter and libraries or
1358packages are available. There is therefore no need to maintain a global `site-packages`.
1359
1360If you want to create a Python environment for development, then the recommended
1361method is to use `nix-shell`, either with or without the `python.buildEnv`
1362function.
1363
1364### How to consume Python modules using pip in a virtual environment like I am used to on other Operating Systems?
1365
1366While this approach is not very idiomatic from Nix perspective, it can still be
1367useful when dealing with pre-existing projects or in situations where it's not
1368feasible or desired to write derivations for all required dependencies.
1369
1370This is an example of a `default.nix` for a `nix-shell`, which allows to consume
1371a virtual environment created by `venv`, and install Python modules through
1372`pip` the traditional way.
1373
1374Create this `default.nix` file, together with a `requirements.txt` and simply
1375execute `nix-shell`.
1376
1377```nix
1378with import <nixpkgs> { };
1379
1380let
1381 pythonPackages = python3Packages;
1382in pkgs.mkShell rec {
1383 name = "impurePythonEnv";
1384 venvDir = "./.venv";
1385 buildInputs = [
1386 # A Python interpreter including the 'venv' module is required to bootstrap
1387 # the environment.
1388 pythonPackages.python
1389
1390 # This execute some shell code to initialize a venv in $venvDir before
1391 # dropping into the shell
1392 pythonPackages.venvShellHook
1393
1394 # Those are dependencies that we would like to use from nixpkgs, which will
1395 # add them to PYTHONPATH and thus make them accessible from within the venv.
1396 pythonPackages.numpy
1397 pythonPackages.requests
1398
1399 # In this particular example, in order to compile any binary extensions they may
1400 # require, the Python modules listed in the hypothetical requirements.txt need
1401 # the following packages to be installed locally:
1402 taglib
1403 openssl
1404 git
1405 libxml2
1406 libxslt
1407 libzip
1408 zlib
1409 ];
1410
1411 # Run this command, only after creating the virtual environment
1412 postVenvCreation = ''
1413 unset SOURCE_DATE_EPOCH
1414 pip install -r requirements.txt
1415 '';
1416
1417 # Now we can execute any commands within the virtual environment.
1418 # This is optional and can be left out to run pip manually.
1419 postShellHook = ''
1420 # allow pip to install wheels
1421 unset SOURCE_DATE_EPOCH
1422 '';
1423
1424}
1425```
1426
1427In case the supplied venvShellHook is insufficient, or when Python 2 support is
1428needed, you can define your own shell hook and adapt to your needs like in the
1429following example:
1430
1431```nix
1432with import <nixpkgs> { };
1433
1434let
1435 venvDir = "./.venv";
1436 pythonPackages = python3Packages;
1437in pkgs.mkShell rec {
1438 name = "impurePythonEnv";
1439 buildInputs = [
1440 pythonPackages.python
1441 # Needed when using python 2.7
1442 # pythonPackages.virtualenv
1443 # ...
1444 ];
1445
1446 # This is very close to how venvShellHook is implemented, but
1447 # adapted to use 'virtualenv'
1448 shellHook = ''
1449 SOURCE_DATE_EPOCH=$(date +%s)
1450
1451 if [ -d "${venvDir}" ]; then
1452 echo "Skipping venv creation, '${venvDir}' already exists"
1453 else
1454 echo "Creating new venv environment in path: '${venvDir}'"
1455 # Note that the module venv was only introduced in python 3, so for 2.7
1456 # this needs to be replaced with a call to virtualenv
1457 ${pythonPackages.python.interpreter} -m venv "${venvDir}"
1458 fi
1459
1460 # Under some circumstances it might be necessary to add your virtual
1461 # environment to PYTHONPATH, which you can do here too;
1462 # PYTHONPATH=$PWD/${venvDir}/${pythonPackages.python.sitePackages}/:$PYTHONPATH
1463
1464 source "${venvDir}/bin/activate"
1465
1466 # As in the previous example, this is optional.
1467 pip install -r requirements.txt
1468 '';
1469}
1470```
1471
1472Note that the `pip install` is an imperative action. So every time `nix-shell`
1473is executed it will attempt to download the Python modules listed in
1474requirements.txt. However these will be cached locally within the `virtualenv`
1475folder and not downloaded again.
1476
1477### How to override a Python package from `configuration.nix`?
1478
1479If you need to change a package's attribute(s) from `configuration.nix` you could do:
1480
1481```nix
1482 nixpkgs.config.packageOverrides = super: {
1483 python = super.python.override {
1484 packageOverrides = python-self: python-super: {
1485 zerobin = python-super.zerobin.overrideAttrs (oldAttrs: {
1486 src = super.fetchgit {
1487 url = "https://github.com/sametmax/0bin";
1488 rev = "a344dbb18fe7a855d0742b9a1cede7ce423b34ec";
1489 sha256 = "16d769kmnrpbdr0ph0whyf4yff5df6zi4kmwx7sz1d3r6c8p6xji";
1490 };
1491 });
1492 };
1493 };
1494 };
1495```
1496
1497`pythonPackages.zerobin` is now globally overridden. All packages and also the
1498`zerobin` NixOS service use the new definition. Note that `python-super` refers
1499to the old package set and `python-self` to the new, overridden version.
1500
1501To modify only a Python package set instead of a whole Python derivation, use
1502this snippet:
1503
1504```nix
1505 myPythonPackages = pythonPackages.override {
1506 overrides = self: super: {
1507 zerobin = ...;
1508 };
1509 }
1510```
1511
1512### How to override a Python package using overlays?
1513
1514Use the following overlay template:
1515
1516```nix
1517self: super: {
1518 python = super.python.override {
1519 packageOverrides = python-self: python-super: {
1520 zerobin = python-super.zerobin.overrideAttrs (oldAttrs: {
1521 src = super.fetchgit {
1522 url = "https://github.com/sametmax/0bin";
1523 rev = "a344dbb18fe7a855d0742b9a1cede7ce423b34ec";
1524 sha256 = "16d769kmnrpbdr0ph0whyf4yff5df6zi4kmwx7sz1d3r6c8p6xji";
1525 };
1526 });
1527 };
1528 };
1529}
1530```
1531
1532### How to use Intel's MKL with numpy and scipy?
1533
1534MKL can be configured using an overlay. See the section "[Using overlays to
1535configure alternatives](#sec-overlays-alternatives-blas-lapack)".
1536
1537### What inputs do `setup_requires`, `install_requires` and `tests_require` map to?
1538
1539In a `setup.py` or `setup.cfg` it is common to declare dependencies:
1540
1541* `setup_requires` corresponds to `nativeBuildInputs`
1542* `install_requires` corresponds to `propagatedBuildInputs`
1543* `tests_require` corresponds to `checkInputs`
1544
1545## Contributing
1546
1547### Contributing guidelines
1548
1549Following rules are desired to be respected:
1550
1551* Python libraries are called from `python-packages.nix` and packaged with
1552 `buildPythonPackage`. The expression of a library should be in
1553 `pkgs/development/python-modules/<name>/default.nix`. Libraries in
1554 `pkgs/top-level/python-packages.nix` are sorted quasi-alphabetically to avoid
1555 merge conflicts.
1556* Python applications live outside of `python-packages.nix` and are packaged
1557 with `buildPythonApplication`.
1558* Make sure libraries build for all Python interpreters.
1559* By default we enable tests. Make sure the tests are found and, in the case of
1560 libraries, are passing for all interpreters. If certain tests fail they can be
1561 disabled individually. Try to avoid disabling the tests altogether. In any
1562 case, when you disable tests, leave a comment explaining why.
1563* Commit names of Python libraries should reflect that they are Python
1564 libraries, so write for example `pythonPackages.numpy: 1.11 -> 1.12`.
1565* Attribute names in `python-packages.nix` should be normalized according to
1566 [PEP 0503](https://www.python.org/dev/peps/pep-0503/#normalized-names). This
1567 means that characters should be converted to lowercase and `.` and `_` should
1568 be replaced by a single `-` (foo-bar-baz instead of Foo__Bar.baz )