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