summary refs log tree commit diff
path: root/doc/languages-frameworks/python.md
diff options
context:
space:
mode:
authorRobin Gloster <mail@glob.in>2016-05-30 19:39:34 +0000
committerRobin Gloster <mail@glob.in>2016-05-30 19:39:34 +0000
commit2d382f3d981fc9e4a350badb43736c252415d27c (patch)
tree3d5f7a96aa71be52c86f3c243b23424e319cc286 /doc/languages-frameworks/python.md
parent365379857fb561df949fc841e80458e317a1d682 (diff)
parent2661511cdb39bd7612dd5311b46420785fc1eac8 (diff)
Merge remote-tracking branch 'upstream/master' into hardened-stdenv
Diffstat (limited to 'doc/languages-frameworks/python.md')
-rw-r--r--doc/languages-frameworks/python.md74
1 files changed, 50 insertions, 24 deletions
diff --git a/doc/languages-frameworks/python.md b/doc/languages-frameworks/python.md
index c6d38c6989a7e..dd9af4e827e22 100644
--- a/doc/languages-frameworks/python.md
+++ b/doc/languages-frameworks/python.md
@@ -78,18 +78,16 @@ containing
 ```nix
 with import <nixpkgs> {};
 
-(pkgs.python35.buildEnv.override  {
-  extraLibs = with pkgs.python35Packages; [ numpy toolz ];
-}).env
+(pkgs.python35.withPackages (ps: [ps.numpy ps.toolz])).env
 ```
 executing `nix-shell` gives you again a Nix shell from which you can run Python.
 
 What's happening here?
 
 1. We begin with importing the Nix Packages collections. `import <nixpkgs>` import the `<nixpkgs>` function, `{}` calls it and the `with` statement brings all attributes of `nixpkgs` in the local scope. Therefore we can now use `pkgs`.
-2. Then we create a Python 3.5 environment with `pkgs.buildEnv`. Because we want to use it with a custom set of Python packages, we override it.
-3. The `extraLibs` argument of the original `buildEnv` function can be used to specify which packages should be included. We want `numpy` and `toolz`. Again, we use the `with` statement to bring a set of attributes into the local scope.
-4. And finally, for in interactive use we return the environment.
+2. Then we create a Python 3.5 environment with the `withPackages` function.
+3. The `withPackages` function expects us to provide a function as an argument that takes the set of all python packages and returns a list of packages to include in the environment. Here, we select the packages `numpy` and `toolz` from the package set.
+4. And finally, for in interactive use we return the environment by using the `env` attribute.
 
 ### Developing with Python
 
@@ -187,10 +185,7 @@ with import <nixpkgs> {};
       };
     };
 
-  in pkgs.python35.buildEnv.override rec {
-
-    extraLibs = [ pkgs.python35Packages.numpy toolz ];
-}
+  in pkgs.python35.withPackages (ps: [ps.numpy toolz])
 ).env
 ```
 
@@ -199,8 +194,11 @@ locally defined package as well as `numpy` which is build according to the
 definition in Nixpkgs. What did we do here? Well, we took the Nix expression
 that we used earlier to build a Python environment, and said that we wanted to
 include our own version of `toolz`. To introduce our own package in the scope of
-`buildEnv.override` we used a
+`withPackages` we used a
 [`let`](http://nixos.org/nix/manual/#sec-constructs) expression.
+You can see that we used `ps.numpy` to select numpy from the nixpkgs package set (`ps`).
+But we do not take `toolz` from the nixpkgs package set this time.
+Instead, `toolz` will resolve to our local definition that we introduced with `let`.
 
 ### Handling dependencies
 
@@ -359,7 +357,7 @@ own packages. The important functions here are `import` and `callPackage`.
 
 ### Including a derivation using `callPackage`
 
-Earlier we created a Python environment using `buildEnv`, and included the
+Earlier we created a Python environment using `withPackages`, and included the
 `toolz` package via a `let` expression.
 Let's split the package definition from the environment definition.
 
@@ -394,9 +392,7 @@ with import <nixpkgs> {};
 
 ( let
     toolz = pkgs.callPackage ~/path/to/toolz/release.nix { pkgs=pkgs; buildPythonPackage=pkgs.python35Packages.buildPythonPackage; };
-  in pkgs.python35.buildEnv.override rec {
-    extraLibs = [ pkgs.python35Packages.numpy  toolz ];
-}
+  in pkgs.python35.withPackages (ps: [ ps.numpy toolz ])
 ).env
 ```
 
@@ -450,6 +446,7 @@ Each interpreter has the following attributes:
 - `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 section *python.buildEnv function* for usage and documentation.
+- `withPackages`. Simpler interface to `buildEnv`. See section *python.withPackages function* for usage and documentation.
 - `sitePackages`. Alias for `lib/${libPrefix}/site-packages`.
 - `executable`. Name of the interpreter executable, ie `python3.4`.
 
@@ -548,7 +545,7 @@ Python environments can be created using the low-level `pkgs.buildEnv` function.
 This example shows how to create an environment that has the Pyramid Web Framework.
 Saving the following as `default.nix`
 
-    with import {};
+    with import <nixpkgs> {};
 
     python.buildEnv.override {
       extraLibs = [ pkgs.pythonPackages.pyramid ];
@@ -565,7 +562,7 @@ You can also use the `env` attribute to create local environments with needed
 packages installed. This is somewhat comparable to `virtualenv`. For example,
 running `nix-shell` with the following `shell.nix`
 
-    with import {};
+    with import <nixpkgs> {};
 
     (python3.buildEnv.override {
       extraLibs = with python3Packages; [ numpy requests ];
@@ -581,6 +578,37 @@ specified packages in its path.
 * `postBuild`: Shell command executed after the build of environment.
 * `ignoreCollisions`: Ignore file collisions inside the environment (default is `false`).
 
+#### python.withPackages function
+
+The `python.withPackages` function provides a simpler interface to the `python.buildEnv` functionality.
+It takes a function as an argument that is passed the set of python packages and returns the list 
+of the packages to be included in the environment. Using the `withPackages` function, the previous
+example for the Pyramid Web Framework environment can be written like this:
+
+    with import <nixpkgs> {};
+
+    python.withPackages (ps: [ps.pyramid])
+
+`withPackages` passes the correct package set for the specific interpreter version as an 
+argument to the function. In the above example, `ps` equals `pythonPackages`.
+But you can also easily switch to using python3:
+    
+    with import <nixpkgs> {};
+
+    python3.withPackages (ps: [ps.pyramid])
+
+Now, `ps` is set to `python3Packages`, matching the version of the interpreter.
+
+As `python.withPackages` simply uses `python.buildEnv` under the hood, it also supports the `env`
+attribute. The `shell.nix` file from the previous section can thus be also written like this:
+
+    with import <nixpkgs> {};
+
+    (python33.withPackages (ps: [ps.numpy ps.requests])).env
+
+In contrast to `python.buildEnv`, `python.withPackages` does not support the more advanced options
+such as `ignoreCollisions = true` or `postBuild`. If you need them, you have to use `python.buildEnv`.
+
 ### Development mode
 
 Development or editable mode is supported. To develop Python packages
@@ -591,7 +619,7 @@ Warning: `shellPhase` is executed only if `setup.py` exists.
 
 Given a `default.nix`:
 
-    with import {};
+    with import <nixpkgs> {};
 
     buildPythonPackage { name = "myproject";
 
@@ -649,9 +677,8 @@ newpkgs = pkgs.overridePackages(self: super: rec {
     self = python35Packages // { pandas = python35Packages.pandas.override{name="foo";};};
   };
 });
-in newpkgs.python35.buildEnv.override{
-  extraLibs = [newpkgs.python35Packages.blaze ];
-}).env
+in newpkgs.python35.withPackages (ps: [ps.blaze])
+).env
 ```
 A typical use case is to switch to another version of a certain package. For example, in the Nixpkgs repository we have multiple versions of `django` and `scipy`.
 In the following example we use a different version of `scipy`. All packages in `newpkgs` will now use the updated `scipy` version.
@@ -665,9 +692,8 @@ newpkgs = pkgs.overridePackages(self: super: rec {
     self = python35Packages // { scipy = python35Packages.scipy_0_16;};
   };
 });
-in pkgs.python35.buildEnv.override{
-  extraLibs = [newpkgs.python35Packages.blaze ];
-}).env
+in newpkgs.python35.withPackages (ps: [ps.blaze])
+).env
 ```
 The requested package `blaze` depends upon `pandas` which itself depends on `scipy`.