summaryrefslogtreecommitdiff
path: root/gnu/packages/python.scm
diff options
context:
space:
mode:
authorRicardo Wurmus <rekado@elephly.net>2025-01-27 08:40:50 +0100
committerAndreas Enge <andreas@enge.fr>2025-04-16 11:46:10 +0200
commit815a70440fdc31ded1fc3c056f1a7b1503e3d78a (patch)
tree33b81c75f227e0dc1f0c94114a0e947e8b25d5e7 /gnu/packages/python.scm
parent1e62855b54ba7b05ec0a8de07a31726d35e8860e (diff)
gnu: python-3.11: Build with libxcrypt.
Linking with libxcrypt provides a featureful fallback for the included crypto module, thus fixing the virtually unmaintained but still widely used python-passlib. * gnu/packages/python.scm (python-3.11)[arguments]<configure-flags>: Link with libcrypt if available. <phases>: Use G-expression; add phase 'add-libxcrypt-reference-pkgconfig. [inputs]: Add libxcrypt. Change-Id: I2e51df7f7f2cc8909ee64717648a36ed0da3f198
Diffstat (limited to 'gnu/packages/python.scm')
-rw-r--r--gnu/packages/python.scm461
1 files changed, 241 insertions, 220 deletions
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 0c5acfcc987..e2349f04247 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -692,9 +692,9 @@ def contents() -> str:
692 (list 692 (list
693 #:test-target "test" 693 #:test-target "test"
694 #:configure-flags 694 #:configure-flags
695 #~(list "--enable-shared" ;allow embedding 695 #~(list "--enable-shared" ;allow embedding
696 "--with-system-expat" ;for XML support 696 "--with-system-expat" ;for XML support
697 "--with-system-ffi" ;build ctypes 697 "--with-system-ffi" ;build ctypes
698 "--with-ensurepip=install" ;install pip and setuptools 698 "--with-ensurepip=install" ;install pip and setuptools
699 "--with-computed-gotos" ;main interpreter loop optimization 699 "--with-computed-gotos" ;main interpreter loop optimization
700 "--enable-unicode=ucs4" 700 "--enable-unicode=ucs4"
@@ -711,6 +711,20 @@ def contents() -> str:
711 "INSTALL=install -c" 711 "INSTALL=install -c"
712 "MKDIR_P=mkdir -p" 712 "MKDIR_P=mkdir -p"
713 713
714 ;; Add a reference to libxcrypt in LIBS so that the
715 ;; sysconfigdata file records it and propagates it to programs
716 ;; linking against Python.
717 (let ((libxcrypt
718 (false-if-exception
719 (dirname
720 (search-input-file %build-inputs
721 "lib/libcrypt.so.1")))))
722 (string-append
723 "LIBS="
724 (if libxcrypt
725 (string-append "-L" libxcrypt)
726 "")))
727
714 ;; Disable runtime check failing if cross-compiling, see: 728 ;; Disable runtime check failing if cross-compiling, see:
715 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html 729 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
716 #$@(if (%current-target-system) 730 #$@(if (%current-target-system)
@@ -790,229 +804,236 @@ def contents() -> str:
790 (guix build gnu-build-system)) 804 (guix build gnu-build-system))
791 805
792 #:phases 806 #:phases
793 `(modify-phases %standard-phases 807 #~(modify-phases %standard-phases
794 ,@(if (system-hurd?) 808 #$@(if (system-hurd?)
795 `((add-after 'unpack 809 `((add-after 'unpack
796 'disable-multi-processing 810 'disable-multi-processing
797 (lambda _ 811 (lambda _
798 (substitute* "Makefile.pre.in" 812 (substitute* "Makefile.pre.in"
799 (("-j0") 813 (("-j0")
800 "-j1"))))) 814 "-j1")))))
801 '()) 815 '())
802 (add-before 'configure 'patch-lib-shells 816 (add-before 'configure 'patch-lib-shells
803 (lambda _ 817 (lambda _
804 ;; This variable is used in setup.py to enable cross compilation 818 ;; This variable is used in setup.py to enable cross compilation
805 ;; specific switches. As it is not set properly by configure 819 ;; specific switches. As it is not set properly by configure
806 ;; script, set it manually. 820 ;; script, set it manually.
807 ,@(if (%current-target-system) 821 #$@(if (%current-target-system)
808 '((setenv "_PYTHON_HOST_PLATFORM" "")) 822 '((setenv "_PYTHON_HOST_PLATFORM" ""))
809 '()) 823 '())
810 ;; Filter for existing files, since some may not exist in all 824 ;; Filter for existing files, since some may not exist in all
811 ;; versions of python that are built with this recipe. 825 ;; versions of python that are built with this recipe.
812 (substitute* (filter file-exists? 826 (substitute* (filter file-exists?
813 '("Lib/subprocess.py" 827 '("Lib/subprocess.py"
814 "Lib/popen2.py" 828 "Lib/popen2.py"
815 "Lib/distutils/tests/test_spawn.py" 829 "Lib/distutils/tests/test_spawn.py"
816 "Lib/test/support/__init__.py" 830 "Lib/test/support/__init__.py"
817 "Lib/test/test_subprocess.py")) 831 "Lib/test/test_subprocess.py"))
818 (("/bin/sh") 832 (("/bin/sh")
819 (which "sh"))))) 833 (which "sh")))))
820 (add-before 'configure 'do-not-record-configure-flags 834 (add-before 'configure 'do-not-record-configure-flags
821 (lambda* (#:key configure-flags #:allow-other-keys) 835 (lambda* (#:key configure-flags #:allow-other-keys)
822 ;; Remove configure flags from the installed '_sysconfigdata.py' 836 ;; Remove configure flags from the installed '_sysconfigdata.py'
823 ;; and 'Makefile' so we don't end up keeping references to the 837 ;; and 'Makefile' so we don't end up keeping references to the
824 ;; build tools. 838 ;; build tools.
825 ;; 839 ;;
826 ;; Preserve at least '--with-system-ffi' since otherwise the 840 ;; Preserve at least '--with-system-ffi' since otherwise the
827 ;; thing tries to build libffi, fails, and we end up with a 841 ;; thing tries to build libffi, fails, and we end up with a
828 ;; Python that lacks ctypes. 842 ;; Python that lacks ctypes.
829 (substitute* "configure" 843 (substitute* "configure"
830 (("^CONFIG_ARGS=.*$") 844 (("^CONFIG_ARGS=.*$")
831 (format #f "CONFIG_ARGS='~a'\n" 845 (format #f "CONFIG_ARGS='~a'\n"
832 (if (member "--with-system-ffi" 846 (if (member "--with-system-ffi"
833 configure-flags) 847 configure-flags)
834 "--with-system-ffi" "")))))) 848 "--with-system-ffi" ""))))))
835 (add-before 'check 'pre-check 849 (add-before 'check 'pre-check
836 (lambda _ 850 (lambda _
837 ;; 'Lib/test/test_site.py' needs a valid $HOME 851 ;; 'Lib/test/test_site.py' needs a valid $HOME
838 (setenv "HOME" 852 (setenv "HOME"
839 (getcwd)))) 853 (getcwd))))
840 (add-after 'unpack 'set-source-file-times-to-1980 854 (add-after 'unpack 'set-source-file-times-to-1980
841 ;; XXX One of the tests uses a ZIP library to pack up some of the 855 ;; XXX One of the tests uses a ZIP library to pack up some of the
842 ;; source tree, and fails with "ZIP does not support timestamps 856 ;; source tree, and fails with "ZIP does not support timestamps
843 ;; before 1980". Work around this by setting the file times in the 857 ;; before 1980". Work around this by setting the file times in the
844 ;; source tree to sometime in early 1980. 858 ;; source tree to sometime in early 1980.
845 (lambda _ 859 (lambda _
846 (let ((circa-1980 (* 10 366 24 60 60))) 860 (let ((circa-1980 (* 10 366 24 60 60)))
847 (ftw "." 861 (ftw "."
848 (lambda (file stat flag) 862 (lambda (file stat flag)
849 (utime file circa-1980 circa-1980) #t))))) 863 (utime file circa-1980 circa-1980) #t)))))
850 (add-after 'unpack 'remove-windows-binaries 864 (add-after 'unpack 'remove-windows-binaries
851 (lambda _ 865 (lambda _
852 ;; Delete .exe from embedded .whl (zip) files 866 ;; Delete .exe from embedded .whl (zip) files
853 (for-each (lambda (whl) 867 (for-each (lambda (whl)
854 (let ((dir "whl-content") 868 (let ((dir "whl-content")
855 (circa-1980 (* 10 366 24 60 60))) 869 (circa-1980 (* 10 366 24 60 60)))
856 (mkdir-p dir) 870 (mkdir-p dir)
857 (with-directory-excursion dir 871 (with-directory-excursion dir
858 (let ((whl (string-append "../" whl))) 872 (let ((whl (string-append "../" whl)))
859 (invoke "unzip" whl) 873 (invoke "unzip" whl)
860 (for-each delete-file 874 (for-each delete-file
861 (find-files "." "\\.exe$")) 875 (find-files "." "\\.exe$"))
862 (delete-file whl) 876 (delete-file whl)
863 ;; Reset timestamps to prevent them from ending 877 ;; Reset timestamps to prevent them from ending
864 ;; up in the Zip archive. 878 ;; up in the Zip archive.
865 (ftw "." 879 (ftw "."
866 (lambda (file stat flag) 880 (lambda (file stat flag)
867 (utime file circa-1980 881 (utime file circa-1980
868 circa-1980) #t)) 882 circa-1980) #t))
869 (apply invoke "zip" "-X" whl 883 (apply invoke "zip" "-X" whl
870 (find-files "." 884 (find-files "."
871 #:directories? #t)))) 885 #:directories? #t))))
872 (delete-file-recursively dir))) 886 (delete-file-recursively dir)))
873 (find-files "Lib/ensurepip" "\\.whl$")))) 887 (find-files "Lib/ensurepip" "\\.whl$"))))
874 (add-after 'install 'remove-tests 888 (add-after 'install 'remove-tests
875 ;; Remove 25 MiB of unneeded unit tests. Keep test_support.* 889 ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
876 ;; because these files are used by some libraries out there. 890 ;; because these files are used by some libraries out there.
877 (lambda* (#:key outputs #:allow-other-keys) 891 (lambda* (#:key outputs #:allow-other-keys)
878 (let ((out (assoc-ref outputs "out"))) 892 (let ((out (assoc-ref outputs "out")))
879 (match (scandir (string-append out "/lib") 893 (match (scandir (string-append out "/lib")
880 (lambda (name) 894 (lambda (name)
881 (string-prefix? "python" name))) 895 (string-prefix? "python" name)))
882 ((pythonX.Y) 896 ((pythonX.Y)
883 (let ((testdir (string-append out "/lib/" pythonX.Y 897 (let ((testdir (string-append out "/lib/" pythonX.Y
884 "/test"))) 898 "/test")))
885 (with-directory-excursion testdir 899 (with-directory-excursion testdir
886 (for-each delete-file-recursively 900 (for-each delete-file-recursively
887 (scandir testdir 901 (scandir testdir
888 (match-lambda 902 (match-lambda
889 ((or "." "..") 903 ((or "." "..")
890 #f) 904 #f)
891 ("support" #f) 905 ("support" #f)
892 (file (not (string-prefix? 906 (file (not (string-prefix?
893 "test_support." 907 "test_support."
894 file)))))) 908 file))))))
895 (call-with-output-file "__init__.py" 909 (call-with-output-file "__init__.py"
896 (const #t)))) 910 (const #t))))
897 (let ((libdir (string-append out "/lib/" pythonX.Y))) 911 (let ((libdir (string-append out "/lib/" pythonX.Y)))
898 (for-each (lambda (directory) 912 (for-each (lambda (directory)
899 (let ((dir (string-append libdir "/" 913 (let ((dir (string-append libdir "/"
900 directory))) 914 directory)))
901 (when (file-exists? dir) 915 (when (file-exists? dir)
902 (delete-file-recursively dir)))) 916 (delete-file-recursively dir))))
903 '("email/test" "ctypes/test" 917 '("email/test" "ctypes/test"
904 "unittest/test" 918 "unittest/test"
905 "tkinter/test" 919 "tkinter/test"
906 "sqlite3/test" 920 "sqlite3/test"
907 "bsddb/test" 921 "bsddb/test"
908 "lib-tk/test" 922 "lib-tk/test"
909 "json/tests" 923 "json/tests"
910 "distutils/tests")))))))) 924 "distutils/tests"))))))))
911 (add-after 'remove-tests 'move-tk-inter 925 (add-after 'remove-tests 'move-tk-inter
912 (lambda* (#:key outputs inputs #:allow-other-keys) 926 (lambda* (#:key outputs inputs #:allow-other-keys)
913 ;; When Tkinter support is built move it to a separate output so 927 ;; When Tkinter support is built move it to a separate output so
914 ;; that the main output doesn't contain a reference to Tcl/Tk. 928 ;; that the main output doesn't contain a reference to Tcl/Tk.
915 (let ((out (assoc-ref outputs "out")) 929 (let ((out (assoc-ref outputs "out"))
916 (tk (assoc-ref outputs "tk"))) 930 (tk (assoc-ref outputs "tk")))
917 (when tk 931 (when tk
918 (match (find-files out "tkinter.*\\.so") 932 (match (find-files out "tkinter.*\\.so")
919 ((tkinter.so) 933 ((tkinter.so)
920 ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we 934 ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
921 ;; want it under TK/lib/pythonX.Y/site-packages. 935 ;; want it under TK/lib/pythonX.Y/site-packages.
922 (let* ((len (string-length out)) 936 (let* ((len (string-length out))
923 (target (string-append tk "/" 937 (target (string-append tk "/"
924 (string-drop (dirname 938 (string-drop (dirname
925 (dirname 939 (dirname
926 tkinter.so)) 940 tkinter.so))
927 len) 941 len)
928 "/site-packages"))) 942 "/site-packages")))
929 (install-file tkinter.so target) 943 (install-file tkinter.so target)
930 (delete-file tkinter.so)))) 944 (delete-file tkinter.so))))
931 ;; Remove explicit store path references. 945 ;; Remove explicit store path references.
932 (let ((tcl (assoc-ref inputs "tcl")) 946 (let ((tcl (assoc-ref inputs "tcl"))
933 (tk (assoc-ref inputs "tk"))) 947 (tk (assoc-ref inputs "tk")))
934 (substitute* (find-files (string-append out "/lib") 948 (substitute* (find-files (string-append out "/lib")
935 "^(_sysconfigdata_.*\\.py|Makefile)$") 949 "^(_sysconfigdata_.*\\.py|Makefile)$")
936 (((string-append "-L" tk "/lib")) 950 (((string-append "-L" tk "/lib"))
937 "") 951 "")
938 (((string-append "-L" tcl "/lib")) 952 (((string-append "-L" tcl "/lib"))
939 ""))))))) 953 "")))))))
940 (add-after 'move-tk-inter 'move-idle 954 (add-after 'move-tk-inter 'move-idle
941 (lambda* (#:key outputs #:allow-other-keys) 955 (lambda* (#:key outputs #:allow-other-keys)
942 ;; when idle is built, move it to a separate output to save some 956 ;; when idle is built, move it to a separate output to save some
943 ;; space (5MB) 957 ;; space (5MB)
944 (let ((out (assoc-ref outputs "out")) 958 (let ((out (assoc-ref outputs "out"))
945 (idle (assoc-ref outputs "idle"))) 959 (idle (assoc-ref outputs "idle")))
946 (when idle 960 (when idle
947 (for-each (lambda (file) 961 (for-each (lambda (file)
948 (let ((target (string-append idle 962 (let ((target (string-append idle
949 "/bin/" 963 "/bin/"
950 (basename 964 (basename
951 file)))) 965 file))))
952 (install-file file 966 (install-file file
953 (dirname target)) 967 (dirname target))
954 (delete-file file))) 968 (delete-file file)))
955 (find-files (string-append out "/bin") 969 (find-files (string-append out "/bin")
956 "^idle")) 970 "^idle"))
957 (match (find-files out "^idlelib$" 971 (match (find-files out "^idlelib$"
958 #:directories? #t) 972 #:directories? #t)
959 ((idlelib) 973 ((idlelib)
960 (let* ((len (string-length out)) 974 (let* ((len (string-length out))
961 (target (string-append idle "/" 975 (target (string-append idle "/"
962 (string-drop 976 (string-drop
963 idlelib len) 977 idlelib len)
964 "/site-packages"))) 978 "/site-packages")))
965 (mkdir-p (dirname target)) 979 (mkdir-p (dirname target))
966 (rename-file idlelib target)))))))) 980 (rename-file idlelib target))))))))
967 (add-after 'move-idle 'rebuild-bytecode 981 (add-after 'move-idle 'rebuild-bytecode
968 (lambda* (#:key outputs #:allow-other-keys) 982 (lambda* (#:key outputs #:allow-other-keys)
969 (let ((out (assoc-ref outputs "out"))) 983 ;; Disable hash randomization to ensure the generated .pycs
970 ;; Disable hash randomization to ensure the generated .pycs 984 ;; are reproducible.
971 ;; are reproducible. 985 (setenv "PYTHONHASHSEED" "0")
972 (setenv "PYTHONHASHSEED" "0")
973 986
974 (for-each (lambda (output) 987 (for-each (lambda (output)
975 ;; XXX: Delete existing pycs generated by the build 988 ;; XXX: Delete existing pycs generated by the build
976 ;; system beforehand because the -f argument does 989 ;; system beforehand because the -f argument does
977 ;; not necessarily overwrite all files, leading to 990 ;; not necessarily overwrite all files, leading to
978 ;; indeterministic results. 991 ;; indeterministic results.
979 (for-each (lambda (pyc) 992 (for-each (lambda (pyc)
980 (delete-file pyc)) 993 (delete-file pyc))
981 (find-files output "\\.pyc$")) 994 (find-files output "\\.pyc$"))
982 995
983 (apply invoke 996 (apply invoke
984 `(,,(if (%current-target-system) 997 #$(if (%current-target-system)
985 "python3" 998 "python3"
986 '(string-append out 999 #~(string-append #$output "/bin/python3"))
987 "/bin/python3")) "-m" 1000 `("-m" "compileall"
988 "compileall" 1001 "-o" "0"
989 "-o" 1002 "-o" "1"
990 "0" 1003 "-o" "2"
991 "-o" 1004 "-f" ;force rebuild
992 "1" 1005 "--invalidation-mode=unchecked-hash"
993 "-o" 1006 ;; Don't build lib2to3, because it's Python
994 "2" 1007 ;; 2 code.
995 "-f" ;force rebuild 1008 "-x" "lib2to3/.*"
996 "--invalidation-mode=unchecked-hash" 1009 ,output)))
997 ;; Don't build lib2to3, because it's 1010 (map cdr outputs))))
998 ;; Python 2 code. 1011 (add-before 'check 'set-TZDIR
999 "-x" 1012 (lambda* (#:key inputs native-inputs #:allow-other-keys)
1000 "lib2to3/.*" 1013 ;; test_email requires the Olson time zone database.
1001 ,output))) 1014 (setenv "TZDIR"
1002 (map cdr outputs))))) 1015 (string-append (assoc-ref (or native-inputs
1003 (add-before 'check 'set-TZDIR 1016 inputs) "tzdata")
1004 (lambda* (#:key inputs native-inputs #:allow-other-keys) 1017 "/share/zoneinfo"))))
1005 ;; test_email requires the Olson time zone database. 1018 (add-after 'install 'add-libxcrypt-reference-pkgconfig
1006 (setenv "TZDIR" 1019 (lambda* (#:key inputs #:allow-other-keys)
1007 (string-append (assoc-ref (or native-inputs 1020 (let ((libxcrypt
1008 inputs) "tzdata") 1021 (false-if-exception
1009 "/share/zoneinfo")))) 1022 (dirname
1010 (add-after 'install 'install-sitecustomize.py 1023 (search-input-file inputs "lib/libcrypt.so.1")))))
1011 ,(customize-site version))))) 1024 (when libxcrypt
1025 (substitute*
1026 (find-files (string-append #$output "/lib/pkgconfig")
1027 ".*\\.pc")
1028 (("Libs:")
1029 (string-append "Libs: " "-L" libxcrypt " -lcrypt")))))))
1030 (add-after 'install 'install-sitecustomize.py
1031 #$(customize-site version)))))
1012 (inputs (list bzip2 1032 (inputs (list bzip2
1013 expat 1033 expat
1014 gdbm 1034 gdbm
1015 libffi ;for ctypes 1035 libffi ;for ctypes
1036 libxcrypt ;crypto module slated for removal in 3.13
1016 sqlite ;for sqlite extension 1037 sqlite ;for sqlite extension
1017 openssl 1038 openssl
1018 readline 1039 readline