···481481#### `buildPythonPackage` function
482482483483The `buildPythonPackage` function is implemented in
484484-`pkgs/development/interpreters/python/buildpythonpackage.nix`
484484+`pkgs/development/interpreters/python/build-python-package.nix`
485485486486and can be used as:
487487
···11+/* This function provides a generic Python package builder. It is
22+ intended to work with packages that use `distutils/setuptools'
33+ (http://pypi.python.org/pypi/setuptools/), which represents a large
44+ number of Python packages nowadays. */
55+66+{ lib
77+, python
88+, mkPythonDerivation
99+, bootstrapped-pip
1010+}:
1111+1212+{ buildInputs ? []
1313+1414+# propagate build dependencies so in case we have A -> B -> C,
1515+# C can import package A propagated by B
1616+#, propagatedBuildInputs ? []
1717+1818+# passed to "python setup.py build_ext"
1919+# https://github.com/pypa/pip/issues/881
2020+, setupPyBuildFlags ? []
2121+2222+# Execute before shell hook
2323+, preShellHook ? ""
2424+2525+# Execute after shell hook
2626+, postShellHook ? ""
2727+2828+# Additional flags to pass to "pip install".
2929+, installFlags ? []
3030+3131+, format ? "setup"
3232+3333+, ... } @ attrs:
3434+3535+3636+3737+3838+let
3939+ # use setuptools shim (so that setuptools is imported before distutils)
4040+ # pip does the same thing: https://github.com/pypa/pip/pull/3265
4141+ setuppy = ./run_setup.py;
4242+4343+ formatspecific =
4444+ if format == "wheel" then
4545+ {
4646+ unpackPhase = ''
4747+ mkdir dist
4848+ cp $src dist/"''${src#*-}"
4949+ '';
5050+5151+ # Wheels are pre-compiled
5252+ buildPhase = attrs.buildPhase or ":";
5353+ installCheckPhase = attrs.checkPhase or ":";
5454+5555+ # Wheels don't have any checks to run
5656+ doCheck = attrs.doCheck or false;
5757+ }
5858+ else if format == "setup" then
5959+ {
6060+ # we copy nix_run_setup.py over so it's executed relative to the root of the source
6161+ # many project make that assumption
6262+ buildPhase = attrs.buildPhase or ''
6363+ runHook preBuild
6464+ cp ${setuppy} nix_run_setup.py
6565+ ${python.interpreter} nix_run_setup.py ${lib.optionalString (setupPyBuildFlags != []) ("build_ext " + (lib.concatStringsSep " " setupPyBuildFlags))} bdist_wheel
6666+ runHook postBuild
6767+ '';
6868+6969+ installCheckPhase = attrs.checkPhase or ''
7070+ runHook preCheck
7171+ ${python.interpreter} nix_run_setup.py test
7272+ runHook postCheck
7373+ '';
7474+7575+ # Python packages that are installed with setuptools
7676+ # are typically distributed with tests.
7777+ # With Python it's a common idiom to run the tests
7878+ # after the software has been installed.
7979+ doCheck = attrs.doCheck or true;
8080+ }
8181+ else
8282+ throw "Unsupported format ${format}";
8383+8484+in mkPythonDerivation ( attrs // {
8585+8686+ # To build and install a wheel we need pip
8787+ buildInputs = buildInputs ++ [ bootstrapped-pip ];
8888+8989+#inherit propagatedBuildInputs;
9090+9191+ configurePhase = attrs.configurePhase or ''
9292+ runHook preConfigure
9393+9494+ # patch python interpreter to write null timestamps when compiling python files
9595+ # this way python doesn't try to update them when we freeze timestamps in nix store
9696+ export DETERMINISTIC_BUILD=1
9797+9898+ runHook postConfigure
9999+ '';
100100+101101+ installPhase = attrs.installPhase or ''
102102+ runHook preInstall
103103+104104+ mkdir -p "$out/${python.sitePackages}"
105105+ export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
106106+107107+ pushd dist
108108+ ${bootstrapped-pip}/bin/pip install *.whl --no-index --prefix=$out --no-cache ${toString installFlags}
109109+ popd
110110+111111+ runHook postInstall
112112+ '';
113113+114114+ shellHook = attrs.shellHook or ''
115115+ ${preShellHook}
116116+ if test -e setup.py; then
117117+ tmp_path=$(mktemp -d)
118118+ export PATH="$tmp_path/bin:$PATH"
119119+ export PYTHONPATH="$tmp_path/${python.sitePackages}:$PYTHONPATH"
120120+ mkdir -p $tmp_path/${python.sitePackages}
121121+ ${bootstrapped-pip}/bin/pip install -e . --prefix $tmp_path
122122+ fi
123123+ ${postShellHook}
124124+ '';
125125+126126+} // formatspecific)
···11-/* This function provides a generic Python package builder. It is
22- intended to work with packages that use `distutils/setuptools'
33- (http://pypi.python.org/pypi/setuptools/), which represents a large
44- number of Python packages nowadays. */
55-66-{ python, setuptools, unzip, wrapPython, lib, bootstrapped-pip
77-, ensureNewerSourcesHook }:
88-99-{ name
1010-1111-# by default prefix `name` e.g. "python3.3-${name}"
1212-, namePrefix ? python.libPrefix + "-"
1313-1414-, buildInputs ? []
1515-1616-# propagate build dependencies so in case we have A -> B -> C,
1717-# C can import package A propagated by B
1818-, propagatedBuildInputs ? []
1919-2020-# passed to "python setup.py build_ext"
2121-# https://github.com/pypa/pip/issues/881
2222-, setupPyBuildFlags ? []
2323-2424-# DEPRECATED: use propagatedBuildInputs
2525-, pythonPath ? []
2626-2727-# used to disable derivation, useful for specific python versions
2828-, disabled ? false
2929-3030-, meta ? {}
3131-3232-# Execute before shell hook
3333-, preShellHook ? ""
3434-3535-# Execute after shell hook
3636-, postShellHook ? ""
3737-3838-# Additional arguments to pass to the makeWrapper function, which wraps
3939-# generated binaries.
4040-, makeWrapperArgs ? []
4141-4242-# Additional flags to pass to "pip install".
4343-, installFlags ? []
4444-4545-# Raise an error if two packages are installed with the same name
4646-, catchConflicts ? true
4747-4848-, format ? "setup"
4949-5050-, ... } @ attrs:
5151-5252-5353-# Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
5454-if disabled
5555-then throw "${name} not supported for interpreter ${python.executable}"
5656-else
5757-5858-let
5959- # use setuptools shim (so that setuptools is imported before distutils)
6060- # pip does the same thing: https://github.com/pypa/pip/pull/3265
6161- setuppy = ./run_setup.py;
6262-6363- formatspecific =
6464- if format == "wheel" then
6565- {
6666- unpackPhase = ''
6767- mkdir dist
6868- cp $src dist/"''${src#*-}"
6969- '';
7070-7171- # Wheels are pre-compiled
7272- buildPhase = attrs.buildPhase or ":";
7373- installCheckPhase = attrs.checkPhase or ":";
7474-7575- # Wheels don't have any checks to run
7676- doInstallCheck = attrs.doCheck or false;
7777- }
7878- else if format == "setup" then
7979- {
8080- # propagate python/setuptools to active setup-hook in nix-shell
8181- propagatedBuildInputs =
8282- propagatedBuildInputs ++ [ python setuptools ];
8383-8484- # we copy nix_run_setup.py over so it's executed relative to the root of the source
8585- # many project make that assumption
8686- buildPhase = attrs.buildPhase or ''
8787- runHook preBuild
8888- cp ${setuppy} nix_run_setup.py
8989- ${python.interpreter} nix_run_setup.py ${lib.optionalString (setupPyBuildFlags != []) ("build_ext " + (lib.concatStringsSep " " setupPyBuildFlags))} bdist_wheel
9090- runHook postBuild
9191- '';
9292-9393- installCheckPhase = attrs.checkPhase or ''
9494- runHook preCheck
9595- ${python.interpreter} nix_run_setup.py test
9696- runHook postCheck
9797- '';
9898-9999- # Python packages that are installed with setuptools
100100- # are typically distributed with tests.
101101- # With Python it's a common idiom to run the tests
102102- # after the software has been installed.
103103-104104- # For backwards compatibility, let's use an alias
105105- doInstallCheck = attrs.doCheck or true;
106106- }
107107- else
108108- throw "Unsupported format ${format}";
109109-in
110110-python.stdenv.mkDerivation (builtins.removeAttrs attrs ["disabled" "doCheck"] // {
111111- name = namePrefix + name;
112112-113113- buildInputs = [ wrapPython bootstrapped-pip ] ++ buildInputs ++ pythonPath
114114- ++ [ (ensureNewerSourcesHook { year = "1980"; }) ]
115115- ++ (lib.optional (lib.hasSuffix "zip" attrs.src.name or "") unzip);
116116-117117- pythonPath = pythonPath;
118118-119119- configurePhase = attrs.configurePhase or ''
120120- runHook preConfigure
121121-122122- # patch python interpreter to write null timestamps when compiling python files
123123- # this way python doesn't try to update them when we freeze timestamps in nix store
124124- export DETERMINISTIC_BUILD=1
125125-126126- runHook postConfigure
127127- '';
128128-129129- # Python packages don't have a checkPhase, only an installCheckPhase
130130- doCheck = false;
131131-132132- installPhase = attrs.installPhase or ''
133133- runHook preInstall
134134-135135- mkdir -p "$out/${python.sitePackages}"
136136- export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
137137-138138- pushd dist
139139- ${bootstrapped-pip}/bin/pip install *.whl --no-index --prefix=$out --no-cache ${toString installFlags}
140140- popd
141141-142142- runHook postInstall
143143- '';
144144-145145- postFixup = attrs.postFixup or ''
146146- wrapPythonPrograms
147147- '' + lib.optionalString catchConflicts ''
148148- # check if we have two packages with the same name in closure and fail
149149- # this shouldn't happen, something went wrong with dependencies specs
150150- ${python.interpreter} ${./catch_conflicts.py}
151151- '';
152152-153153- shellHook = attrs.shellHook or ''
154154- ${preShellHook}
155155- if test -e setup.py; then
156156- tmp_path=$(mktemp -d)
157157- export PATH="$tmp_path/bin:$PATH"
158158- export PYTHONPATH="$tmp_path/${python.sitePackages}:$PYTHONPATH"
159159- mkdir -p $tmp_path/${python.sitePackages}
160160- ${bootstrapped-pip}/bin/pip install -e . --prefix $tmp_path
161161- fi
162162- ${postShellHook}
163163- '';
164164-165165- meta = with lib.maintainers; {
166166- # default to python's platforms
167167- platforms = python.meta.platforms;
168168- } // meta // {
169169- # add extra maintainer(s) to every package
170170- maintainers = (meta.maintainers or []) ++ [ chaoflow domenkozar ];
171171- # a marker for release utilities to discover python packages
172172- isBuildPythonPackage = python.meta.platforms;
173173- };
174174-} // formatspecific)
···11+/* Generic builder for Python packages that come without a setup.py. */
22+33+{ lib
44+, python
55+, wrapPython
66+, setuptools
77+, unzip
88+, ensureNewerSourcesHook
99+}:
1010+1111+{ name
1212+1313+# by default prefix `name` e.g. "python3.3-${name}"
1414+, namePrefix ? python.libPrefix + "-"
1515+1616+, buildInputs ? []
1717+1818+# propagate build dependencies so in case we have A -> B -> C,
1919+# C can import package A propagated by B
2020+, propagatedBuildInputs ? []
2121+2222+# DEPRECATED: use propagatedBuildInputs
2323+, pythonPath ? []
2424+2525+# used to disable derivation, useful for specific python versions
2626+, disabled ? false
2727+2828+# Raise an error if two packages are installed with the same name
2929+, catchConflicts ? true
3030+3131+# Additional arguments to pass to the makeWrapper function, which wraps
3232+# generated binaries.
3333+, makeWrapperArgs ? []
3434+3535+, meta ? {}
3636+3737+, passthru ? {}
3838+3939+, ... } @ attrs:
4040+4141+4242+# Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
4343+if disabled
4444+then throw "${name} not supported for interpreter ${python.executable}"
4545+else
4646+4747+python.stdenv.mkDerivation (builtins.removeAttrs attrs ["disabled"] // {
4848+4949+ name = namePrefix + name;
5050+5151+ inherit pythonPath;
5252+5353+ buildInputs = [ wrapPython ] ++ buildInputs ++ pythonPath
5454+ ++ [ (ensureNewerSourcesHook { year = "1980"; }) ]
5555+ ++ (lib.optional (lib.hasSuffix "zip" attrs.src.name or "") unzip);
5656+5757+ # propagate python/setuptools to active setup-hook in nix-shell
5858+ propagatedBuildInputs = propagatedBuildInputs ++ [ python setuptools ];
5959+6060+ # Python packages don't have a checkPhase, only an installCheckPhase
6161+ doCheck = false;
6262+ doInstallCheck = attrs.doCheck or false;
6363+6464+ postFixup = attrs.postFixup or ''
6565+ wrapPythonPrograms
6666+ '' + lib.optionalString catchConflicts ''
6767+ # check if we have two packages with the same name in closure and fail
6868+ # this shouldn't happen, something went wrong with dependencies specs
6969+ ${python.interpreter} ${./catch_conflicts.py}
7070+ '';
7171+7272+ passthru = {
7373+ inherit python; # The python interpreter
7474+ } // passthru;
7575+7676+ meta = with lib.maintainers; {
7777+ # default to python's platforms
7878+ platforms = python.meta.platforms;
7979+ } // meta // {
8080+ # add extra maintainer(s) to every package
8181+ maintainers = (meta.maintainers or []) ++ [ chaoflow domenkozar ];
8282+ # a marker for release utilities to discover python packages
8383+ isBuildPythonPackage = python.meta.platforms;
8484+ };
8585+})
8686+8787+