# Python

Currently supported interpreters are `python26`, `python27`, `python33`, `python34`, `python35` and `pypy`.

`python` is an alias to `python27` and `python3` is an alias to `python34`.

`python26` and `python27` do not include modules that require external dependencies (to reduce dependency bloat). Following modules need to be added as `buildInput` explicitly:

- `python.modules.bsddb`

- `python.modules.curses`

- `python.modules.curses_panel`

- `python.modules.crypt`

- `python.modules.gdbm`

- `python.modules.sqlite3`

- `python.modules.tkinter`

- `python.modules.readline`

For convenience `python27Full` and `python26Full` are provided with all modules included.

Python packages that use `setuptools` or `distutils`, can be built using the `buildPythonPackage` function as documented below.

All packages depending on any Python interpreter get appended `$out/${python.sitePackages}` to `$PYTHONPATH` if such directory exists.

## Useful attributes on interpreters packages:

`libPrefix`

  Name of the folder in `${python}/lib/` for corresponding interpreter.

`interpreter`

  Alias for `${python}/bin/${executable}.`

`buildEnv`

  Function to build python interpreter environments with extra packages bundled together. See for usage and documentation.

`sitePackages`

  Alias for `lib/${libPrefix}/site-packages`.

`executable`

  Name of the interpreter executable, ie `python3.4`.

## `buildPythonPackage` function

The function is implemented in `pkgs/development/python-modules/generic/default.nix`. Example usage:

    twisted = buildPythonPackage {
      name = "twisted-8.1.0";

      src = pkgs.fetchurl {
        url = http://tmrc.mit.edu/mirror/twisted/Twisted/8.1/Twisted-8.1.0.tar.bz2;
        sha256 = "0q25zbr4xzknaghha72mq57kh53qw1bf8csgp63pm9sfi72qhirl";
      };

      propagatedBuildInputs = [ self.ZopeInterface ];

      meta = {
        homepage = http://twistedmatrix.com/;
        description = "Twisted, an event-driven networking engine written in Python";
        license = stdenv.lib.licenses.mit;
      };
    };

Most of Python packages that use `buildPythonPackage` are defined in `pkgs/top-level/python-packages.nix` and generated for each python interpreter separately into attribute sets `python26Packages`, `python27Packages`, `python35Packages`, `python33Packages`, `python34Packages` and `pypyPackages`.

`buildPythonPackage` mainly does four things:

1. In the `buildPhase`, it calls `${python.interpreter} setup.py bdist_wheel` to build a wheel binary zipfile.

2. In the `installPhase`, it installs the wheel file using `pip install *.whl`.

3. In the `postFixup` phase, `wrapPythonPrograms` bash function is called to wrap all programs in `$out/bin/*` directory to include `$PYTHONPATH` and `$PATH` environment variables.

4. In the `installCheck` phase, `${python.interpreter} setup.py test` is ran.

By default `doCheck = true` is set

As in Perl, dependencies on other Python packages can be specified in the `buildInputs` and `propagatedBuildInputs` attributes. If something is exclusively a build-time dependency, use `buildInputs`; if it’s (also) a runtime dependency, use `propagatedBuildInputs`.

By default `meta.platforms` is set to the same value as the interpreter unless overriden otherwise.

### `buildPythonPackage` parameters (all parameters from `mkDerivation` function are still supported)

`namePrefix`

  Prepended text to `${name}` parameter. Defaults to `"python3.3-"` for Python 3.3, etc. Set it to `""` if you're packaging an application or a command line tool.

`disabled`

  If `true`, package is not build for particular python interpreter version. Grep around `pkgs/top-level/python-packages.nix` for examples.

`setupPyBuildFlags`

  List of flags passed to `setup.py build_ext` command.

`pythonPath`

  List of packages to be added into `$PYTHONPATH`. Packages in `pythonPath` are not propagated (contrary to `propagatedBuildInputs`).

`preShellHook`

  Hook to execute commands before `shellHook`.

`postShellHook`

  Hook to execute commands after `shellHook`.

`makeWrapperArgs`

  A list of strings. Arguments to be passed to `makeWrapper`, which wraps generated binaries. By default, the arguments to `makeWrapper` set `PATH` and `PYTHONPATH` environment variables before calling the binary. Additional arguments here can allow a developer to set environment variables which will be available when the binary is run. For example, `makeWrapperArgs = ["--set FOO BAR" "--set BAZ QUX"]`.

## `python.buildEnv` function

Create Python environments using low-level `pkgs.buildEnv` function. Example `default.nix`:

    with import <nixpkgs> {};

    python.buildEnv.override {
      extraLibs = [ pkgs.pythonPackages.pyramid ];
      ignoreCollisions = true;
    }

Running `nix-build` will create `/nix/store/cf1xhjwzmdki7fasgr4kz6di72ykicl5-python-2.7.8-env` with wrapped binaries in `bin/`.

You can also use `env` attribute to create local environments with needed packages installed (somewhat comparable to `virtualenv`). For example, with the following `shell.nix`:

    with import <nixpkgs> {};

    (python3.buildEnv.override {
      extraLibs = with python3Packages;
        [ numpy
          requests
        ];
    }).env

Running `nix-shell` will drop you into a shell where `python` will have specified packages in its path.

### `python.buildEnv` arguments

`extraLibs`

  List of packages installed inside the environment.

`postBuild`

  Shell command executed after the build of environment.

`ignoreCollisions`

  Ignore file collisions inside the environment (default is `false`).

## Tools

Packages inside nixpkgs are written by hand. However many tools exist in community to help save time. No tool is preferred at the moment.

- python2nix by Vladimir Kirillov

- pypi2nix by Rok Garbas

- pypi2nix by Jaka Hudoklin

## Development

To develop Python packages `buildPythonPackage` has additional logic inside `shellPhase` to run `pip install -e . --prefix $TMPDIR/` for the package.

`shellPhase` is executed only if `setup.py` exists.

Given a `default.nix`:

    with import <nixpkgs> {};

    buildPythonPackage {
      name = "myproject";

      buildInputs = with pkgs.pythonPackages; [ pyramid ];

      src = ./.;
    }

Running `nix-shell` with no arguments should give you the environment in which the package would be build with `nix-build`.

Shortcut to setup environments with C headers/libraries and python packages:

    $ nix-shell -p pythonPackages.pyramid zlib libjpeg git

There is a boolean value `lib.inNixShell` set to `true` if nix-shell is invoked.

## FAQ

How to solve circular dependencies?

  If you have packages `A` and `B` that depend on each other, when packaging `B` override package `A` not to depend on `B` as input (and also the other way around).

`install_data / data_files` problems resulting into `error: could not create '/nix/store/6l1bvljpy8gazlsw2aw9skwwp4pmvyxw-python-2.7.8/etc': Permission denied`

  Known bug in setuptools `install_data` does not respect --prefix. Example of such package using the feature is `pkgs/tools/X11/xpra/default.nix`. As workaround install it as an extra `preInstall` step:

      ${python.interpreter} setup.py install_data --install-dir=$out --root=$out
      sed -i '/ = data_files/d' setup.py

Rationale of non-existent global site-packages

  There is no need to have global site-packages in Nix. Each package has isolated dependency tree and installing any python package will only populate `$PATH` inside user environment. See to create self-contained interpreter with a set of packages.

## Contributing guidelines

Following rules are desired to be respected:

- Make sure package builds for all python interpreters. Use `disabled` argument to `buildPythonPackage` to set unsupported interpreters.

- If tests need to be disabled for a package, make sure you leave a comment about reasoning.

- Packages in `pkgs/top-level/python-packages.nix` are sorted quasi-alphabetically to avoid merge conflicts.