summary refs log tree commit diff
path: root/doc/languages-frameworks/python.section.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/languages-frameworks/python.section.md')
-rw-r--r--doc/languages-frameworks/python.section.md73
1 files changed, 70 insertions, 3 deletions
diff --git a/doc/languages-frameworks/python.section.md b/doc/languages-frameworks/python.section.md
index fe28f94c069..3211ae616a1 100644
--- a/doc/languages-frameworks/python.section.md
+++ b/doc/languages-frameworks/python.section.md
@@ -663,6 +663,70 @@ However, this is done in it's own phase, and not dependent on whether `doCheck =
 This can also be useful in verifying that the package doesn't assume commonly
 present packages (e.g. `setuptools`)
 
+#### Using pythonRelaxDepsHook {#using-pythonrelaxdepshook}
+
+It is common for upstream to specify a range of versions for its package
+dependencies. This makes sense, since it ensures that the package will be built
+with a subset of packages that is well tested. However, this commonly causes
+issues when packaging in Nixpkgs, because the dependencies that this package
+may need are too new or old for the package to build correctly. We also cannot
+package multiple versions of the same package since this may cause conflicts
+in `PYTHONPATH`.
+
+One way to side step this issue is to relax the dependencies. This can be done
+by either removing the package version range or by removing the package
+declaration entirely. This can be done using the `pythonRelaxDepsHook` hook. For
+example, given the following `requirements.txt` file:
+
+```
+pkg1<1.0
+pkg2
+pkg3>=1.0,<=2.0
+```
+
+we can do:
+
+```
+  nativeBuildInputs = [ pythonRelaxDepsHook ];
+  pythonRelaxDeps = [ "pkg1" "pkg3" ];
+  pythonRemoveDeps = [ "pkg2" ];
+```
+
+which would result in the following `requirements.txt` file:
+
+```
+pkg1
+pkg3
+```
+
+Another option is to pass `true`, that will relax/remove all dependencies, for
+example:
+
+```
+  nativeBuildInputs = [ pythonRelaxDepsHook ];
+  pythonRelaxDeps = true;
+```
+
+which would result in the following `requirements.txt` file:
+
+```
+pkg1
+pkg2
+pkg3
+```
+
+In general you should always use `pythonRelaxDeps`, because `pythonRemoveDeps`
+will convert build errors in runtime errors. However `pythonRemoveDeps` may
+still be useful in exceptional cases, and also to remove dependencies wrongly
+declared by upstream (for example, declaring `black` as a runtime dependency
+instead of a dev dependency).
+
+Keep in mind that while the examples above are done with `requirements.txt`,
+`pythonRelaxDepsHook` works by modifying the resulting wheel file, so it should
+work in any of the formats supported by `buildPythonPackage` currently,
+with the exception of `other` (see `format` in
+[`buildPythonPackage` parameters](#buildpythonpackage-parameters) for more details).
+
 ### Develop local package {#develop-local-package}
 
 As a Python developer you're likely aware of [development mode](http://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode)
@@ -982,12 +1046,13 @@ in python.withPackages(ps: [ps.blaze])).env
 #### Optional extra dependencies
 
 Some packages define optional dependencies for additional features. With
-`setuptools` this is called `extras_require` and `flit` calls it `extras-require`. A
+`setuptools` this is called `extras_require` and `flit` calls it
+`extras-require`, while PEP 621 calls these `optional-dependencies`. A
 method for supporting this is by declaring the extras of a package in its
 `passthru`, e.g. in case of the package `dask`
 
 ```nix
-passthru.extras-require = {
+passthru.optional-dependencies = {
   complete = [ distributed ];
 };
 ```
@@ -997,7 +1062,7 @@ and letting the package requiring the extra add the list to its dependencies
 ```nix
 propagatedBuildInputs = [
   ...
-] ++ dask.extras-require.complete;
+] ++ dask.optional-dependencies.complete;
 ```
 
 Note this method is preferred over adding parameters to builders, as that can
@@ -1196,6 +1261,8 @@ are used in `buildPythonPackage`.
   to run commands only after venv is first created.
 - `wheelUnpackHook` to move a wheel to the correct folder so it can be installed
   with the `pipInstallHook`.
+- `pythonRelaxDepsHook` will relax Python dependencies restrictions for the package.
+  See [example usage](#using-pythonrelaxdepshook).
 
 ### Development mode {#development-mode}