This commit is contained in:
Some One 2025-08-13 20:52:04 +02:00
commit df07954f74
27 changed files with 1129 additions and 0 deletions

44
flake.lock generated Normal file
View File

@ -0,0 +1,44 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1754725699,
"narHash": "sha256-iAcj9T/Y+3DBy2J0N+yF9XQQQ8IEb5swLFzs23CdP88=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-old": {
"locked": {
"lastModified": 1754725699,
"narHash": "sha256-iAcj9T/Y+3DBy2J0N+yF9XQQQ8IEb5swLFzs23CdP88=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"nixpkgs-old": "nixpkgs-old"
}
}
},
"root": "root",
"version": 7
}

30
flake.nix Normal file
View File

@ -0,0 +1,30 @@
{
description = "A very basic flake";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
nixpkgs-old.url = "github:nixos/nixpkgs?ref=nixos-unstable";
};
outputs =
{
self,
nixpkgs,
nixpkgs-old,
}:
let
forAllSystems =
f: nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" ] (sys: let pkgs = import nixpkgs {system = sys; overlays = [self.overlays.default];}; in f pkgs);
myOverlay =
pkgs:
import ./overlay.nix {
inherit pkgs;
oldPkgs = nixpkgs-old.legacyPackages.${pkgs.hostPlatform.system};
};
in
{
overlays.default = final: _: myOverlay final;
legacyPackages = forAllSystems (pkgs: myOverlay pkgs);
};
}

11
importlib.nix Normal file
View File

@ -0,0 +1,11 @@
{stdenv, fetchPypi, python26Packages }: python26Packages.buildPythonPackage rec {
pname = "importlib";
version = "1.0.2";
pyproject = true;
src = fetchPypi {
inherit pname version;
extension = "tar.gz";
hash = "sha256-JNCWaqdoWbKISFgD8xAHZRL4c3fmya/pwoxSqMzdMow=";
};
}

16
jinja2.nix Normal file
View File

@ -0,0 +1,16 @@
{stdenv, fetchPypi, buildPythonPackage, setuptools }: buildPythonPackage rec {
pname = "Jinja2";
version = "2.5.2";
format = "setuptools";
#pyproject = true;
src = fetchPypi {
inherit pname version;
extension = "tar.gz";
hash = "sha256-GQQPAbOp2MY+TVeTb3hxCQgZm2k3CrRKD3QH3YkfAZs=";
};
propagatedBuildInputs = [setuptools];
#dependencies = [importlib];
}

28
overlay.nix Normal file
View File

@ -0,0 +1,28 @@
{ pkgs, oldPkgs }:
let
bommels = pkgs.lib.makeScope pkgs.newScope (self: rec {
# python26 = pkgs.callPackage ./python26/default.nix {
# self = python26;
# xlibsWrapper = pkgs.xlibsWrapper;
# };
setuptools = self.callPackage ./setuptools.nix { inherit pythonPackages; };
#wrapPython = pkgs.callPackage ./python26/wrap-python.nix { python = python26; };
#mkPythonDerivation = pkgs.callPackage ./python26/mk-python-derivation.nix { inherit setuptools wrapPython; python = python26; };
#bootstrapped-pip = pkgs.callPackage ./python26/bootstrapped-pip.nix { python = python26; };
#buildPythonPackage = pkgs.callPackage ./python26/build-python-package.nix { inherit bootstrapped-pip mkPythonDerivation; python = python26; };
#pip = pkgs.callPackage ./pip.nix { inherit python26 buildPythonPackage; };
pythonInterpreters = self.callPackage ./python-interpreters.nix {};
inherit (pythonInterpreters) python26;
python26Packages = python26.pkgs;
pythonPackages = python26Packages;
#importlib = self.callPackage ./importlib.nix {};
some-package = pkgs.callPackage ./some-package.nix { inherit pythonPackages; };
});
in
{
inherit bommels;
inherit (bommels) python26;
}

37
pip-install-hook.nix Normal file
View File

@ -0,0 +1,37 @@
# Setup hook for pip.
# shellcheck shell=bash
echo "Sourcing pip-install-hook"
pipInstallPhase() {
echo "Executing pipInstallPhase"
runHook preInstall
# shellcheck disable=SC2154
mkdir -p "$out/@pythonSitePackages@"
export PYTHONPATH="$out/@pythonSitePackages@:$PYTHONPATH"
local -a flagsArray=(
--no-index
--no-warn-script-location
--prefix="$out"
--no-cache
)
concatTo flagsArray pipInstallFlags
echo "Lolol"
pushd dist || return 1
echoCmd 'pip install flags' "${flagsArray[@]}"
# @pythonInterpreter@ -m pip install ./*.whl "${flagsArray[@]}"
@pip@ install ./*.whl "${flagsArray[@]}"
popd || return 1
runHook postInstall
echo "Finished executing pipInstallPhase"
}
if [ -z "${dontUsePipInstall-}" ] && [ -z "${installPhase-}" ]; then
echo "Using pipInstallPhase"
installPhase=pipInstallPhase
fi

10
pip.nix Normal file
View File

@ -0,0 +1,10 @@
{stdenv, buildPythonPackage, fetchPypi, python26 }: buildPythonPackage rec {
pname = "pip";
version = "9.0.3";
pyproject = true;
src = fetchPypi {
inherit pname version;
hash = "";
};
}

View File

@ -0,0 +1,28 @@
# shellcheck shell=bash
# Setup hook for checking whether Python imports succeed
echo "Sourcing python-imports-check-hook.sh"
pythonImportsCheckPhase() {
echo "Executing pythonImportsCheckPhase"
if [[ -n "${pythonImportsCheck[*]-}" ]]; then
echo "Check whether the following modules can be imported: ${pythonImportsCheck[*]}"
# shellcheck disable=SC2154
pythonImportsCheckOutput="$out"
if [[ -n "${python-}" ]]; then
echo "Using python specific output \$python for imports check"
pythonImportsCheckOutput=$python
fi
export PYTHONPATH="$pythonImportsCheckOutput/@pythonSitePackages@:$PYTHONPATH"
# Python modules and namespaces names are Python identifiers, which must not contain spaces.
# See https://docs.python.org/3/reference/lexical_analysis.html
# shellcheck disable=SC2048,SC2086
(cd "$pythonImportsCheckOutput" && @pythonCheckInterpreter@ -c 'import sys; import importlib; list(map(lambda mod: importlib.import_module(mod), sys.argv[1:]))' ${pythonImportsCheck[*]})
fi
}
if [[ -z "${dontUsePythonImportsCheck-}" ]]; then
echo "Using pythonImportsCheckPhase"
appendToVar preDistPhases pythonImportsCheckPhase
fi

80
python-interpreters.nix Normal file
View File

@ -0,0 +1,80 @@
{
__splicedPackages,
callPackage,
fetchzip,
config,
db,
lib,
makeScopeWithSplicing',
pythonPackagesExtensions,
stdenv,
path
}@args:
(
let
pythonBase = path + "/pkgs/development/interpreters/python";
# Common passthru for all Python interpreters.
passthruFun = import ( pythonBase + "/passthrufun.nix") args;
fixupString = s: lib.replaceString "2.7" "2.6" (lib.replaceString "2.7.1" "2.6.9" s);
pythonRaw = ((callPackage "${pythonBase}/cpython/2.7" {
# TODO: splicedPackages again
self = __splicedPackages.python26;
sourceVersion = {
major = "2";
minor = "6";
patch = "9";
suffix = ""; # ActiveState's Python 2 extended support
};
hash = "sha256-uxXpGJ5rGPb5x0bIg5yqyQmyLKrjIl0LZjgApzsfd3Q=";
inherit passthruFun;
}).override {
rebuildBytecode = false;
pythonAttr = "python26";
packageOverrides = import ./python-overrides.nix;
#packageOverridesss = _: super: {
# setupTools = "lol";
#};
});
in {
python26 = pythonRaw.overrideAttrs (prev: {
patches = [
# Look in C_INCLUDE_PATH and LIBRARY_PATH for stuff.
./python26/search-path.patch
# Python recompiles a Python if the mtime stored *in* the
# pyc/pyo file differs from the mtime of the source file. This
# doesn't work in Nix because Nix changes the mtime of files in
# the Nix store to 1. So treat that as a special case.
./python26/nix-store-mtime.patch
# http://bugs.python.org/issue10013
./python26/python2.6-fix-parallel-make.patch
];
postInstall = fixupString prev.postInstall;
preConfigure = lib.replaceString "${stdenv.cc.libc}/include/" "${stdenv.cc.libc.dev or stdenv.libc}/include/" prev.preConfigure;
});
pypy27 = callPackage ./pypy {
self = __splicedPackages.pypy27;
sourceVersion = {
major = "7";
minor = "3";
patch = "19";
};
hash = "sha256-hwPNywH5+Clm3UO2pgGPFAOZ21HrtDwSXB+aIV57sAM=";
pythonVersion = "2.7";
db = db.override { dbmSupport = !stdenv.hostPlatform.isDarwin; };
python = __splicedPackages.pythonInterpreters.pypy27_prebuilt;
inherit passthruFun;
};
}
// lib.optionalAttrs config.allowAliases {
pypy39_prebuilt = throw "pypy 3.9 has been removed, use pypy 3.10 instead"; # Added 2025-01-03
}
)

40
python-overrides.nix Normal file
View File

@ -0,0 +1,40 @@
self: super:
let
pipFunction = {fetchFromGitHub}: rec {version = "9.0.3";src = fetchFromGitHub {owner = "pypa"; repo = "pip"; rev = version; hash = "sha256-ei5ru7kr6m+VJYcYMH8Fjya1eqBqkOaC4+JwDqTd46Q=";};};
in
with self;
with super;
rec {
bootstrapped-pip = toPythonModule (callPackage ./python26/bootstrapped-pip.nix {});
pipInstallHookMine = callPackage (
{ makePythonHook, pip }:
makePythonHook {
name = "pip-install-hook";
propagatedBuildInputs = [ pip ];
substitutions = {
inherit pythonInterpreter pythonSitePackages pip;
};
} ./pip-install-hook.sh
) { };
pipInstallHook = pipInstallHookMine;
pythonImportsCheckHookMine = callPackage (
{ makePythonHook }:
makePythonHook {
name = "python-imports-check-hook";
substitutions = {
inherit pythonInterpreter pythonSitePackages;
};
} ./python-imports-check-hook.sh
) { };
pythonImportsCheckHook = pythonImportsCheckHookMine;
setuptools = toPythonModule (callPackage ./setuptools.nix { });
wheel = callPackage ./python26/wheel.nix { };
#pip = pip.overridePythonAttrs (callPackage pipFunction {});
bommels = {
jinja2 = callPackage ./jinja2.nix { };
};
}

View File

@ -0,0 +1,56 @@
{ lib, stdenv, python, fetchurl, makeWrapper, unzip }:
let
wheel_source = fetchurl {
url = "https://pypi.python.org/packages/py2.py3/w/wheel/wheel-0.29.0-py2.py3-none-any.whl";
sha256 = "ea8033fc9905804e652f75474d33410a07404c1a78dd3c949a66863bd1050ebd";
};
setuptools_source = fetchurl {
url = "https://files.pythonhosted.org/packages/b8/cb/b919f52dd81b4b2210d0c5529b6b629a4002e08d49a90183605d1181b10c/setuptools-30.2.0-py2.py3-none-any.whl";
sha256 = "b7e7b28d6a728ea38953d66e12ef400c3c153c523539f1b3997c5a42f3770ff1";
};
argparse_source = fetchurl {
url = "https://pypi.python.org/packages/2.7/a/argparse/argparse-1.4.0-py2.py3-none-any.whl";
sha256 = "0533cr5w14da8wdb2q4py6aizvbvsdbk3sj7m1jx9lwznvnlf5n3";
};
in stdenv.mkDerivation rec {
name = "${python.libPrefix}-bootstrapped-pip-${version}";
version = "9.0.1";
src = fetchurl {
url = "https://files.pythonhosted.org/packages/b6/ac/7015eb97dc749283ffdec1c3a88ddb8ae03b8fad0f0e611408f196358da3/pip-9.0.1-py2.py3-none-any.whl";
sha256 = "690b762c0a8460c303c089d5d0be034fb15a5ea2b75bdf565f40421f542fefb0";
};
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}
'' + lib.optionalString (python.isPy26 or true) ''
unzip -d $out/${python.sitePackages} ${argparse_source}
'';
patchPhase = ''
mkdir -p $out/bin
'';
buildInputs = [ python makeWrapper unzip ];
installPhase = ''
runHook preInstall
# install pip binary
echo '#!${python.interpreter}' > $out/bin/pip
echo 'import sys;from pip import main' >> $out/bin/pip
echo 'sys.exit(main())' >> $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
runHook postInstall
'';
}

View File

@ -0,0 +1,32 @@
# This function provides generic bits to install a Python wheel.
{ python
, bootstrapped-pip
}:
{ buildInputs ? []
# Additional flags to pass to "pip install".
, installFlags ? []
, ... } @ attrs:
attrs // {
buildInputs = buildInputs ++ [ bootstrapped-pip ];
configurePhase = attrs.configurePhase or ''
runHook preConfigure
runHook postConfigure
'';
installPhase = attrs.installPhase or ''
runHook preInstall
mkdir -p "$out/${python.sitePackages}"
export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
pushd dist
${bootstrapped-pip}/bin/pip install *.whl --no-index --prefix=$out --no-cache ${toString installFlags} --build tmpbuild
popd
runHook postInstall
'';
}

View File

@ -0,0 +1,56 @@
# This function provides specific bits for building a setuptools-based Python package.
{ lib
, python
, bootstrapped-pip
}:
{
# passed to "python setup.py build_ext"
# https://github.com/pypa/pip/issues/881
setupPyBuildFlags ? []
# Execute before shell hook
, preShellHook ? ""
# Execute after shell hook
, postShellHook ? ""
, ... } @ attrs:
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;
in attrs // {
# 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
cp ${setuppy} nix_run_setup.py
${python.interpreter} nix_run_setup.py ${lib.optionalString (setupPyBuildFlags != []) ("build_ext " + (lib.concatStringsSep " " setupPyBuildFlags))} bdist_wheel
runHook postBuild
'';
installCheckPhase = attrs.checkPhase or ''
runHook preCheck
${python.interpreter} nix_run_setup.py test
runHook postCheck
'';
# Python packages that are installed with setuptools
# are typically distributed with tests.
# With Python it's a common idiom to run the tests
# after the software has been installed.
doCheck = attrs.doCheck or true;
shellHook = attrs.shellHook or ''
${preShellHook}
if test -e setup.py; then
tmp_path=$(mktemp -d)
export PATH="$tmp_path/bin:$PATH"
export PYTHONPATH="$tmp_path/${python.sitePackages}:$PYTHONPATH"
mkdir -p $tmp_path/${python.sitePackages}
${bootstrapped-pip}/bin/pip install -e . --prefix $tmp_path >&2
fi
${postShellHook}
'';
}

View File

@ -0,0 +1,20 @@
# This function provides specific bits for building a wheel-based Python package.
{
}:
{ ... } @ attrs:
attrs // {
unpackPhase = ''
mkdir dist
cp $src dist/"''${src#*-}"
'';
# Wheels are pre-compiled
buildPhase = attrs.buildPhase or ":";
installCheckPhase = attrs.checkPhase or ":";
# Wheels don't have any checks to run
doCheck = attrs.doCheck or false;
}

View File

@ -0,0 +1,34 @@
/* This function provides a generic Python package builder. It is
intended to work with packages that use `distutils/setuptools'
(http://pypi.python.org/pypi/setuptools/), which represents a large
number of Python packages nowadays. */
{ lib
, python
, mkPythonDerivation
, bootstrapped-pip
}:
let
setuptools-specific = import ./build-python-package-setuptools.nix { inherit lib python bootstrapped-pip; };
wheel-specific = import ./build-python-package-wheel.nix { };
common = import ./build-python-package-common.nix { inherit python bootstrapped-pip; };
in
{
# Several package formats are supported.
# "setuptools" : Install a common setuptools/distutils based package. This builds a wheel.
# "wheel" : Install from a pre-compiled wheel.
# "flit" : Install a flit package. This builds a wheel.
# "other" : Provide your own buildPhase and installPhase.
format ? "setuptools"
, ... } @ attrs:
let
formatspecific =
if format == "setuptools" then common (setuptools-specific attrs)
else if format == "wheel" then common (wheel-specific attrs)
else if format == "other" then {}
else throw "Unsupported format ${format}";
in mkPythonDerivation ( attrs // formatspecific )

216
python26/default.nix Normal file
View File

@ -0,0 +1,216 @@
{ lib, stdenv, fetchurl, zlib ? null, zlibSupport ? true, bzip2, includeModules ? false
, sqlite, tcl, tk, xlibsWrapper, openssl, readline, db, ncurses, gdbm, self, callPackage
/*, python26Packages*/ }:
assert zlibSupport -> zlib != null;
let
majorVersion = "2.6";
version = "${majorVersion}.9";
src = fetchurl {
url = "http://www.python.org/ftp/python/${version}/Python-${version}.tar.xz";
sha256 = "0hbfs2691b60c7arbysbzr0w9528d5pl8a4x7mq5psh6a2cvprya";
};
patches =
[ # Look in C_INCLUDE_PATH and LIBRARY_PATH for stuff.
./search-path.patch
# Python recompiles a Python if the mtime stored *in* the
# pyc/pyo file differs from the mtime of the source file. This
# doesn't work in Nix because Nix changes the mtime of files in
# the Nix store to 1. So treat that as a special case.
./nix-store-mtime.patch
# http://bugs.python.org/issue10013
./python2.6-fix-parallel-make.patch
];
preConfigure = ''
# Purity.
for i in /usr /sw /opt /pkg; do
substituteInPlace ./setup.py --replace $i /no-such-path
done
'' + lib.optionalString (stdenv ? cc && stdenv.cc.libc != null) ''
for i in Lib/plat-*/regen; do
substituteInPlace $i --replace /usr/include/ ${stdenv.cc.libc.dev or stdenv.cc.libc}/include/
done
'' + lib.optionalString stdenv.isCygwin ''
# On Cygwin, `make install' tries to read this Makefile.
mkdir -p $out/lib/python${majorVersion}/config
touch $out/lib/python${majorVersion}/config/Makefile
mkdir -p $out/include/python${majorVersion}
touch $out/include/python${majorVersion}/pyconfig.h
'';
configureFlags = ["--enable-shared" "--with-threads" "--enable-unicode=ucs4"];
buildInputs =
lib.optional (stdenv ? cc && stdenv.cc.libc != null) stdenv.cc.libc ++
[ bzip2 openssl ]++ lib.optionals includeModules [ db openssl ncurses gdbm readline xlibsWrapper tcl tk sqlite ]
++ lib.optional zlibSupport zlib;
mkPaths = paths: {
C_INCLUDE_PATH = lib.makeSearchPathOutput "dev" "include" paths;
LIBRARY_PATH = lib.makeLibraryPath paths;
};
# Build the basic Python interpreter without modules that have
# external dependencies.
python = stdenv.mkDerivation {
name = "python${if includeModules then "" else "-minimal"}-${version}";
pythonVersion = majorVersion;
inherit majorVersion version src patches buildInputs preConfigure
configureFlags;
inherit (mkPaths buildInputs) C_INCLUDE_PATH LIBRARY_PATH;
NIX_CFLAGS_COMPILE = lib.optionalString stdenv.isDarwin "-msse2";
setupHook = ./setup-hook.sh;
postInstall =
''
# needed for some packages, especially packages that backport
# functionality to 2.x from 3.x
for item in $out/lib/python${majorVersion}/test/*; do
if [[ "$item" != */test_support.py* ]]; then
rm -rf "$item"
fi
done
touch $out/lib/python${majorVersion}/test/__init__.py
ln -s $out/lib/python${majorVersion}/pdb.py $out/bin/pdb
ln -s $out/lib/python${majorVersion}/pdb.py $out/bin/pdb${majorVersion}
mv $out/share/man/man1/{python.1,python2.6.1}
ln -s $out/share/man/man1/{python2.6.1,python.1}
#paxmark E $out/bin/python${majorVersion}
${ lib.optionalString includeModules "$out/bin/python ./setup.py build_ext"}
rm "$out"/lib/python*/plat-*/regen # refers to glibc.dev
'';
passthru = rec {
inherit zlibSupport;
isPy2 = true;
isPy26 = true;
buildEnv = callPackage ./wrapper.nix { python = self; };
#withPackages = import ../../with-packages.nix { inherit buildEnv; pythonPackages = python26Packages; };
libPrefix = "python${majorVersion}";
executable = libPrefix;
sitePackages = "lib/${libPrefix}/site-packages";
interpreter = "${self}/bin/${executable}";
};
enableParallelBuilding = true;
meta = {
homepage = "http://python.org";
description = "A high-level dynamically-typed programming language";
longDescription = ''
Python is a remarkably powerful dynamic programming language that
is used in a wide variety of application domains. Some of its key
distinguishing features include: clear, readable syntax; strong
introspection capabilities; intuitive object orientation; natural
expression of procedural code; full modularity, supporting
hierarchical packages; exception-based error handling; and very
high level dynamic data types.
'';
license = lib.licenses.psfl;
platforms = lib.platforms.all;
maintainers = with lib.maintainers; [ chaoflow domenkozar ];
# If you want to use Python 2.6, remove "broken = true;" at your own
# risk. Python 2.6 has known security vulnerabilities is not receiving
# security updates as of October 2013.
#broken = true;
};
};
# This function builds a Python module included in the main Python
# distribution in a separate derivation.
buildInternalPythonModule =
{ moduleName
, internalName ? "_" + moduleName
, deps
}:
if includeModules then null else stdenv.mkDerivation rec {
name = "python-${moduleName}-${python.version}";
inherit src patches preConfigure configureFlags;
buildInputs = [ python ] ++ deps;
inherit (mkPaths buildInputs) C_INCLUDE_PATH LIBRARY_PATH;
buildPhase =
''
substituteInPlace setup.py --replace 'self.extensions = extensions' \
'self.extensions = [ext for ext in self.extensions if ext.name in ["${internalName}"]]'
python ./setup.py build_ext
[ -z "$(find build -name '*_failed.so' -print)" ]
'';
installPhase =
''
dest=$out/lib/${python.libPrefix}/site-packages
mkdir -p $dest
cp -p $(find . -name "*.${if stdenv.isCygwin then "dll" else "so"}") $dest/
'';
};
# The Python modules included in the main Python distribution, built
# as separate derivations.
modules = {
bsddb = buildInternalPythonModule {
moduleName = "bsddb";
deps = [ db ];
};
crypt = buildInternalPythonModule {
moduleName = "crypt";
internalName = "crypt";
deps = lib.optional (stdenv ? glibc) stdenv.glibc;
};
curses = buildInternalPythonModule {
moduleName = "curses";
deps = [ ncurses ];
};
curses_panel = buildInternalPythonModule {
moduleName = "curses_panel";
deps = [ ncurses modules.curses ];
};
gdbm = buildInternalPythonModule {
moduleName = "gdbm";
internalName = "gdbm";
deps = [ gdbm ];
};
sqlite3 = buildInternalPythonModule {
moduleName = "sqlite3";
deps = [ sqlite ];
};
tkinter = buildInternalPythonModule {
moduleName = "tkinter";
deps = [ tcl tk xlibsWrapper ];
};
readline = buildInternalPythonModule {
moduleName = "readline";
internalName = "readline";
deps = [ readline ];
};
};
in python // { inherit modules; }

View File

@ -0,0 +1,102 @@
/* Generic builder for Python packages that come without a setup.py. */
{ lib
, python
, wrapPython
, setuptools
, unzip
, ensureNewerSourcesHook
}:
{ name
# by default prefix `name` e.g. "python3.3-${name}"
, namePrefix ? python.libPrefix + "-"
# Dependencies for building the package
, buildInputs ? []
# Dependencies needed for running the checkPhase.
# These are added to buildInputs when doCheck = true.
, checkInputs ? []
# propagate build dependencies so in case we have A -> B -> C,
# C can import package A propagated by B
, propagatedBuildInputs ? []
# DEPRECATED: use propagatedBuildInputs
, pythonPath ? []
# used to disable derivation, useful for specific python versions
, disabled ? false
# Raise an error if two packages are installed with the same name
, catchConflicts ? true
# Additional arguments to pass to the makeWrapper function, which wraps
# generated binaries.
, makeWrapperArgs ? []
, meta ? {}
, passthru ? {}
, doCheck ? false
, ... } @ attrs:
# Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
if disabled
then throw "${name} not supported for interpreter ${python.executable}"
else
python.stdenv.mkDerivation (builtins.removeAttrs attrs ["disabled"] // {
name = namePrefix + name;
inherit pythonPath;
# Determinism: The interpreter is patched to write null timestamps when compiling python files.
# This way python doesn't try to update them when we freeze timestamps in nix store.
DETERMINISTIC_BUILD=1;
# Determinism: We fix the hashes of str, bytes and datetime objects.
PYTHONHASHSEED = 0;
buildInputs = [ wrapPython ] ++ buildInputs ++ pythonPath
++ [ (ensureNewerSourcesHook { year = "1980"; }) ]
++ (lib.optional (lib.hasSuffix "zip" attrs.src.name or "") unzip)
++ lib.optionals doCheck checkInputs;
# propagate python/setuptools to active setup-hook in nix-shell
propagatedBuildInputs = propagatedBuildInputs ++ [ python setuptools ];
# Python packages don't have a checkPhase, only an installCheckPhase
doCheck = false;
doInstallCheck = doCheck;
postFixup = ''
wrapPythonPrograms
'' + lib.optionalString catchConflicts ''
# check if we have two packages with the same name in closure and fail
# this shouldn't happen, something went wrong with dependencies specs
${python.interpreter} ${./catch_conflicts.py}
'' + attrs.postFixup or '''';
passthru = {
inherit python; # The python interpreter
} // passthru;
meta = with lib.maintainers; {
# default to python's platforms
platforms = python.meta.platforms;
} // meta // {
# add extra maintainer(s) to every package
maintainers = (meta.maintainers or []) ++ [ chaoflow domenkozar ];
# a marker for release utilities to discover python packages
isBuildPythonPackage = python.meta.platforms;
};
})

View File

@ -0,0 +1,12 @@
diff -ru -x '*~' Python-2.7.1-orig/Python/import.c Python-2.7.1/Python/import.c
--- Python-2.7.1-orig/Python/import.c 2010-05-20 20:37:55.000000000 +0200
+++ Python-2.7.1/Python/import.c 2011-01-04 15:55:11.000000000 +0100
@@ -751,7 +751,7 @@
return NULL;
}
pyc_mtime = PyMarshal_ReadLongFromFile(fp);
- if (pyc_mtime != mtime) {
+ if (pyc_mtime != mtime && mtime != 1) {
if (Py_VerboseFlag)
PySys_WriteStderr("# %s has bad mtime\n", cpathname);
fclose(fp);

View File

@ -0,0 +1,37 @@
diff -up Python-2.7/Makefile.pre.in.fix-parallel-make Python-2.7/Makefile.pre.in
--- Python-2.7/Makefile.pre.in.fix-parallel-make 2010-07-22 15:01:39.567996932 -0400
+++ Python-2.7/Makefile.pre.in 2010-07-22 15:47:02.437998509 -0400
@@ -207,6 +207,7 @@ SIGNAL_OBJS= @SIGNAL_OBJS@
##########################################################################
# Grammar
+GRAMMAR_STAMP= $(srcdir)/grammar-stamp
GRAMMAR_H= $(srcdir)/Include/graminit.h
GRAMMAR_C= $(srcdir)/Python/graminit.c
GRAMMAR_INPUT= $(srcdir)/Grammar/Grammar
@@ -530,10 +531,24 @@ Modules/getpath.o: $(srcdir)/Modules/get
Modules/python.o: $(srcdir)/Modules/python.c
$(MAINCC) -c $(PY_CFLAGS) -o $@ $(srcdir)/Modules/python.c
+# GNU "make" interprets rules with two dependents as two copies of the rule.
+#
+# In a parallel build this can lead to pgen being run twice, once for each of
+# GRAMMAR_H and GRAMMAR_C, leading to race conditions in which the compiler
+# reads a partially-overwritten copy of one of these files, leading to syntax
+# errors (or linker errors if the fragment happens to be syntactically valid C)
+#
+# See http://www.gnu.org/software/hello/manual/automake/Multiple-Outputs.html
+# for more information
+#
+# Introduce ".grammar-stamp" as a contrived single output from PGEN to avoid
+# this:
+$(GRAMMAR_H) $(GRAMMAR_C): $(GRAMMAR_STAMP)
-$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
+$(GRAMMAR_STAMP): $(PGEN) $(GRAMMAR_INPUT)
-@$(INSTALL) -d Include
-$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
+ touch $(GRAMMAR_STAMP)
$(PGEN): $(PGENOBJS)
$(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)

View File

@ -0,0 +1,27 @@
diff -rc Python-2.4.4-orig/setup.py Python-2.4.4/setup.py
*** Python-2.4.4-orig/setup.py 2006-10-08 19:41:25.000000000 +0200
--- Python-2.4.4/setup.py 2007-05-27 16:04:54.000000000 +0200
***************
*** 279,288 ****
# Check for AtheOS which has libraries in non-standard locations
if platform == 'atheos':
lib_dirs += ['/system/libs', '/atheos/autolnk/lib']
- lib_dirs += os.getenv('LIBRARY_PATH', '').split(os.pathsep)
inc_dirs += ['/system/include', '/atheos/autolnk/include']
- inc_dirs += os.getenv('C_INCLUDE_PATH', '').split(os.pathsep)
# OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb)
if platform in ['osf1', 'unixware7', 'openunix8']:
lib_dirs += ['/usr/ccs/lib']
--- 279,289 ----
# Check for AtheOS which has libraries in non-standard locations
if platform == 'atheos':
lib_dirs += ['/system/libs', '/atheos/autolnk/lib']
inc_dirs += ['/system/include', '/atheos/autolnk/include']
+ lib_dirs += os.getenv('LIBRARY_PATH', '').split(os.pathsep)
+ inc_dirs += os.getenv('C_INCLUDE_PATH', '').split(os.pathsep)
+
# OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb)
if platform in ['osf1', 'unixware7', 'openunix8']:
lib_dirs += ['/usr/ccs/lib']

15
python26/setup-hook.sh Normal file
View File

@ -0,0 +1,15 @@
addPythonPath() {
addToSearchPathWithCustomDelimiter : PYTHONPATH $1/lib/python2.6/site-packages
}
toPythonPath() {
local paths="$1"
local result=
for i in $paths; do
p="$i/lib/python2.6/site-packages"
result="${result}${result:+:}$p"
done
echo $result
}
envHooks+=(addPythonPath)

44
python26/wheel.nix Normal file
View File

@ -0,0 +1,44 @@
{ lib
, buildPythonPackage
, fetchPypi
, jsonschema
, bootstrapped-pip
, setuptools
, fetchFromGitHub
}:
buildPythonPackage rec {
pname = "wheel";
version = "0.29.0";
format = "setuptools";
#src = fetchPypi {
# inherit pname version;
# sha256 = "1ebb8ad7e26b448e9caa4773d2357849bf80ff9e313964bcaf79cbf0201a1648";
#};
src = fetchFromGitHub {
owner = "pypa";
repo = pname;
rev = version;
name = "${pname}-${version}-source";
hash = "sha256-HedK21Lykt1dbq1wIKGlInuEWV4WezjV2Q2YX+0vyO8=";
};
#buildInputs = [ pytest pytestcov coverage ];
#nativeBuildInputs = [ bootstrapped-pip setuptools ];
#catchConflicts = false;
#doCheck = false;
#pythonImportsCheck = [ "wheel" ];
# We add this flag to ignore the copy installed by bootstrapped-pip
installFlags = [ "--ignore-installed" ];
meta = {
description = "A built-package format for Python";
license = with lib.licenses; [ mit ];
homepage = "https://bitbucket.org/pypa/wheel/";
};
}

51
python26/wrap-python.nix Normal file
View File

@ -0,0 +1,51 @@
{ lib
, python
, makeSetupHook
, makeWrapper }:
with lib;
makeSetupHook {
deps = makeWrapper;
substitutions.libPrefix = python.libPrefix;
substitutions.executable = python.interpreter;
substitutions.python = python;
substitutions.magicalSedExpression = let
# Looks weird? Of course, it's between single quoted shell strings.
# NOTE: Order DOES matter here, so single character quotes need to be
# at the last position.
quoteVariants = [ "'\"'''\"'" "\"\"\"" "\"" "'\"'\"'" ]; # hey Vim: ''
mkStringSkipper = labelNum: quote: let
label = "q${toString labelNum}";
isSingle = elem quote [ "\"" "'\"'\"'" ];
endQuote = if isSingle then "[^\\\\]${quote}" else quote;
in ''
/^[a-z]?${quote}/ {
/${quote}${quote}|${quote}.*${endQuote}/{n;br}
:${label}; n; /^${quote}/{n;br}; /${endQuote}/{n;br}; b${label}
}
'';
# This preamble does two things:
# * Sets argv[0] to the original application's name; otherwise it would be .foo-wrapped.
# Python doesn't support `exec -a`.
# * Adds all required libraries to sys.path via `site.addsitedir`. It also handles *.pth files.
preamble = ''
import sys
import site
import functools
sys.argv[0] = '"'$(readlink -f "$f")'"'
functools.reduce(lambda k, p: site.addsitedir(p, k), ['"$([ -n "$program_PYTHONPATH" ] && (echo "'$program_PYTHONPATH'" | sed "s|:|','|g") || true)"'], site._init_pathinfo())
'';
in ''
1 {
:r
/\\$|,$/{N;br}
/__future__|^ |^ *(#.*)?$/{n;br}
${concatImapStrings mkStringSkipper quoteVariants}
/^[^# ]/i ${replaceStrings ["\n"] [";"] preamble}
}
'';
} ./wrap.sh

54
python26/wrapper.nix Normal file
View File

@ -0,0 +1,54 @@
{ stdenv, python, buildEnv, makeWrapper
, extraLibs ? []
, postBuild ? ""
, ignoreCollisions ? false }:
# Create a python executable that knows about additional packages.
let
recursivePthLoader = import ../../python-modules/recursive-pth-loader/default.nix { stdenv = stdenv; python = python; };
env = (
let
paths = stdenv.lib.filter (x : x ? pythonPath) (stdenv.lib.closePropagation extraLibs) ++ [ python recursivePthLoader ];
in buildEnv {
name = "${python.name}-env";
inherit paths;
inherit ignoreCollisions;
postBuild = ''
. "${makeWrapper}/nix-support/setup-hook"
if [ -L "$out/bin" ]; then
unlink "$out/bin"
fi
mkdir -p "$out/bin"
for path in ${stdenv.lib.concatStringsSep " " paths}; do
if [ -d "$path/bin" ]; then
cd "$path/bin"
for prg in *; do
if [ -f "$prg" ]; then
rm -f "$out/bin/$prg"
makeWrapper "$path/bin/$prg" "$out/bin/$prg" --set PYTHONHOME "$out"
fi
done
fi
done
'' + postBuild;
passthru.env = stdenv.mkDerivation {
name = "interactive-${python.name}-environment";
nativeBuildInputs = [ env ];
buildCommand = ''
echo >&2 ""
echo >&2 "*** Python 'env' attributes are intended for interactive nix-shell sessions, not for building! ***"
echo >&2 ""
exit 1
'';
};
}) // {
inherit python;
inherit (python) meta;
};
in env

1
result Symbolic link
View File

@ -0,0 +1 @@
/nix/store/b5d52gx1g9lwihsqgkdgm606nb1hni57-python2.6-wheel-0.29.0

40
setuptools.nix Normal file
View File

@ -0,0 +1,40 @@
{ lib,
stdenv
, fetchPypi
, python
, wrapPython
, unzip
}:
# Should use buildPythonPackage here somehow
stdenv.mkDerivation rec {
pname = "setuptools";
version = "36.8.0";
name = "${python.libPrefix}-${pname}-${version}";
src = fetchPypi {
inherit pname version;
extension = "zip";
hash = "sha256-sqpaAOnk/SDzw91BLUkJIXRu/hS9o01TlzxKWasFs10=";
};
buildInputs = [ python wrapPython unzip ];
doCheck = false; # requires pytest
installPhase = ''
dst=$out/${python.sitePackages}
mkdir -p $dst
export PYTHONPATH="$dst:$PYTHONPATH"
${python.interpreter} setup.py install --prefix=$out
wrapPythonPrograms
'';
pythonPath = [];
meta = with lib; {
description = "Utilities to facilitate the installation of Python packages";
homepage = http://pypi.python.org/pypi/setuptools;
license = with licenses; [ psfl zpl20 ];
platforms = platforms.all;
priority = 10;
};
}

8
some-package.nix Normal file
View File

@ -0,0 +1,8 @@
{stdenv, path }: stdenv.mkDerivation {
pname = "abc";
version = "0.1.0";
#src = ./some-package.nix;
builder = ''
'';
PATH_TEST=path;
}