From 928f69cf9ab4df25074de1196e9c3cffe02087f6 Mon Sep 17 00:00:00 2001 From: Alex Hedges Date: Thu, 5 Oct 2023 23:59:29 -0400 Subject: [PATCH] Install ncurses from Homebrew, if available (#2813) XCode Command Line Tools 15.0 was recently released, and it contains a broken version of ncurses 6.0. Some uses of Python's `curses` module will segfault when compiled with it. The solution is to switch to using the version of ncurses from Homebrew, which is currently 6.4. Support for ncurses 6 was added to Python 3.7 and was backported to 3.6 and 2.7, so this change should not break any recently supported Python versions. Tested with Python 3.12, 3.11, and 2.7, and all tests in the `test.test_curses` module pass without issue. See https://github.com/python/cpython/issues/109617 and https://github.com/python/cpython/issues/69906 for more information. --- plugins/python-build/bin/python-build | 13 ++++ plugins/python-build/test/build.bats | 96 ++++++++++++++++-------- plugins/python-build/test/compiler.bats | 2 +- plugins/python-build/test/pyenv_ext.bats | 2 +- 4 files changed, 78 insertions(+), 35 deletions(-) diff --git a/plugins/python-build/bin/python-build b/plugins/python-build/bin/python-build index 349c8de5..783848dc 100755 --- a/plugins/python-build/bin/python-build +++ b/plugins/python-build/bin/python-build @@ -803,6 +803,7 @@ build_package_standard_build() { use_homebrew || true use_tcltk || true use_homebrew_readline || use_freebsd_pkg || true + use_homebrew_ncurses || true if is_mac -ge 1014; then use_xcode_sdk_zlib || use_homebrew_zlib || true else @@ -1468,6 +1469,18 @@ use_homebrew_readline() { fi } +use_homebrew_ncurses() { + can_use_homebrew || return 1 + local libdir="$(brew --prefix ncurses 2>/dev/null || true)" + if [ -d "$libdir" ]; then + echo "python-build: use ncurses from homebrew" + export CPPFLAGS="-I$libdir/include${CPPFLAGS:+ $CPPFLAGS}" + export LDFLAGS="-L$libdir/lib${LDFLAGS:+ $LDFLAGS}" + else + return 1 + fi +} + prefer_openssl11() { # Allow overriding the preference of OpenSSL version per definition basis (#1302, #1325, #1326) PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA="${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl@1.1 openssl}" diff --git a/plugins/python-build/test/build.bats b/plugins/python-build/test/build.bats index 8a0dee1c..f050e4b5 100644 --- a/plugins/python-build/test/build.bats +++ b/plugins/python-build/test/build.bats @@ -62,7 +62,7 @@ assert_build_log() { cached_tarball "yaml-0.1.6" cached_tarball "Python-3.6.2" - for i in {1..9}; do stub uname '-s : echo Linux'; done + for i in {1..10}; do stub uname '-s : echo Linux'; done stub brew false stub_make_install stub_make_install @@ -89,7 +89,7 @@ OUT cached_tarball "yaml-0.1.6" cached_tarball "Python-3.6.2" - for i in {1..9}; do stub uname '-s : echo Linux'; done + for i in {1..10}; do stub uname '-s : echo Linux'; done stub brew false stub_make_install stub_make_install @@ -119,7 +119,7 @@ OUT cached_tarball "yaml-0.1.6" cached_tarball "Python-3.6.2" - for i in {1..9}; do stub uname '-s : echo Linux'; done + for i in {1..10}; do stub uname '-s : echo Linux'; done stub brew false stub_make_install stub_make_install @@ -151,7 +151,7 @@ OUT BREW_PREFIX="$TMP/homebrew-prefix" mkdir -p "$BREW_PREFIX" - for i in {1..8}; do stub uname '-s : echo Darwin'; done + for i in {1..9}; do stub uname '-s : echo Darwin'; done for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done stub brew "--prefix : echo '$BREW_PREFIX'" false stub_make_install @@ -179,10 +179,10 @@ OUT brew_libdir="$TMP/homebrew-yaml" mkdir -p "$brew_libdir" - for i in {1..9}; do stub uname '-s : echo Darwin'; done + for i in {1..10}; do stub uname '-s : echo Darwin'; done for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done stub brew "--prefix libyaml : echo '$brew_libdir'" - for i in {1..4}; do stub brew false; done + for i in {1..5}; do stub brew false; done stub_make_install install_fixture definitions/needs-yaml @@ -205,7 +205,7 @@ OUT cached_tarball "yaml-0.1.6" cached_tarball "Python-3.6.2" - for i in {1..9}; do stub uname '-s : echo Linux'; done + for i in {1..10}; do stub uname '-s : echo Linux'; done stub brew true; brew stub_make_install stub_make_install @@ -234,11 +234,11 @@ OUT readline_libdir="$TMP/homebrew-readline" mkdir -p "$readline_libdir" - for i in {1..7}; do stub uname '-s : echo Darwin'; done + for i in {1..8}; do stub uname '-s : echo Darwin'; done for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done for i in {1..2}; do stub brew false; done stub brew "--prefix readline : echo '$readline_libdir'" - stub brew false + for i in {1..2}; do stub brew false; done stub_make_install run_inline_definition <>"$tcl_tk_libdir/lib/tclConfig.sh" - for i in {1..9}; do stub uname '-s : echo Darwin'; done + for i in {1..10}; do stub uname '-s : echo Darwin'; done for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done stub brew false for i in {1..2}; do stub brew "--prefix tcl-tk : echo '$tcl_tk_libdir'"; done - for i in {1..2}; do stub brew false; done + for i in {1..3}; do stub brew false; done stub_make_install @@ -452,10 +482,10 @@ OUT tcl_tk_version_long="8.6.10" tcl_tk_version="${tcl_tk_version_long%.*}" - for i in {1..8}; do stub uname '-s : echo Darwin'; done + for i in {1..9}; do stub uname '-s : echo Darwin'; done for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done - for i in {1..4}; do stub brew false; done + for i in {1..5}; do stub brew false; done stub_make_install export PYTHON_CONFIGURE_OPTS="--with-tcltk-libs='-L${TMP}/custom-tcl-tk/lib -ltcl$tcl_tk_version -ltk$tcl_tk_version'" @@ -480,7 +510,7 @@ OUT @test "tcl-tk is linked from Homebrew via pkgconfig only when envvar is set" { cached_tarball "Python-3.6.2" - for i in {1..9}; do stub uname '-s : echo Darwin'; done + for i in {1..10}; do stub uname '-s : echo Darwin'; done for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done tcl_tk_libdir="$TMP/homebrew-tcl-tk" @@ -488,7 +518,7 @@ OUT stub brew false for i in {1..2}; do stub brew "--prefix tcl-tk : echo '${tcl_tk_libdir}'"; done - for i in {1..2}; do stub brew false; done + for i in {1..3}; do stub brew false; done stub_make_install @@ -513,7 +543,7 @@ OUT @test "number of CPU cores defaults to 2" { cached_tarball "Python-3.6.2" - for i in {1..9}; do stub uname '-s : echo Darwin'; done + for i in {1..10}; do stub uname '-s : echo Darwin'; done for i in {1..2}; do stub sw_vers '-productVersion : echo 10.10'; done stub sysctl false @@ -540,7 +570,7 @@ OUT @test "number of CPU cores is detected on Mac" { cached_tarball "Python-3.6.2" - for i in {1..9}; do stub uname '-s : echo Darwin'; done + for i in {1..10}; do stub uname '-s : echo Darwin'; done for i in {1..2}; do stub sw_vers '-productVersion : echo 10.10'; done stub sysctl '-n hw.ncpu : echo 4' @@ -570,7 +600,7 @@ OUT for i in {1..7}; do stub uname '-s : echo FreeBSD'; done stub uname '-r : echo 11.0-RELEASE' - for i in {1..2}; do stub uname '-s : echo FreeBSD'; done + for i in {1..3}; do stub uname '-s : echo FreeBSD'; done for i in {1..3}; do stub pkg false; done stub sysctl '-n hw.ncpu : echo 1' @@ -597,7 +627,7 @@ OUT @test "setting PYTHON_MAKE_INSTALL_OPTS to a multi-word string" { cached_tarball "Python-3.6.2" - for i in {1..8}; do stub uname '-s : echo Linux'; done + for i in {1..9}; do stub uname '-s : echo Linux'; done stub_make_install @@ -621,7 +651,7 @@ OUT @test "(PYTHON_)CONFIGURE_OPTS and (PYTHON_)MAKE_OPTS take priority over automatically added options" { cached_tarball "Python-3.6.2" - for i in {1..8}; do stub uname '-s : echo Linux'; done + for i in {1..9}; do stub uname '-s : echo Linux'; done stub_make_install @@ -649,7 +679,7 @@ OUT @test "--enable-shared is not added if --disable-shared is passed" { cached_tarball "Python-3.6.2" - for i in {1..8}; do stub uname '-s : echo Linux'; done + for i in {1..9}; do stub uname '-s : echo Linux'; done stub_make_install @@ -673,9 +703,9 @@ OUT @test "configuring with dSYM in MacOS" { cached_tarball "Python-3.6.2" - for i in {1..9}; do stub uname '-s : echo Darwin'; done + for i in {1..10}; do stub uname '-s : echo Darwin'; done for i in {1..2}; do stub sw_vers '-productVersion : echo 1010'; done - for i in {1..4}; do stub brew false; done + for i in {1..5}; do stub brew false; done stub_make_install run_inline_definition <> build.log' stub_make_install diff --git a/plugins/python-build/test/compiler.bats b/plugins/python-build/test/compiler.bats index 8f9f3eea..63da5800 100644 --- a/plugins/python-build/test/compiler.bats +++ b/plugins/python-build/test/compiler.bats @@ -69,7 +69,7 @@ DEF mkdir -p "$INSTALL_ROOT" cd "$INSTALL_ROOT" - for i in {1..9}; do stub uname '-s : echo Darwin'; done + for i in {1..10}; do stub uname '-s : echo Darwin'; done for i in {1..3}; do stub sw_vers '-productVersion : echo 10.10'; done stub cc 'false' diff --git a/plugins/python-build/test/pyenv_ext.bats b/plugins/python-build/test/pyenv_ext.bats index 6212638b..a4d45901 100644 --- a/plugins/python-build/test/pyenv_ext.bats +++ b/plugins/python-build/test/pyenv_ext.bats @@ -325,7 +325,7 @@ EOS cached_tarball "Python-3.6.2" for i in {1..4}; do stub brew false; done - for i in {1..7}; do stub uname '-s : echo Linux'; done + for i in {1..8}; do stub uname '-s : echo Linux'; done stub "$MAKE" \ " : echo \"$MAKE \$@\" >> build.log" \ " : echo \"$MAKE \$@\" >> build.log && cat build.log >> '$INSTALL_ROOT/build.log'"