1/* Generic builder for Python packages that come without a setup.py. */
2
3{ lib
4, python
5, wrapPython
6, setuptools
7, unzip
8, ensureNewerSourcesHook
9}:
10
11{ name
12
13# by default prefix `name` e.g. "python3.3-${name}"
14, namePrefix ? python.libPrefix + "-"
15
16# Dependencies for building the package
17, buildInputs ? []
18
19# Dependencies needed for running the checkPhase.
20# These are added to buildInputs when doCheck = true.
21, checkInputs ? []
22
23# propagate build dependencies so in case we have A -> B -> C,
24# C can import package A propagated by B
25, propagatedBuildInputs ? []
26
27# DEPRECATED: use propagatedBuildInputs
28, pythonPath ? []
29
30# used to disable derivation, useful for specific python versions
31, disabled ? false
32
33# Raise an error if two packages are installed with the same name
34, catchConflicts ? true
35
36# Additional arguments to pass to the makeWrapper function, which wraps
37# generated binaries.
38, makeWrapperArgs ? []
39
40# Skip wrapping of python programs altogether
41, dontWrapPythonPrograms ? false
42
43, meta ? {}
44
45, passthru ? {}
46
47, doCheck ? false
48
49, ... } @ attrs:
50
51
52# Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
53if disabled
54then throw "${name} not supported for interpreter ${python.executable}"
55else
56
57python.stdenv.mkDerivation (builtins.removeAttrs attrs ["disabled" "checkInputs"] // {
58
59 name = namePrefix + name;
60
61 inherit pythonPath;
62
63 buildInputs = [ wrapPython ] ++ buildInputs ++ pythonPath
64 ++ [ (ensureNewerSourcesHook { year = "1980"; }) ]
65 ++ (lib.optional (lib.hasSuffix "zip" attrs.src.name or "") unzip)
66 ++ lib.optionals doCheck checkInputs;
67
68 # propagate python/setuptools to active setup-hook in nix-shell
69 propagatedBuildInputs = propagatedBuildInputs ++ [ python setuptools ];
70
71 # Python packages don't have a checkPhase, only an installCheckPhase
72 doCheck = false;
73 doInstallCheck = doCheck;
74
75 postFixup = lib.optionalString (!dontWrapPythonPrograms) ''
76 wrapPythonPrograms
77 '' + lib.optionalString catchConflicts ''
78 # Check if we have two packages with the same name in the closure and fail.
79 # If this happens, something went wrong with the dependencies specs.
80 # Intentionally kept in a subdirectory, see catch_conflicts/README.md.
81 ${python.interpreter} ${./catch_conflicts}/catch_conflicts.py
82 '' + attrs.postFixup or '''';
83
84 passthru = {
85 inherit python; # The python interpreter
86 } // passthru;
87
88 meta = with lib.maintainers; {
89 # default to python's platforms
90 platforms = python.meta.platforms;
91 } // meta // {
92 # add extra maintainer(s) to every package
93 maintainers = (meta.maintainers or []) ++ [ chaoflow ];
94 # a marker for release utilities to discover python packages
95 isBuildPythonPackage = python.meta.platforms;
96 };
97})