diff options
Diffstat (limited to 'pkgs/development/interpreters/python/python2')
| -rw-r--r-- | pkgs/development/interpreters/python/python2/mk-python-derivation.nix | 450 |
1 files changed, 254 insertions, 196 deletions
diff --git a/pkgs/development/interpreters/python/python2/mk-python-derivation.nix b/pkgs/development/interpreters/python/python2/mk-python-derivation.nix index 427c94241070..5bdfa4cd2992 100644 --- a/pkgs/development/interpreters/python/python2/mk-python-derivation.nix +++ b/pkgs/development/interpreters/python/python2/mk-python-derivation.nix @@ -1,243 +1,301 @@ # Generic builder only used for EOL and deprecated Python 2. -{ lib -, config -, python -, wrapPython -, unzip -, ensureNewerSourcesForZipFilesHook -# Whether the derivation provides a Python module or not. -, toPythonModule -, namePrefix -, update-python-libraries -, setuptools -, pipBuildHook -, pipInstallHook -, pythonCatchConflictsHook -, pythonImportsCheckHook -, pythonOutputDistHook -, pythonRemoveBinBytecodeHook -, pythonRemoveTestsDirHook -, setuptoolsBuildHook -, wheelUnpackHook -, eggUnpackHook -, eggBuildHook -, eggInstallHook +{ + lib, + config, + python, + wrapPython, + unzip, + ensureNewerSourcesForZipFilesHook, + # Whether the derivation provides a Python module or not. + toPythonModule, + namePrefix, + update-python-libraries, + setuptools, + pipBuildHook, + pipInstallHook, + pythonCatchConflictsHook, + pythonImportsCheckHook, + pythonOutputDistHook, + pythonRemoveBinBytecodeHook, + pythonRemoveTestsDirHook, + setuptoolsBuildHook, + wheelUnpackHook, + eggUnpackHook, + eggBuildHook, + eggInstallHook, }: -{ name ? "${attrs.pname}-${attrs.version}" +{ + name ? "${attrs.pname}-${attrs.version}", -# Build-time dependencies for the package -, nativeBuildInputs ? [] + # Build-time dependencies for the package + nativeBuildInputs ? [ ], -# Run-time dependencies for the package -, buildInputs ? [] + # Run-time dependencies for the package + buildInputs ? [ ], -# Dependencies needed for running the checkPhase. -# These are added to buildInputs when doCheck = true. -, checkInputs ? [] -, nativeCheckInputs ? [] + # Dependencies needed for running the checkPhase. + # These are added to buildInputs when doCheck = true. + checkInputs ? [ ], + nativeCheckInputs ? [ ], -# propagate build dependencies so in case we have A -> B -> C, -# C can import package A propagated by B -, propagatedBuildInputs ? [] + # propagate build dependencies so in case we have A -> B -> C, + # C can import package A propagated by B + propagatedBuildInputs ? [ ], -# DEPRECATED: use propagatedBuildInputs -, pythonPath ? [] + # DEPRECATED: use propagatedBuildInputs + pythonPath ? [ ], -# Enabled to detect some (native)BuildInputs mistakes -, strictDeps ? true + # Enabled to detect some (native)BuildInputs mistakes + strictDeps ? true, -, outputs ? [ "out" ] + outputs ? [ "out" ], -# used to disable derivation, useful for specific python versions -, disabled ? false + # used to disable derivation, useful for specific python versions + disabled ? false, -# Raise an error if two packages are installed with the same name -# TODO: For cross we probably need a different PYTHONPATH, or not -# add the runtime deps until after buildPhase. -, catchConflicts ? (python.stdenv.hostPlatform == python.stdenv.buildPlatform) + # Raise an error if two packages are installed with the same name + # TODO: For cross we probably need a different PYTHONPATH, or not + # add the runtime deps until after buildPhase. + catchConflicts ? (python.stdenv.hostPlatform == python.stdenv.buildPlatform), -# Additional arguments to pass to the makeWrapper function, which wraps -# generated binaries. -, makeWrapperArgs ? [] + # Additional arguments to pass to the makeWrapper function, which wraps + # generated binaries. + makeWrapperArgs ? [ ], -# Skip wrapping of python programs altogether -, dontWrapPythonPrograms ? false + # Skip wrapping of python programs altogether + dontWrapPythonPrograms ? false, -# Don't use Pip to install a wheel -# Note this is actually a variable for the pipInstallPhase in pip's setupHook. -# It's included here to prevent an infinite recursion. -, dontUsePipInstall ? false + # Don't use Pip to install a wheel + # Note this is actually a variable for the pipInstallPhase in pip's setupHook. + # It's included here to prevent an infinite recursion. + dontUsePipInstall ? false, -# Skip setting the PYTHONNOUSERSITE environment variable in wrapped programs -, permitUserSite ? false + # Skip setting the PYTHONNOUSERSITE environment variable in wrapped programs + permitUserSite ? false, -# Remove bytecode from bin folder. -# When a Python script has the extension `.py`, bytecode is generated -# Typically, executables in bin have no extension, so no bytecode is generated. -# However, some packages do provide executables with extensions, and thus bytecode is generated. -, removeBinBytecode ? true + # Remove bytecode from bin folder. + # When a Python script has the extension `.py`, bytecode is generated + # Typically, executables in bin have no extension, so no bytecode is generated. + # However, some packages do provide executables with extensions, and thus bytecode is generated. + removeBinBytecode ? true, -# Several package formats are supported. -# "setuptools" : Install a common setuptools/distutils based package. This builds a wheel. -# "wheel" : Install from a pre-compiled wheel. -# "pyproject": Install a package using a ``pyproject.toml`` file (PEP517). This builds a wheel. -# "egg": Install a package from an egg. -# "other" : Provide your own buildPhase and installPhase. -, format ? "setuptools" + # Several package formats are supported. + # "setuptools" : Install a common setuptools/distutils based package. This builds a wheel. + # "wheel" : Install from a pre-compiled wheel. + # "pyproject": Install a package using a ``pyproject.toml`` file (PEP517). This builds a wheel. + # "egg": Install a package from an egg. + # "other" : Provide your own buildPhase and installPhase. + format ? "setuptools", -, meta ? {} + meta ? { }, -, passthru ? {} + passthru ? { }, -, doCheck ? true + doCheck ? true, -, disabledTestPaths ? [] + disabledTestPaths ? [ ], -, ... } @ attrs: + ... +}@attrs: let inherit (python) stdenv; - withDistOutput = lib.elem format ["pyproject" "setuptools" "wheel"]; + withDistOutput = lib.elem format [ + "pyproject" + "setuptools" + "wheel" + ]; name_ = name; - validatePythonMatches = attrName: let - isPythonModule = drv: - # all pythonModules have the pythonModule attribute - (drv ? "pythonModule") - # Some pythonModules are turned in to a pythonApplication by setting the field to false - && (!builtins.isBool drv.pythonModule); - isMismatchedPython = drv: drv.pythonModule != python; + validatePythonMatches = + attrName: + let + isPythonModule = + drv: + # all pythonModules have the pythonModule attribute + (drv ? "pythonModule") + # Some pythonModules are turned in to a pythonApplication by setting the field to false + && (!builtins.isBool drv.pythonModule); + isMismatchedPython = drv: drv.pythonModule != python; - optionalLocation = let - pos = builtins.unsafeGetAttrPos (if attrs ? "pname" then "pname" else "name") attrs; - in lib.optionalString (pos != null) " at ${pos.file}:${toString pos.line}:${toString pos.column}"; + optionalLocation = + let + pos = builtins.unsafeGetAttrPos (if attrs ? "pname" then "pname" else "name") attrs; + in + lib.optionalString (pos != null) " at ${pos.file}:${toString pos.line}:${toString pos.column}"; - leftPadName = name: against: let - len = lib.max (lib.stringLength name) (lib.stringLength against); - in lib.strings.fixedWidthString len " " name; + leftPadName = + name: against: + let + len = lib.max (lib.stringLength name) (lib.stringLength against); + in + lib.strings.fixedWidthString len " " name; - throwMismatch = drv: let - myName = "'${namePrefix}${name}'"; - theirName = "'${drv.name}'"; - in throw '' - Python version mismatch in ${myName}: + throwMismatch = + drv: + let + myName = "'${namePrefix}${name}'"; + theirName = "'${drv.name}'"; + in + throw '' + Python version mismatch in ${myName}: - The Python derivation ${myName} depends on a Python derivation - named ${theirName}, but the two derivations use different versions - of Python: + The Python derivation ${myName} depends on a Python derivation + named ${theirName}, but the two derivations use different versions + of Python: - ${leftPadName myName theirName} uses ${python} - ${leftPadName theirName myName} uses ${toString drv.pythonModule} + ${leftPadName myName theirName} uses ${python} + ${leftPadName theirName myName} uses ${toString drv.pythonModule} - Possible solutions: + Possible solutions: - * If ${theirName} is a Python library, change the reference to ${theirName} - in the ${attrName} of ${myName} to use a ${theirName} built from the same - version of Python + * If ${theirName} is a Python library, change the reference to ${theirName} + in the ${attrName} of ${myName} to use a ${theirName} built from the same + version of Python - * If ${theirName} is used as a tool during the build, move the reference to - ${theirName} in ${myName} from ${attrName} to nativeBuildInputs + * If ${theirName} is used as a tool during the build, move the reference to + ${theirName} in ${myName} from ${attrName} to nativeBuildInputs - * If ${theirName} provides executables that are called at run time, pass its - bin path to makeWrapperArgs: + * If ${theirName} provides executables that are called at run time, pass its + bin path to makeWrapperArgs: - makeWrapperArgs = [ "--prefix PATH : ''${lib.makeBinPath [ ${lib.getName drv } ] }" ]; + makeWrapperArgs = [ "--prefix PATH : ''${lib.makeBinPath [ ${lib.getName drv} ] }" ]; - ${optionalLocation} - ''; + ${optionalLocation} + ''; - checkDrv = drv: - if (isPythonModule drv) && (isMismatchedPython drv) - then throwMismatch drv - else drv; + checkDrv = drv: if (isPythonModule drv) && (isMismatchedPython drv) then throwMismatch drv else drv; - in inputs: builtins.map (checkDrv) inputs; + in + inputs: builtins.map (checkDrv) inputs; # Keep extra attributes from `attrs`, e.g., `patchPhase', etc. - self = toPythonModule (stdenv.mkDerivation ((builtins.removeAttrs attrs [ - "disabled" "checkPhase" "checkInputs" "nativeCheckInputs" "doCheck" "doInstallCheck" "dontWrapPythonPrograms" "catchConflicts" "format" - "disabledTestPaths" "outputs" - ]) // { - - name = namePrefix + name_; - - nativeBuildInputs = [ - python - wrapPython - ensureNewerSourcesForZipFilesHook # move to wheel installer (pip) or builder (setuptools, ...)? - pythonRemoveTestsDirHook - ] ++ lib.optionals catchConflicts [ - pythonCatchConflictsHook - ] ++ lib.optionals removeBinBytecode [ - pythonRemoveBinBytecodeHook - ] ++ lib.optionals (lib.hasSuffix "zip" (attrs.src.name or "")) [ - unzip - ] ++ lib.optionals (format == "setuptools") [ - setuptoolsBuildHook - ] ++ lib.optionals (format == "pyproject") [( - pipBuildHook - )] ++ lib.optionals (format == "wheel") [ - wheelUnpackHook - ] ++ lib.optionals (format == "egg") [ - eggUnpackHook eggBuildHook eggInstallHook - ] ++ lib.optionals (format != "other") [( - pipInstallHook - )] ++ lib.optionals (stdenv.buildPlatform == stdenv.hostPlatform) [ - # This is a test, however, it should be ran independent of the checkPhase and checkInputs - pythonImportsCheckHook - ] ++ lib.optionals withDistOutput [ - pythonOutputDistHook - ] ++ nativeBuildInputs; - - buildInputs = validatePythonMatches "buildInputs" (buildInputs ++ pythonPath); - - propagatedBuildInputs = validatePythonMatches "propagatedBuildInputs" (propagatedBuildInputs ++ [ - # we propagate python even for packages transformed with 'toPythonApplication' - # this pollutes the PATH but avoids rebuilds - # see https://github.com/NixOS/nixpkgs/issues/170887 for more context - python - ]); - - inherit strictDeps; - - LANG = "${if python.stdenv.hostPlatform.isDarwin then "en_US" else "C"}.UTF-8"; - - # Python packages don't have a checkPhase, only an installCheckPhase - doCheck = false; - doInstallCheck = attrs.doCheck or true; - nativeInstallCheckInputs = nativeCheckInputs; - installCheckInputs = checkInputs; - - postFixup = lib.optionalString (!dontWrapPythonPrograms) '' - wrapPythonPrograms - '' + attrs.postFixup or ""; - - # Python packages built through cross-compilation are always for the host platform. - disallowedReferences = lib.optionals (python.stdenv.hostPlatform != python.stdenv.buildPlatform) [ python.pythonOnBuildForHost ]; - - outputs = outputs ++ lib.optional withDistOutput "dist"; - - meta = { - # default to python's platforms - platforms = python.meta.platforms; - isBuildPythonPackage = python.meta.platforms; - } // meta; - } // lib.optionalAttrs (attrs?checkPhase) { - # If given use the specified checkPhase, otherwise use the setup hook. - # Longer-term we should get rid of `checkPhase` and use `installCheckPhase`. - installCheckPhase = attrs.checkPhase; - } // lib.optionalAttrs (disabledTestPaths != []) { - disabledTestPaths = lib.escapeShellArgs disabledTestPaths; - })); - - passthru.updateScript = let + self = toPythonModule ( + stdenv.mkDerivation ( + (builtins.removeAttrs attrs [ + "disabled" + "checkPhase" + "checkInputs" + "nativeCheckInputs" + "doCheck" + "doInstallCheck" + "dontWrapPythonPrograms" + "catchConflicts" + "format" + "disabledTestPaths" + "outputs" + ]) + // { + + name = namePrefix + name_; + + nativeBuildInputs = + [ + python + wrapPython + ensureNewerSourcesForZipFilesHook # move to wheel installer (pip) or builder (setuptools, ...)? + pythonRemoveTestsDirHook + ] + ++ lib.optionals catchConflicts [ + pythonCatchConflictsHook + ] + ++ lib.optionals removeBinBytecode [ + pythonRemoveBinBytecodeHook + ] + ++ lib.optionals (lib.hasSuffix "zip" (attrs.src.name or "")) [ + unzip + ] + ++ lib.optionals (format == "setuptools") [ + setuptoolsBuildHook + ] + ++ lib.optionals (format == "pyproject") [ + (pipBuildHook) + ] + ++ lib.optionals (format == "wheel") [ + wheelUnpackHook + ] + ++ lib.optionals (format == "egg") [ + eggUnpackHook + eggBuildHook + eggInstallHook + ] + ++ lib.optionals (format != "other") [ + (pipInstallHook) + ] + ++ lib.optionals (stdenv.buildPlatform == stdenv.hostPlatform) [ + # This is a test, however, it should be ran independent of the checkPhase and checkInputs + pythonImportsCheckHook + ] + ++ lib.optionals withDistOutput [ + pythonOutputDistHook + ] + ++ nativeBuildInputs; + + buildInputs = validatePythonMatches "buildInputs" (buildInputs ++ pythonPath); + + propagatedBuildInputs = validatePythonMatches "propagatedBuildInputs" ( + propagatedBuildInputs + ++ [ + # we propagate python even for packages transformed with 'toPythonApplication' + # this pollutes the PATH but avoids rebuilds + # see https://github.com/NixOS/nixpkgs/issues/170887 for more context + python + ] + ); + + inherit strictDeps; + + LANG = "${if python.stdenv.hostPlatform.isDarwin then "en_US" else "C"}.UTF-8"; + + # Python packages don't have a checkPhase, only an installCheckPhase + doCheck = false; + doInstallCheck = attrs.doCheck or true; + nativeInstallCheckInputs = nativeCheckInputs; + installCheckInputs = checkInputs; + + postFixup = + lib.optionalString (!dontWrapPythonPrograms) '' + wrapPythonPrograms + '' + + attrs.postFixup or ""; + + # Python packages built through cross-compilation are always for the host platform. + disallowedReferences = lib.optionals (python.stdenv.hostPlatform != python.stdenv.buildPlatform) [ + python.pythonOnBuildForHost + ]; + + outputs = outputs ++ lib.optional withDistOutput "dist"; + + meta = { + # default to python's platforms + platforms = python.meta.platforms; + isBuildPythonPackage = python.meta.platforms; + } // meta; + } + // lib.optionalAttrs (attrs ? checkPhase) { + # If given use the specified checkPhase, otherwise use the setup hook. + # Longer-term we should get rid of `checkPhase` and use `installCheckPhase`. + installCheckPhase = attrs.checkPhase; + } + // lib.optionalAttrs (disabledTestPaths != [ ]) { + disabledTestPaths = lib.escapeShellArgs disabledTestPaths; + } + ) + ); + + passthru.updateScript = + let filename = builtins.head (lib.splitString ":" self.meta.position); - in attrs.passthru.updateScript or [ update-python-libraries filename ]; -in lib.extendDerivation - (disabled -> throw "${name} not supported for interpreter ${python.executable}") - passthru - self + in + attrs.passthru.updateScript or [ + update-python-libraries + filename + ]; +in +lib.extendDerivation ( + disabled -> throw "${name} not supported for interpreter ${python.executable}" +) passthru self |
