diff --git a/doc/languages-frameworks/python.section.md b/doc/languages-frameworks/python.section.md index 9cb9d2ba7bfd..3211ae616a1c 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) @@ -1197,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}