Merge branch 'buildPythonPackage+wheels'

This commit is contained in:
Domen Kožar
2015-11-26 17:38:35 +01:00
40 changed files with 1073 additions and 837 deletions

View File

@@ -0,0 +1,51 @@
{ stdenv, python, fetchurl, makeWrapper, unzip }:
let
wheel_source = fetchurl {
url = "https://pypi.python.org/packages/py2.py3/w/wheel/wheel-0.26.0-py2.py3-none-any.whl";
sha256 = "1sl642ncvipqx0hzypvl5hsiqngy0sib0kq242g4mic7vnid6bn9";
};
setuptools_source = fetchurl {
url = "https://pypi.python.org/packages/3.4/s/setuptools/setuptools-18.2-py2.py3-none-any.whl";
sha256 = "0jhafl8wmjc8xigl1ib5hqiq9crmipcz0zcga52riymgqbf2bzh4";
};
in stdenv.mkDerivation rec {
name = "python-${python.version}-bootstrapped-pip-${version}";
version = "7.1.2";
src = fetchurl {
url = "https://pypi.python.org/packages/py2.py3/p/pip/pip-${version}-py2.py3-none-any.whl";
sha256 = "133hx6jaspm6hd02gza66lng37l65yficc2y2x1gh16fbhxrilxr";
};
unpackPhase = ''
mkdir -p $out/${python.sitePackages}
unzip -d $out/${python.sitePackages} $src
unzip -d $out/${python.sitePackages} ${setuptools_source}
unzip -d $out/${python.sitePackages} ${wheel_source}
'';
patchPhase = ''
mkdir -p $out/bin
# patch pip to support "pip install --prefix"
# https://github.com/pypa/pip/pull/3252
pushd $out/${python.sitePackages}/
patch -p1 < ${./pip-7.0.1-prefix.patch}
popd
'';
buildInputs = [ python makeWrapper unzip ];
installPhase = ''
# install pip binary
echo '${python.interpreter} -m pip "$@"' > $out/bin/pip
chmod +x $out/bin/pip
# wrap binaries with PYTHONPATH
for f in $out/bin/*; do
wrapProgram $f --prefix PYTHONPATH ":" $out/${python.sitePackages}/
done
'';
}

View File

@@ -0,0 +1,151 @@
commit e87c83d95bb91acdca92202e94488ca51a70e059
Author: Domen Kožar <domen@dev.si>
Date: Mon Nov 16 17:39:44 2015 +0100
WIP
diff --git a/pip/commands/install.py b/pip/commands/install.py
index dbcf100..05d5a08 100644
--- a/pip/commands/install.py
+++ b/pip/commands/install.py
@@ -139,6 +139,13 @@ class InstallCommand(RequirementCommand):
"directory.")
cmd_opts.add_option(
+ '--prefix',
+ dest='prefix_path',
+ metavar='dir',
+ default=None,
+ help="Installation prefix where lib, bin and other top-level folders are placed")
+
+ cmd_opts.add_option(
"--compile",
action="store_true",
dest="compile",
@@ -309,6 +316,7 @@ class InstallCommand(RequirementCommand):
install_options,
global_options,
root=options.root_path,
+ prefix=options.prefix_path,
)
reqs = sorted(
requirement_set.successfully_installed,
diff --git a/pip/locations.py b/pip/locations.py
index 4e6f65d..43aeb1f 100644
--- a/pip/locations.py
+++ b/pip/locations.py
@@ -163,7 +163,7 @@ site_config_files = [
def distutils_scheme(dist_name, user=False, home=None, root=None,
- isolated=False):
+ isolated=False, prefix=None):
"""
Return a distutils install scheme
"""
@@ -187,6 +187,8 @@ def distutils_scheme(dist_name, user=False, home=None, root=None,
i.user = user or i.user
if user:
i.prefix = ""
+ else:
+ i.prefix = prefix or i.prefix
i.home = home or i.home
i.root = root or i.root
i.finalize_options()
diff --git a/pip/req/req_install.py b/pip/req/req_install.py
index 7c5bf8f..6f80a18 100644
--- a/pip/req/req_install.py
+++ b/pip/req/req_install.py
@@ -792,7 +792,7 @@ exec(compile(
else:
return True
- def install(self, install_options, global_options=[], root=None):
+ def install(self, install_options, global_options=[], root=None, prefix=None):
if self.editable:
self.install_editable(install_options, global_options)
return
@@ -800,7 +800,7 @@ exec(compile(
version = pip.wheel.wheel_version(self.source_dir)
pip.wheel.check_compatibility(version, self.name)
- self.move_wheel_files(self.source_dir, root=root)
+ self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
self.install_succeeded = True
return
@@ -833,6 +833,8 @@ exec(compile(
if root is not None:
install_args += ['--root', root]
+ if prefix is not None:
+ install_args += ['--prefix', prefix]
if self.pycompile:
install_args += ["--compile"]
@@ -988,12 +990,13 @@ exec(compile(
def is_wheel(self):
return self.link and self.link.is_wheel
- def move_wheel_files(self, wheeldir, root=None):
+ def move_wheel_files(self, wheeldir, root=None, prefix=None):
move_wheel_files(
self.name, self.req, wheeldir,
user=self.use_user_site,
home=self.target_dir,
root=root,
+ prefix=prefix,
pycompile=self.pycompile,
isolated=self.isolated,
)
diff --git a/pip/wheel.py b/pip/wheel.py
index 403f48b..14eb141 100644
--- a/pip/wheel.py
+++ b/pip/wheel.py
@@ -234,12 +234,12 @@ def get_entrypoints(filename):
def move_wheel_files(name, req, wheeldir, user=False, home=None, root=None,
- pycompile=True, scheme=None, isolated=False):
+ pycompile=True, scheme=None, isolated=False, prefix=None):
"""Install a wheel"""
if not scheme:
scheme = distutils_scheme(
- name, user=user, home=home, root=root, isolated=isolated
+ name, user=user, home=home, root=root, isolated=isolated, prefix=prefix,
)
if root_is_purelib(name, wheeldir):
diff --git a/pip/req/req_install.py b/pip/req/req_install.py
index 51bf4a7..e2e285e 100644
--- a/pip/req/req_install.py
+++ b/pip/req/req_install.py
@@ -795,7 +795,7 @@ exec(compile(
def install(self, install_options, global_options=[], root=None,
prefix=None):
if self.editable:
- self.install_editable(install_options, global_options)
+ self.install_editable(install_options, global_options, prefix=prefix)
return
if self.is_wheel:
version = pip.wheel.wheel_version(self.source_dir)
@@ -929,12 +929,16 @@ exec(compile(
rmtree(self._temp_build_dir)
self._temp_build_dir = None
- def install_editable(self, install_options, global_options=()):
+ def install_editable(self, install_options, global_options=(), prefix=None):
logger.info('Running setup.py develop for %s', self.name)
if self.isolated:
global_options = list(global_options) + ["--no-user-cfg"]
+ if prefix:
+ prefix_param = ['--prefix={0}'.format(prefix)]
+ install_options = list(install_options) + prefix_param
+
with indent_log():
# FIXME: should we do --install-headers here too?
cwd = self.source_dir

View File

@@ -0,0 +1,30 @@
import pkg_resources
import collections
import sys
do_abort = False
packages = collections.defaultdict(list)
for f in sys.path:
for req in pkg_resources.find_distributions(f):
if req not in packages[req.project_name]:
# some exceptions inside buildPythonPackage
if req.project_name in ['setuptools', 'pip']:
continue
packages[req.project_name].append(req)
for name, duplicates in packages.items():
if len(duplicates) > 1:
do_abort = True
print("Found duplicated packages in closure for dependency '{}': ".format(name))
for dup in duplicates:
print(" " + repr(dup))
if do_abort:
print("")
print(
'Package duplicates found in closure, see above. Usually this '
'happens if two packages depend on different version '
'of the same dependency.')
sys.exit(1)

View File

@@ -3,7 +3,7 @@
(http://pypi.python.org/pypi/setuptools/), which represents a large
number of Python packages nowadays. */
{ python, setuptools, unzip, wrapPython, lib, recursivePthLoader, distutils-cfg }:
{ python, setuptools, unzip, wrapPython, lib, bootstrapped-pip }:
{ name
@@ -12,28 +12,18 @@
, buildInputs ? []
# pass extra information to the distutils global configuration (think as global setup.cfg)
, distutilsExtraCfg ? ""
# propagate build dependencies so in case we have A -> B -> C,
# C can import propagated packages by A
# C can import package A propagated by B
, propagatedBuildInputs ? []
# passed to "python setup.py install"
, setupPyInstallFlags ? []
# passed to "python setup.py build"
# passed to "python setup.py build_ext"
# https://github.com/pypa/pip/issues/881
, setupPyBuildFlags ? []
# enable tests by default
, doCheck ? true
# List of packages that should be added to the PYTHONPATH
# environment variable in programs built by this function. Packages
# in the standard `propagatedBuildInputs' variable are also added.
# The difference is that `pythonPath' is not propagated to the user
# environment. This is preferrable for programs because it doesn't
# pollute the user environment.
# DEPRECATED: use propagatedBuildInputs
, pythonPath ? []
# used to disable derivation, useful for specific python versions
@@ -59,106 +49,71 @@ if disabled
then throw "${name} not supported for interpreter ${python.executable}"
else
python.stdenv.mkDerivation (builtins.removeAttrs attrs ["disabled"] // {
inherit doCheck;
let
# use setuptools shim (so that setuptools is imported before distutils)
# pip does the same thing: https://github.com/pypa/pip/pull/3265
setuppy = ./run_setup.py;
# For backwards compatibility, let's use an alias
doInstallCheck = doCheck;
in
python.stdenv.mkDerivation (builtins.removeAttrs attrs ["disabled" "doCheck"] // {
name = namePrefix + name;
buildInputs = [
wrapPython setuptools
(distutils-cfg.override { extraCfg = distutilsExtraCfg; })
] ++ buildInputs ++ pythonPath
buildInputs = [ wrapPython bootstrapped-pip ] ++ buildInputs ++ pythonPath
++ (lib.optional (lib.hasSuffix "zip" attrs.src.name or "") unzip);
# propagate python/setuptools to active setup-hook in nix-shell
propagatedBuildInputs = propagatedBuildInputs ++ [ recursivePthLoader python setuptools ];
pythonPath = pythonPath;
propagatedBuildInputs = propagatedBuildInputs ++ [ python setuptools ];
configurePhase = attrs.configurePhase or ''
runHook preConfigure
# patch python interpreter to write null timestamps when compiling python files
# with following var we tell python to activate the patch so that python doesn't
# try to update them when we freeze timestamps in nix store
# this way python doesn't try to update them when we freeze timestamps in nix store
export DETERMINISTIC_BUILD=1
# prepend following line to import setuptools before distutils
# this way we make sure setuptools monkeypatches distutils commands
# this way setuptools provides extra helpers such as "python setup.py test"
sed -i '0,/import distutils/s//import setuptools;import distutils/' setup.py
sed -i '0,/from distutils/s//import setuptools;from distutils/' setup.py
runHook postConfigure
'';
checkPhase = attrs.checkPhase or ''
runHook preCheck
${python}/bin/${python.executable} setup.py test
runHook postCheck
'';
# we copy nix_run_setup.py over so it's executed relative to the root of the source
# many project make that assumption
buildPhase = attrs.buildPhase or ''
runHook preBuild
${python}/bin/${python.executable} setup.py build ${lib.concatStringsSep " " setupPyBuildFlags}
cp ${setuppy} nix_run_setup.py
${python.interpreter} nix_run_setup.py ${lib.optionalString (setupPyBuildFlags != []) ("build_ext " + (lib.concatStringsSep " " setupPyBuildFlags))} bdist_wheel
runHook postBuild
'';
installPhase = attrs.installPhase or ''
runHook preInstall
mkdir -p "$out/lib/${python.libPrefix}/site-packages"
mkdir -p "$out/${python.sitePackages}"
export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
export PYTHONPATH="$out/lib/${python.libPrefix}/site-packages:$PYTHONPATH"
${python}/bin/${python.executable} setup.py install \
--install-lib=$out/lib/${python.libPrefix}/site-packages \
--old-and-unmanageable \
--prefix="$out" ${lib.concatStringsSep " " setupPyInstallFlags}
# --install-lib:
# sometimes packages specify where files should be installed outside the usual
# python lib prefix, we override that back so all infrastructure (setup hooks)
# work as expected
# --old-and-unmanagable:
# instruct setuptools not to use eggs but fallback to plan package install
# this also reduces one .pth file in the chain, but the main reason is to
# force install process to install only scripts for the package we are
# installing (otherwise it will install scripts also for dependencies)
# A pth file might have been generated to load the package from
# within its own site-packages, rename this package not to
# collide with others.
eapth="$out/lib/${python.libPrefix}"/site-packages/easy-install.pth
if [ -e "$eapth" ]; then
# move colliding easy_install.pth to specifically named one
mv "$eapth" $(dirname "$eapth")/${name}.pth
fi
# Remove any site.py files generated by easy_install as these
# cause collisions. If pth files are to be processed a
# corresponding site.py needs to be included in the PYTHONPATH.
rm -f "$out/lib/${python.libPrefix}"/site-packages/site.py*
pushd dist
${bootstrapped-pip}/bin/pip install *.whl --no-index --prefix=$out --no-cache
popd
runHook postInstall
'';
postFixup = attrs.postFixup or ''
wrapPythonPrograms
# We run all tests after software has been installed since that is
# a common idiom in Python
doInstallCheck = doInstallCheck;
# TODO: document
createBuildInputsPth build-inputs "$buildInputStrings"
for inputsfile in propagated-build-inputs propagated-native-build-inputs; do
if test -e $out/nix-support/$inputsfile; then
createBuildInputsPth $inputsfile "$(cat $out/nix-support/$inputsfile)"
fi
done
'';
installCheckPhase = attrs.checkPhase or ''
runHook preCheck
${python.interpreter} nix_run_setup.py test
runHook postCheck
'';
postFixup = attrs.postFixup or ''
wrapPythonPrograms
# check if we have two packagegs with the same name in closure and fail
# this shouldn't happen, something went wrong with dependencies specs
${python.interpreter} ${./catch_conflicts.py}
'';
shellHook = attrs.shellHook or ''
${preShellHook}
@@ -166,7 +121,8 @@ python.stdenv.mkDerivation (builtins.removeAttrs attrs ["disabled"] // {
tmp_path=$(mktemp -d)
export PATH="$tmp_path/bin:$PATH"
export PYTHONPATH="$tmp_path/${python.sitePackages}:$PYTHONPATH"
${python.interpreter} setup.py develop --prefix $tmp_path
mkdir -p $tmp_path/${python.sitePackages}
${bootstrapped-pip}/bin/pip install -e . --prefix $tmp_path
fi
${postShellHook}
'';
@@ -177,6 +133,7 @@ python.stdenv.mkDerivation (builtins.removeAttrs attrs ["disabled"] // {
} // meta // {
# add extra maintainer(s) to every package
maintainers = (meta.maintainers or []) ++ [ chaoflow iElectric ];
# a marker for release utilies to discover python packages
isBuildPythonPackage = python.meta.platforms;
};
})

View File

@@ -0,0 +1,6 @@
import setuptools
import tokenize
__file__='setup.py';
exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))

View File

@@ -46,7 +46,7 @@ wrapPythonProgramsIn() {
# (see pkgs/build-support/setup-hooks/make-wrapper.sh)
local wrap_args="$f \
--prefix PYTHONPATH ':' $program_PYTHONPATH \
--prefix PATH ':' $program_PATH"
--prefix PATH ':' $program_PATH:$dir/bin"
# Add any additional arguments provided by makeWrapperArgs
# argument to buildPythonPackage.

View File

@@ -35,6 +35,8 @@ buildPythonPackage rec {
sed -i 's/test_use_url/fails/' lib/matplotlib/tests/test_style.py
# Failing test: ERROR: test suite for <class 'matplotlib.sphinxext.tests.test_tinypages.TestTinyPages'>
sed -i 's/TestTinyPages/fails/' lib/matplotlib/sphinxext/tests/test_tinypages.py
# Transient errors
sed -i 's/test_invisible_Line_rendering/noop/' lib/matplotlib/tests/test_lines.py
'';

View File

@@ -8,9 +8,11 @@ buildPythonPackage rec {
sha256 = "6a0b7b1fe2b046875456e14eda3e42430e493bf2251a64481cf4fd1a1e21a80e";
};
buildInputs = [ pythonPackages.nose pythonPackages.minimock ];
buildInputs = with pythonPackages; [ nose minimock ];
checkPhase = "make test";
checkPhase = ''
nosetests
'';
meta = {
description = "A gpodder.net client library";

View File

@@ -16,30 +16,9 @@
# .test() function, which will run the test suite.
checkPhase = ''
runHook preCheck
_python=${python}/bin/${python.executable}
# We will "install" into a temp directory, so that we can run the
# tests (see below).
install_dir="$TMPDIR/test_install"
install_lib="$install_dir/lib/${python.libPrefix}/site-packages"
mkdir -p $install_dir
$_python setup.py install \
--install-lib=$install_lib \
--old-and-unmanageable \
--prefix=$install_dir > /dev/null
# Create a directory in which to run tests (you get an error if you try to
# import the package when you're in the current directory).
mkdir $TMPDIR/run_tests
pushd $TMPDIR/run_tests > /dev/null
# Temporarily add the directory we installed in to the python path
# (not permanently, or this pythonpath will wind up getting exported),
# and run the test suite.
PYTHONPATH="$install_lib:$PYTHONPATH" $_python -c \
'import ${pkgName}; ${pkgName}.test("fast", verbose=10)'
popd > /dev/null
pushd dist
${python.interpreter} -c 'import ${pkgName}; ${pkgName}.test("fast", verbose=10)'
popd
runHook postCheck
'';

View File

@@ -1,4 +1,4 @@
{ stdenv, fetchurl, python, wrapPython, distutils-cfg }:
{ stdenv, fetchurl, python, wrapPython }:
stdenv.mkDerivation rec {
shortName = "setuptools-${version}";
@@ -11,23 +11,14 @@ stdenv.mkDerivation rec {
sha256 = "07avbdc26yl2a46s76fc7m4vg611g8sh39l26x9dr9byya6sb509";
};
buildInputs = [ python wrapPython distutils-cfg ];
buildPhase = "${python}/bin/${python.executable} setup.py build";
installPhase =
''
dst=$out/lib/${python.libPrefix}/site-packages
buildInputs = [ python wrapPython ];
doCheck = false; # requires pytest
installPhase = ''
dst=$out/${python.sitePackages}
mkdir -p $dst
export PYTHONPATH="$dst:$PYTHONPATH"
${python}/bin/${python.executable} setup.py install --prefix=$out --install-lib=$out/lib/${python.libPrefix}/site-packages
${python.interpreter} setup.py install --prefix=$out
wrapPythonPrograms
'';
doCheck = false; # requires pytest
checkPhase = ''
${python}/bin/${python.executable} setup.py test
'';
meta = with stdenv.lib; {

View File

@@ -31,19 +31,6 @@ index 416df5a..f07c9ec 100644
.. changelog::
:version: 0.7.10
diff --git a/lib/sqlalchemy/__init__.py b/lib/sqlalchemy/__init__.py
index 9a21a70..6523ccb 100644
--- a/lib/sqlalchemy/__init__.py
+++ b/lib/sqlalchemy/__init__.py
@@ -120,7 +120,7 @@
__all__ = sorted(name for name, obj in locals().items()
if not (name.startswith('_') or inspect.ismodule(obj)))
-__version__ = '0.7.10'
+__version__ = '0.7.11'
del inspect, sys
diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py
index 69b94f1..a37f684 100644
--- a/test/engine/test_execute.py

View File

@@ -20,7 +20,6 @@ buildPythonPackage rec {
"--lzo=${lzo}"
"--bzip2=${bzip2}"
];
setupPyInstallFlags = setupPyBuildFlags;
# Run the test suite.
# It requires the build path to be in the python search path.

View File

@@ -1,9 +1,6 @@
{ callPackage, ... } @ args:
callPackage ./generic.nix (args // rec {
version = "2.8.12.1";
sha256 = "1l1w4i113csv3bd5r8ybyj0qpxdq83lj6jrc5p7cc10mkwyiagqz";
})

View File

@@ -1,31 +1,28 @@
{ stdenv, fetchurl, pkgconfig, python, buildPythonPackage, isPy3k, isPyPy, wxGTK, openglSupport ? true, pyopengl
, version, sha256, ...
{ stdenv, fetchurl, pkgconfig, python, isPy3k, isPyPy, wxGTK, openglSupport ? true, pyopengl
, version, sha256, wrapPython, setuptools, ...
}:
assert wxGTK.unicode;
buildPythonPackage rec {
stdenv.mkDerivation rec {
name = "wxPython-${version}";
inherit version;
disabled = isPy3k || isPyPy;
doCheck = false;
name = "wxPython-${version}";
inherit version;
src = fetchurl {
url = "mirror://sourceforge/wxpython/wxPython-src-${version}.tar.bz2";
inherit sha256;
};
buildInputs = [ pkgconfig wxGTK (wxGTK.gtk) ]
++ stdenv.lib.optional openglSupport pyopengl;
pythonPath = [ python setuptools ];
buildInputs = [ python setuptools pkgconfig wxGTK (wxGTK.gtk) wrapPython ] ++ stdenv.lib.optional openglSupport pyopengl;
preConfigure = "cd wxPython";
setupPyBuildFlags = [ "WXPORT=gtk2" "NO_HEADERS=1" "BUILD_GLCANVAS=${if openglSupport then "1" else "0"}" "UNICODE=1" ];
installPhase = ''
${python}/bin/${python.executable} setup.py ${stdenv.lib.concatStringsSep " " setupPyBuildFlags} install --prefix=$out
${python.interpreter} setup.py install WXPORT=gtk2 NO_HEADERS=1 BUILD_GLCANVAS=${if openglSupport then "1" else "0"} UNICODE=1 --prefix=$out
wrapPythonPrograms
'';
passthru = { inherit wxGTK openglSupport; };