nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 866 lines 31 kB view raw
1{ 2 lib, 3 stdenv, 4 fetchurl, 5 fetchpatch, 6 fetchgit, 7 8 # build dependencies 9 autoconf-archive, 10 autoreconfHook, 11 nukeReferences, 12 pkg-config, 13 python-setup-hook, 14 15 # high level switches 16 withMinimalDeps ? false, 17 18 # runtime dependencies 19 bzip2, 20 withExpat ? !withMinimalDeps, 21 expat, 22 libffi, 23 libuuid, 24 libxcrypt, 25 withMpdecimal ? !withMinimalDeps, 26 mpdecimal, 27 ncurses, 28 withOpenssl ? !withMinimalDeps, 29 openssl, 30 withSqlite ? !withMinimalDeps, 31 sqlite, 32 xz, 33 zlib, 34 zstd, 35 36 # platform-specific dependencies 37 bashNonInteractive, 38 windows, 39 40 # optional dependencies 41 bluezSupport ? !withMinimalDeps && stdenv.hostPlatform.isLinux, 42 bluez-headers, 43 mimetypesSupport ? !withMinimalDeps, 44 mailcap, 45 tzdata, 46 withGdbm ? !withMinimalDeps && !stdenv.hostPlatform.isWindows, 47 gdbm, 48 withReadline ? !withMinimalDeps && !stdenv.hostPlatform.isWindows, 49 readline, 50 51 # splicing/cross 52 pythonAttr ? "python${sourceVersion.major}${sourceVersion.minor}", 53 self, 54 pkgsBuildBuild, 55 pkgsBuildHost, 56 pkgsBuildTarget, 57 pkgsHostHost, 58 pkgsTargetTarget, 59 __splices ? { }, 60 61 # build customization 62 sourceVersion, 63 hash, 64 passthruFun, 65 stripConfig ? withMinimalDeps, 66 stripIdlelib ? withMinimalDeps, 67 stripTests ? withMinimalDeps, 68 stripTkinter ? withMinimalDeps, 69 rebuildBytecode ? !withMinimalDeps, 70 stripBytecode ? true, 71 includeSiteCustomize ? !withMinimalDeps, 72 static ? stdenv.hostPlatform.isStatic, 73 enableFramework ? false, 74 noldconfigPatch ? ./. + "/${sourceVersion.major}.${sourceVersion.minor}/no-ldconfig.patch", 75 enableGIL ? true, 76 enableDebug ? false, 77 78 # pgo (not reproducible) + -fno-semantic-interposition 79 # https://docs.python.org/3/using/configure.html#cmdoption-enable-optimizations 80 enableOptimizations ? false, 81 82 # improves performance, but remains reproducible 83 enableNoSemanticInterposition ? true, 84 85 # enabling LTO on 32bit arch causes downstream packages to fail when linking 86 enableLTO ? 87 !withMinimalDeps 88 && (stdenv.hostPlatform.isDarwin || (stdenv.hostPlatform.is64bit && stdenv.hostPlatform.isLinux)), 89 90 # enable asserts to ensure the build remains reproducible 91 reproducibleBuild ? false, 92 93 # for the Python package set 94 packageOverrides ? (self: super: { }), 95 96 # tests 97 testers, 98 99 # allow pythonMinimal to prevent accidental dependencies it doesn't want 100 # Having this as an option is useful to allow overriding, eg. adding things to 101 # python3Minimal 102 allowedReferenceNames ? if withMinimalDeps then [ "bashNonInteractive" ] else [ ], 103 104}@inputs: 105 106# Note: this package is used for bootstrapping fetchurl, and thus 107# cannot use fetchpatch! All mutable patches (generated by GitHub or 108# cgit) that are needed here should be included directly in Nixpkgs as 109# files. 110 111assert lib.assertMsg ( 112 enableFramework -> stdenv.hostPlatform.isDarwin 113) "Framework builds are only supported on Darwin."; 114 115assert lib.assertMsg ( 116 reproducibleBuild -> stripBytecode 117) "Deterministic builds require stripping bytecode."; 118 119assert lib.assertMsg ( 120 reproducibleBuild -> (!enableOptimizations) 121) "Deterministic builds are not achieved when optimizations are enabled."; 122 123assert lib.assertMsg ( 124 reproducibleBuild -> (!rebuildBytecode) 125) "Deterministic builds are not achieved when (default unoptimized) bytecode is created."; 126 127let 128 inherit (lib) 129 concatMapStringsSep 130 concatStringsSep 131 enableFeature 132 getDev 133 getLib 134 optionals 135 optionalString 136 replaceStrings 137 ; 138 139 withLibxcrypt = 140 (!withMinimalDeps) 141 && 142 # mixes libc and libxcrypt headers and libs and causes segfaults on importing crypt 143 (!stdenv.hostPlatform.isFreeBSD) 144 && 145 # crypt module was removed in 3.13 146 passthru.pythonOlder "3.13"; 147 148 buildPackages = pkgsBuildHost; 149 inherit (passthru) pythonOnBuildForHost; 150 151 tzdataSupport = !withMinimalDeps && tzdata != null && passthru.pythonAtLeast "3.9"; 152 153 passthru = 154 let 155 # When we override the interpreter we also need to override the spliced versions of the interpreter 156 inputs' = lib.filterAttrs (n: v: n != "passthruFun" && !lib.isDerivation v) inputs; 157 # Memoization of the splices to avoid re-evaluating this function for all combinations of splices e.g. 158 # python3.pythonOnBuildForHost.pythonOnBuildForTarget == python3.pythonOnBuildForTarget by consuming 159 # __splices as an arg and using the cache if populated. 160 splices = { 161 pythonOnBuildForBuild = override pkgsBuildBuild.${pythonAttr}; 162 pythonOnBuildForHost = override pkgsBuildHost.${pythonAttr}; 163 pythonOnBuildForTarget = override pkgsBuildTarget.${pythonAttr}; 164 pythonOnHostForHost = override pkgsHostHost.${pythonAttr}; 165 pythonOnTargetForTarget = lib.optionalAttrs (lib.hasAttr pythonAttr pkgsTargetTarget) ( 166 override pkgsTargetTarget.${pythonAttr} 167 ); 168 } 169 // __splices; 170 override = 171 attr: 172 let 173 python = attr.override ( 174 inputs' 175 // { 176 self = python; 177 __splices = splices; 178 } 179 ); 180 in 181 python; 182 in 183 passthruFun rec { 184 inherit self sourceVersion packageOverrides; 185 implementation = "cpython"; 186 libPrefix = "python${pythonVersion}${lib.optionalString (!enableGIL) "t"}"; 187 executable = libPrefix; 188 pythonVersion = with sourceVersion; "${major}.${minor}"; 189 sitePackages = "lib/${libPrefix}/site-packages"; 190 inherit hasDistutilsCxxPatch pythonAttr; 191 inherit (splices) 192 pythonOnBuildForBuild 193 pythonOnBuildForHost 194 pythonOnBuildForTarget 195 pythonOnHostForHost 196 pythonOnTargetForTarget 197 ; 198 199 pythonABITags = [ 200 "abi3" 201 "none" 202 "cp${sourceVersion.major}${sourceVersion.minor}${lib.optionalString (!enableGIL) "t"}" 203 ]; 204 }; 205 206 version = with sourceVersion; "${major}.${minor}.${patch}${suffix}"; 207 208 nativeBuildInputs = [ 209 nukeReferences 210 ] 211 ++ 212 optionals 213 ( 214 (!stdenv.hostPlatform.isDarwin && !withMinimalDeps) 215 || (stdenv.hostPlatform != stdenv.buildPlatform && stdenv.hostPlatform.isFreeBSD) 216 ) 217 [ 218 autoconf-archive # needed for AX_CHECK_COMPILE_FLAG 219 autoreconfHook 220 ] 221 ++ 222 optionals ((!stdenv.hostPlatform.isDarwin || passthru.pythonAtLeast "3.14") && !withMinimalDeps) 223 [ 224 pkg-config 225 ] 226 ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ 227 buildPackages.stdenv.cc 228 pythonOnBuildForHost 229 ] 230 ++ 231 optionals 232 ( 233 stdenv.cc.isClang 234 && (!stdenv.hostPlatform.useAndroidPrebuilt or false) 235 && (enableLTO || enableOptimizations) 236 ) 237 [ 238 stdenv.cc.cc.libllvm.out 239 ]; 240 241 buildInputs = lib.filter (p: p != null) ( 242 optionals (!withMinimalDeps) [ 243 bzip2 244 libffi 245 libuuid 246 ncurses 247 xz 248 zlib 249 ] 250 ++ optionals withLibxcrypt [ 251 libxcrypt 252 ] 253 ++ optionals withOpenssl [ 254 openssl 255 ] 256 ++ optionals withSqlite [ 257 sqlite 258 ] 259 ++ optionals withMpdecimal [ 260 mpdecimal 261 ] 262 ++ optionals withExpat [ 263 expat 264 ] 265 ++ optionals (passthru.pythonAtLeast "3.14") [ 266 zstd 267 ] 268 ++ optionals bluezSupport [ 269 bluez-headers 270 ] 271 ++ optionals stdenv.hostPlatform.isMinGW [ 272 windows.dlfcn 273 windows.pthreads 274 ] 275 ++ optionals tzdataSupport [ 276 tzdata 277 ] 278 ++ optionals withGdbm [ 279 gdbm 280 ] 281 ++ optionals withReadline [ 282 readline 283 ] 284 ); 285 286 hasDistutilsCxxPatch = !(stdenv.cc.isGNU or false); 287 288 pythonOnBuildForHostInterpreter = 289 if stdenv.hostPlatform == stdenv.buildPlatform then 290 "$out/bin/python" 291 else 292 pythonOnBuildForHost.interpreter; 293 294 src = fetchurl { 295 url = 296 with sourceVersion; 297 "https://www.python.org/ftp/python/${major}.${minor}.${patch}/Python-${version}.tar.xz"; 298 inherit hash; 299 }; 300 301 # win32 is added by Fedora’s patch 302 machdep = if stdenv.hostPlatform.isWindows then "win32" else stdenv.hostPlatform.parsed.kernel.name; 303 304 # https://github.com/python/cpython/blob/e488e300f5c01289c10906c2e53a8e43d6de32d8/configure.ac#L428 305 # The configure script uses "arm" as the CPU name for all 32-bit ARM 306 # variants when cross-compiling, but native builds include the version 307 # suffix, so we do the same. 308 pythonHostPlatform = 309 let 310 cpu = 311 { 312 # According to PEP600, Python's name for the Power PC 313 # architecture is "ppc", not "powerpc". Without the Rosetta 314 # Stone below, the PEP600 requirement that "${ARCH} matches 315 # the return value from distutils.util.get_platform()" fails. 316 # https://peps.python.org/pep-0600/ 317 powerpc = "ppc"; 318 powerpcle = "ppcle"; 319 powerpc64 = "ppc64"; 320 powerpc64le = "ppc64le"; 321 } 322 .${stdenv.hostPlatform.parsed.cpu.name} or stdenv.hostPlatform.parsed.cpu.name; 323 in 324 "${machdep}-${cpu}"; 325 326 execSuffix = stdenv.hostPlatform.extensions.executable; 327in 328with passthru; 329stdenv.mkDerivation (finalAttrs: { 330 pname = "python3"; 331 inherit src version; 332 333 inherit nativeBuildInputs; 334 buildInputs = 335 lib.optionals (!stdenv.hostPlatform.isWindows) [ 336 bashNonInteractive # only required for patchShebangs 337 ] 338 ++ buildInputs; 339 340 prePatch = optionalString stdenv.hostPlatform.isDarwin '' 341 substituteInPlace configure --replace-fail '`/usr/bin/arch`' '"i386"' 342 ''; 343 344 patches = [ 345 # Disable the use of ldconfig in ctypes.util.find_library (since 346 # ldconfig doesn't work on NixOS), and don't use 347 # ctypes.util.find_library during the loading of the uuid module 348 # (since it will do a futile invocation of gcc (!) to find 349 # libuuid, slowing down program startup a lot). 350 noldconfigPatch 351 ] 352 ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform && stdenv.hostPlatform.isFreeBSD) [ 353 # Cross compilation only supports a limited number of "known good" 354 # configurations. If you're reading this and it's been a long time 355 # since this diff, consider submitting this patch upstream! 356 ./freebsd-cross.patch 357 ] 358 ++ optionals (pythonOlder "3.13") [ 359 # Make sure that the virtualenv activation scripts are 360 # owner-writable, so venvs can be recreated without permission 361 # errors. 362 ./virtualenv-permissions.patch 363 ] 364 ++ optionals (pythonAtLeast "3.13") [ 365 ./3.13/virtualenv-permissions.patch 366 ] 367 ++ optionals mimetypesSupport [ 368 # Make the mimetypes module refer to the right file 369 ./mimetypes.patch 370 ] 371 ++ optionals (pythonAtLeast "3.9" && pythonOlder "3.11" && stdenv.hostPlatform.isDarwin) [ 372 # Stop checking for TCL/TK in global macOS locations 373 ./3.9/darwin-tcl-tk.patch 374 ] 375 ++ optionals (hasDistutilsCxxPatch && pythonOlder "3.12") [ 376 # Fix for http://bugs.python.org/issue1222585 377 # Upstream distutils is calling C compiler to compile C++ code, which 378 # only works for GCC and Apple Clang. This makes distutils to call C++ 379 # compiler when needed. 380 ( 381 if pythonAtLeast "3.7" && pythonOlder "3.11" then 382 ./3.7/python-3.x-distutils-C++.patch 383 else if pythonAtLeast "3.11" then 384 ./3.11/python-3.x-distutils-C++.patch 385 else 386 fetchpatch { 387 url = "https://bugs.python.org/file48016/python-3.x-distutils-C++.patch"; 388 sha256 = "1h18lnpx539h5lfxyk379dxwr8m2raigcjixkf133l4xy3f4bzi2"; 389 } 390 ) 391 ] 392 ++ optionals (pythonAtLeast "3.7" && pythonOlder "3.12") [ 393 # LDSHARED now uses $CC instead of gcc. Fixes cross-compilation of extension modules. 394 ./3.8/0001-On-all-posix-systems-not-just-Darwin-set-LDSHARED-if.patch 395 # Use sysconfigdata to find headers. Fixes cross-compilation of extension modules. 396 ./3.7/fix-finding-headers-when-cross-compiling.patch 397 ] 398 ++ optionals (pythonOlder "3.12") [ 399 # https://github.com/python/cpython/issues/90656 400 ./loongarch-support.patch 401 # fix failing tests with openssl >= 3.4 402 # https://github.com/python/cpython/pull/127361 403 ] 404 ++ optionals (pythonAtLeast "3.11" && pythonOlder "3.13") [ 405 # backport fix for https://github.com/python/cpython/issues/95855 406 ./platform-triplet-detection.patch 407 ] 408 ++ optionals (version == "3.13.10" || version == "3.14.1") [ 409 # https://github.com/python/cpython/issues/142218 410 ./${lib.versions.majorMinor version}/gh-142218.patch 411 ] 412 ++ optionals (stdenv.hostPlatform.isMinGW) ( 413 let 414 # https://src.fedoraproject.org/rpms/mingw-python3 415 mingw-patch = fetchgit { 416 name = "mingw-python-patches"; 417 url = "https://src.fedoraproject.org/rpms/mingw-python3.git"; 418 rev = "3edecdbfb4bbf1276d09cd5e80e9fb3dd88c9511"; # for python 3.11.9 at the time of writing. 419 hash = "sha256-kpXoIHlz53+0FAm/fK99ZBdNUg0u13erOr1XP2FSkQY="; 420 }; 421 in 422 (map (f: "${mingw-patch}/${f}") [ 423 # The other patches in that repo are already applied to 3.11.10 424 "mingw-python3_distutils.patch" 425 "mingw-python3_frozenmain.patch" 426 "mingw-python3_make-sysconfigdata.py-relocatable.patch" 427 "mingw-python3_mods-failed.patch" 428 "mingw-python3_module-select.patch" 429 "mingw-python3_module-socket.patch" 430 "mingw-python3_modules.patch" 431 "mingw-python3_platform-mingw.patch" 432 "mingw-python3_posix-layout.patch" 433 "mingw-python3_pthread_threadid.patch" 434 "mingw-python3_pythonw.patch" 435 "mingw-python3_setenv.patch" 436 "mingw-python3_win-modules.patch" 437 ]) 438 ); 439 440 postPatch = 441 optionalString (!stdenv.hostPlatform.isWindows) '' 442 substituteInPlace Lib/subprocess.py \ 443 --replace-fail "'/bin/sh'" "'${bashNonInteractive}/bin/sh'" 444 '' 445 + optionalString mimetypesSupport '' 446 substituteInPlace Lib/mimetypes.py \ 447 --replace-fail "@mime-types@" "${mailcap}" 448 ''; 449 450 env = { 451 CPPFLAGS = concatStringsSep " " (map (p: "-I${getDev p}/include") buildInputs); 452 LDFLAGS = concatStringsSep " " (map (p: "-L${getLib p}/lib") buildInputs); 453 LIBS = "${optionalString (!stdenv.hostPlatform.isDarwin && withLibxcrypt) "-lcrypt"}"; 454 NIX_LDFLAGS = lib.optionalString (stdenv.cc.isGNU && !stdenv.hostPlatform.isStatic) ( 455 { 456 "glibc" = "-lgcc_s"; 457 "musl" = "-lgcc_eh"; 458 } 459 ."${stdenv.hostPlatform.libc}" or "" 460 ); 461 # Determinism: We fix the hashes of str, bytes and datetime objects. 462 PYTHONHASHSEED = 0; 463 }; 464 465 # https://docs.python.org/3/using/configure.html 466 configureFlags = [ 467 "--without-ensurepip" 468 ] 469 ++ optionals withExpat [ 470 "--with-system-expat" 471 ] 472 ++ optionals withMpdecimal [ 473 "--with-system-libmpdec" 474 ] 475 ++ optionals withOpenssl [ 476 "--with-openssl=${openssl.dev}" 477 ] 478 ++ optionals tzdataSupport [ 479 "--with-tzpath=${tzdata}/share/zoneinfo" 480 ] 481 ++ optionals (execSuffix != "") [ 482 "--with-suffix=${execSuffix}" 483 ] 484 ++ optionals enableLTO [ 485 "--with-lto" 486 ] 487 ++ optionals (!static && !enableFramework) [ 488 "--enable-shared" 489 ] 490 ++ optionals enableFramework [ 491 "--enable-framework=${placeholder "out"}/Library/Frameworks" 492 ] 493 ++ optionals (pythonAtLeast "3.13") [ 494 (enableFeature enableGIL "gil") 495 ] 496 ++ optionals enableOptimizations [ 497 "--enable-optimizations" 498 ] 499 ++ optionals enableDebug [ 500 "--with-pydebug" 501 ] 502 ++ optionals withSqlite [ 503 "--enable-loadable-sqlite-extensions" 504 ] 505 ++ optionals withLibxcrypt [ 506 "CFLAGS=-I${libxcrypt}/include" 507 "LIBS=-L${libxcrypt}/lib" 508 ] 509 ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ 510 "ac_cv_buggy_getaddrinfo=no" 511 # Assume little-endian IEEE 754 floating point when cross compiling 512 "ac_cv_little_endian_double=yes" 513 "ac_cv_big_endian_double=no" 514 "ac_cv_mixed_endian_double=no" 515 "ac_cv_x87_double_rounding=yes" 516 "ac_cv_tanh_preserves_zero_sign=yes" 517 # Generally assume that things are present and work 518 "ac_cv_posix_semaphores_enabled=yes" 519 "ac_cv_broken_sem_getvalue=no" 520 "ac_cv_wchar_t_signed=yes" 521 "ac_cv_rshift_extends_sign=yes" 522 "ac_cv_broken_nice=no" 523 "ac_cv_broken_poll=no" 524 "ac_cv_working_tzset=yes" 525 "ac_cv_have_long_long_format=yes" 526 "ac_cv_have_size_t_format=yes" 527 "ac_cv_computed_gotos=yes" 528 # Both fail when building for windows, normally configure checks this by itself but on other platforms this is set to yes always. 529 "ac_cv_file__dev_ptmx=${lib.boolToYesNo (!stdenv.hostPlatform.isWindows)}" 530 "ac_cv_file__dev_ptc=${lib.boolToYesNo (!stdenv.hostPlatform.isWindows)}" 531 ] 532 ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform && pythonAtLeast "3.11") [ 533 "--with-build-python=${pythonOnBuildForHostInterpreter}" 534 ] 535 ++ optionals stdenv.hostPlatform.isLinux [ 536 # Never even try to use lchmod on linux, 537 # don't rely on detecting glibc-isms. 538 "ac_cv_func_lchmod=no" 539 ] 540 ++ optionals static [ 541 "--disable-test-modules" 542 "LDFLAGS=-static" 543 "MODULE_BUILDTYPE=static" 544 ] 545 ++ optionals (stdenv.hostPlatform.isStatic && stdenv.hostPlatform.isMusl) [ 546 # dlopen is a no-op in static musl builds, and since we build everything without -fPIC it's better not to pretend. 547 "ac_cv_func_dlopen=no" 548 ]; 549 550 preConfigure = '' 551 # Attempt to purify some of the host info collection 552 sed -E -i -e 's/uname -r/echo/g' -e 's/uname -n/echo nixpkgs/g' config.guess 553 sed -E -i -e 's/uname -r/echo/g' -e 's/uname -n/echo nixpkgs/g' configure 554 '' 555 + optionalString (pythonOlder "3.12") '' 556 # Improve purity 557 for path in /usr /sw /opt /pkg; do 558 substituteInPlace ./setup.py --replace-warn $path /no-such-path 559 done 560 '' 561 + optionalString (stdenv.hostPlatform.isDarwin && pythonOlder "3.12") '' 562 # Fix _ctypes module compilation 563 export NIX_CFLAGS_COMPILE+=" -DUSING_APPLE_OS_LIBFFI=1" 564 '' 565 + optionalString stdenv.hostPlatform.isDarwin '' 566 # Override the auto-detection in setup.py, which assumes a universal build 567 export PYTHON_DECIMAL_WITH_MACHINE=${if stdenv.hostPlatform.isAarch64 then "uint128" else "x64"} 568 # Ensure that modern platform features are enabled on Darwin in spite of having no version suffix. 569 sed -E -i -e 's|Darwin/\[12\]\[0-9\]\.\*|Darwin/*|' configure 570 '' 571 + optionalString (pythonAtLeast "3.11") '' 572 # Also override the auto-detection in `configure`. 573 substituteInPlace configure \ 574 --replace-fail 'libmpdec_machine=universal' 'libmpdec_machine=${ 575 if stdenv.hostPlatform.isAarch64 then "uint128" else "x64" 576 }' 577 '' 578 + optionalString stdenv.hostPlatform.isWindows '' 579 export NIX_CFLAGS_COMPILE+=" -Wno-error=incompatible-pointer-types" 580 '' 581 + optionalString stdenv.hostPlatform.isMusl '' 582 export NIX_CFLAGS_COMPILE+=" -DTHREAD_STACK_SIZE=0x100000" 583 '' 584 + 585 586 # enableNoSemanticInterposition essentially sets that CFLAG -fno-semantic-interposition 587 # which changes how symbols are looked up. This essentially means we can't override 588 # libpython symbols via LD_PRELOAD anymore. This is common enough as every build 589 # that uses --enable-optimizations has the same "issue". 590 # 591 # The Fedora wiki has a good article about their journey towards enabling this flag: 592 # https://fedoraproject.org/wiki/Changes/PythonNoSemanticInterpositionSpeedup 593 optionalString enableNoSemanticInterposition '' 594 export CFLAGS_NODIST="-fno-semantic-interposition" 595 ''; 596 597 setupHook = python-setup-hook sitePackages; 598 599 postInstall = 600 let 601 # References *not* to nuke from (sys)config files 602 keep-references = concatMapStringsSep " " (val: "-e ${val}") ( 603 [ 604 (placeholder "out") 605 ] 606 ++ lib.optional withLibxcrypt libxcrypt 607 ++ lib.optional tzdataSupport tzdata 608 ); 609 in 610 lib.optionalString enableFramework '' 611 for dir in include lib share; do 612 ln -s $out/Library/Frameworks/Python.framework/Versions/Current/$dir $out/$dir 613 done 614 '' 615 + '' 616 # needed for some packages, especially packages that backport functionality 617 # to 2.x from 3.x 618 for item in $out/lib/${libPrefix}/test/*; do 619 if [[ "$item" != */test_support.py* 620 && "$item" != */test/support 621 && "$item" != */test/libregrtest 622 && "$item" != */test/regrtest.py* ]]; then 623 rm -rf "$item" 624 else 625 echo $item 626 fi 627 done 628 '' 629 + lib.optionalString (!static) '' 630 touch $out/lib/${libPrefix}/test/__init__.py 631 '' 632 + '' 633 634 # Determinism: Windows installers were not deterministic. 635 # We're also not interested in building Windows installers. 636 find "$out" -name 'wininst*.exe' | xargs -r rm -f 637 638 # Use Python3 as default python 639 ln -s "$out/bin/idle3" "$out/bin/idle" 640 ln -s "$out/bin/pydoc3" "$out/bin/pydoc" 641 ln -s "$out/bin/python3${execSuffix}" "$out/bin/python${execSuffix}" 642 ln -s "$out/bin/python3-config" "$out/bin/python-config" 643 ln -s "$out/lib/pkgconfig/python3.pc" "$out/lib/pkgconfig/python.pc" 644 ln -sL "$out/share/man/man1/python3.1.gz" "$out/share/man/man1/python.1.gz" 645 646 # Get rid of retained dependencies on -dev packages, and remove 647 # some $TMPDIR references to improve binary reproducibility. 648 # Note that the .pyc file of _sysconfigdata.py should be regenerated! 649 for i in $out/lib/${libPrefix}/_sysconfigdata*.py $out/lib/${libPrefix}/config-${sourceVersion.major}.${sourceVersion.minor}*/Makefile; do 650 sed -i $i -e "s|$TMPDIR|/no-such-path|g" 651 done 652 653 # Further get rid of references. https://github.com/NixOS/nixpkgs/issues/51668 654 find $out/lib/python*/config-* -type f -print -exec nuke-refs ${keep-references} '{}' + 655 find $out/lib -name '_sysconfigdata*.py*' -print -exec nuke-refs ${keep-references} '{}' + 656 657 # Make the sysconfigdata module accessible on PYTHONPATH 658 # This allows build Python to import host Python's sysconfigdata 659 mkdir -p "$out/${sitePackages}" 660 ln -s "$out/lib/${libPrefix}/"_sysconfigdata*.py "$out/${sitePackages}/" 661 '' 662 + optionalString (pythonAtLeast "3.14") '' 663 # Get rid of retained dependencies on -dev packages, and remove from _sysconfig_vars*.json introduced with Python3.14 664 for i in $out/lib/${libPrefix}/_sysconfig_vars*.json; do 665 sed -i $i -e "s|$TMPDIR|/no-such-path|g" 666 done 667 find $out/lib -name '_sysconfig_vars*.json*' -print -exec nuke-refs ${keep-references} '{}' + 668 ln -s "$out/lib/${libPrefix}/"_sysconfig_vars*.json "$out/${sitePackages}/" 669 '' 670 + optionalString stripConfig '' 671 rm -R $out/bin/python*-config $out/lib/python*/config-* 672 '' 673 + optionalString stripIdlelib '' 674 # Strip IDLE (and turtledemo, which uses it) 675 rm -R $out/bin/idle* $out/lib/python*/{idlelib,turtledemo} 676 '' 677 + optionalString stripTkinter '' 678 rm -R $out/lib/python*/tkinter 679 '' 680 + optionalString stripTests '' 681 # Strip tests 682 rm -R $out/lib/python*/test $out/lib/python*/**/test{,s} 683 '' 684 + optionalString includeSiteCustomize '' 685 # Include a sitecustomize.py file 686 cp ${../sitecustomize.py} $out/${sitePackages}/sitecustomize.py 687 '' 688 + optionalString stripBytecode '' 689 # Determinism: deterministic bytecode 690 # First we delete all old bytecode. 691 find $out -type d -name __pycache__ -print0 | xargs -0 -I {} rm -rf "{}" 692 '' 693 + optionalString rebuildBytecode '' 694 # Python 3.7 implements PEP 552, introducing support for deterministic bytecode. 695 # compileall uses the therein introduced checked-hash method by default when 696 # `SOURCE_DATE_EPOCH` is set. 697 # We exclude lib2to3 because that's Python 2 code which fails 698 # We build 3 levels of optimized bytecode. Note the default level, without optimizations, 699 # is not reproducible yet. https://bugs.python.org/issue29708 700 # Not creating bytecode will result in a large performance loss however, so we do build it. 701 find $out -name "*.py" | ${pythonOnBuildForHostInterpreter} -m compileall -q -f -x "lib2to3" -i - 702 find $out -name "*.py" | ${pythonOnBuildForHostInterpreter} -O -m compileall -q -f -x "lib2to3" -i - 703 find $out -name "*.py" | ${pythonOnBuildForHostInterpreter} -OO -m compileall -q -f -x "lib2to3" -i - 704 '' 705 + '' 706 # *strip* shebang from libpython gdb script - it should be dual-syntax and 707 # interpretable by whatever python the gdb in question is using, which may 708 # not even match the major version of this python. doing this after the 709 # bytecode compilations for the same reason - we don't want bytecode generated. 710 mkdir -p $out/share/gdb 711 sed '/^#!/d' Tools/gdb/libpython.py > $out/share/gdb/libpython.py 712 713 # Disable system-wide pip installation. See https://peps.python.org/pep-0668/. 714 cat <<'EXTERNALLY_MANAGED' > $out/lib/${libPrefix}/EXTERNALLY-MANAGED 715 [externally-managed] 716 Error=This command has been disabled as it tries to modify the immutable 717 `/nix/store` filesystem. 718 719 To use Python with Nix and nixpkgs, have a look at the online documentation: 720 <https://nixos.org/manual/nixpkgs/stable/#python>. 721 EXTERNALLY_MANAGED 722 '' 723 + optionalString stdenv.hostPlatform.isWindows '' 724 # Shebang files that link against the build python. Shebang dont work on windows 725 rm $out/bin/2to3* 726 rm $out/bin/idle* 727 rm $out/bin/pydoc* 728 729 echo linking DLLs for pythons compiled librairies 730 linkDLLsInfolder $out/lib/python*/lib-dynload/ 731 ''; 732 733 preFixup = lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) '' 734 # Ensure patch-shebangs uses shebangs of host interpreter. 735 export PATH=${lib.makeBinPath [ "$out" ]}:$PATH 736 ''; 737 738 # Add CPython specific setup-hook that configures distutils.sysconfig to 739 # always load sysconfigdata from host Python. 740 postFixup = lib.optionalString (!stdenv.hostPlatform.isDarwin) '' 741 # https://github.com/python/cpython/blob/e488e300f5c01289c10906c2e53a8e43d6de32d8/configure.ac#L78 742 sysconfigdataName="$(make --eval $'print-sysconfigdata-name: 743 \t@echo _sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) ' print-sysconfigdata-name)" 744 745 # The CPython interpreter contains a _sysconfigdata_<platform specific suffix> 746 # module that is imported by the sysconfig and distutils.sysconfig modules. 747 # The sysconfigdata module is generated at build time and contains settings 748 # required for building Python extension modules, such as include paths and 749 # other compiler flags. By default, the sysconfigdata module is loaded from 750 # the currently running interpreter (ie. the build platform interpreter), but 751 # when cross-compiling we want to load it from the host platform interpreter. 752 # This can be done using the _PYTHON_SYSCONFIGDATA_NAME environment variable. 753 # The _PYTHON_HOST_PLATFORM variable also needs to be set to get the correct 754 # platform suffix on extension modules. The correct values for these variables 755 # are not documented, and must be derived from the configure script (see links 756 # below). 757 cat <<EOF >> "$out/nix-support/setup-hook" 758 sysconfigdataHook() { 759 if [ "\$1" = '$out' ]; then 760 export _PYTHON_HOST_PLATFORM='${pythonHostPlatform}' 761 export _PYTHON_SYSCONFIGDATA_NAME='$sysconfigdataName' 762 fi 763 } 764 765 addEnvHooks "\$hostOffset" sysconfigdataHook 766 EOF 767 ''; 768 769 # Enforce that we don't have references to the OpenSSL -dev package, which we 770 # explicitly specify in our configure flags above. 771 disallowedReferences = 772 lib.optionals (withOpenssl && !static && !enableFramework) [ 773 openssl.dev 774 ] 775 ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ 776 # Ensure we don't have references to build-time packages. 777 # These typically end up in shebangs. 778 pythonOnBuildForHost 779 buildPackages.bashNonInteractive 780 ]; 781 782 # Optionally set allowedReferences to guarantee minimal dependencies 783 # Allows python3Minimal to stay minimal and not have deps added by accident 784 # Doesn't do anything if allowedReferenceNames is empty (was not set) 785 ${if allowedReferenceNames != [ ] then "allowedReferences" else null} = 786 # map allowed names to their derivations 787 (map (name: inputs.${name}) allowedReferenceNames) ++ [ 788 # any version of python depends on libc and libgcc 789 stdenv.cc.cc.lib 790 stdenv.cc.libc 791 # allows python referring to its own store path 792 "out" 793 ]; 794 795 separateDebugInfo = true; 796 __structuredAttrs = true; 797 798 passthru = passthru // { 799 doc = stdenv.mkDerivation { 800 inherit src; 801 name = "python${pythonVersion}-${version}-doc"; 802 803 postPatch = lib.optionalString (pythonAtLeast "3.9" && pythonOlder "3.11") '' 804 substituteInPlace Doc/tools/extensions/pyspecific.py \ 805 --replace-fail "from sphinx.util import status_iterator" "from sphinx.util.display import status_iterator" 806 ''; 807 808 dontConfigure = true; 809 810 dontBuild = true; 811 812 sphinxRoot = "Doc"; 813 814 postInstallSphinx = '' 815 mv $out/share/doc/* $out/share/doc/python${pythonVersion}-${version} 816 ''; 817 818 nativeBuildInputs = with pkgsBuildBuild.python3.pkgs; [ 819 sphinxHook 820 python-docs-theme 821 ]; 822 }; 823 824 tests = passthru.tests // { 825 pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; 826 }; 827 }; 828 829 enableParallelBuilding = true; 830 831 meta = { 832 homepage = "https://www.python.org"; 833 changelog = 834 let 835 majorMinor = lib.versions.majorMinor version; 836 dashedVersion = lib.replaceStrings [ "." "a" "b" ] [ "-" "-alpha-" "-beta-" ] version; 837 in 838 if sourceVersion.suffix == "" then 839 "https://docs.python.org/release/${version}/whatsnew/changelog.html" 840 else 841 "https://docs.python.org/${majorMinor}/whatsnew/changelog.html#python-${dashedVersion}"; 842 description = "High-level dynamically-typed programming language"; 843 longDescription = '' 844 Python is a remarkably powerful dynamic programming language that 845 is used in a wide variety of application domains. Some of its key 846 distinguishing features include: clear, readable syntax; strong 847 introspection capabilities; intuitive object orientation; natural 848 expression of procedural code; full modularity, supporting 849 hierarchical packages; exception-based error handling; and very 850 high level dynamic data types. 851 ''; 852 license = lib.licenses.psfl; 853 pkgConfigModules = [ "python3" ]; 854 platforms = 855 lib.platforms.linux ++ lib.platforms.darwin ++ lib.platforms.windows ++ lib.platforms.freebsd; 856 mainProgram = executable; 857 teams = [ lib.teams.python ]; 858 # static build on x86_64-darwin/aarch64-darwin breaks with: 859 # configure: error: C compiler cannot create executables 860 861 # mingw patches only apply to Python 3.11 currently 862 broken = 863 (lib.versions.minor version != "11" && stdenv.hostPlatform.isWindows) 864 || (stdenv.hostPlatform.isStatic && stdenv.hostPlatform.isDarwin); 865 }; 866})