diff options
| author | Ricardo Wurmus <rekado@elephly.net> | 2025-01-27 08:40:50 +0100 |
|---|---|---|
| committer | Andreas Enge <andreas@enge.fr> | 2025-04-16 11:46:10 +0200 |
| commit | 815a70440fdc31ded1fc3c056f1a7b1503e3d78a (patch) | |
| tree | 33b81c75f227e0dc1f0c94114a0e947e8b25d5e7 /gnu/packages/python.scm | |
| parent | 1e62855b54ba7b05ec0a8de07a31726d35e8860e (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.scm | 461 |
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 |
