SUMMARY="An interpreted, interactive, object-oriented programming language" DESCRIPTION="Python is a programming language that lets you work more quickly \ and integrate your systems more effectively. You can learn to use Python and \ see almost immediate gains in productivity and lower maintenance costs. Python runs on Windows, Linux/Unix, Mac OS X, and has been ported to the Java \ and .NET virtual machines. Python is free to use, even for commercial products, because of its \ OSI-approved open source license." HOMEPAGE="https://www.python.org" LICENSE="Python" COPYRIGHT="1990-2025 Python Software Foundation" REVISION="1" SOURCE_URI="https://www.python.org/ftp/python/$portVersion/Python-${portVersion}.tar.xz" CHECKSUM_SHA256="fb85a13414b028c49ba18bbd523c2d055a30b56b18b92ce454ea2c51edc656c4" SOURCE_DIR="Python-$portVersion" pyShortVer="${portVersion%.*}" pyVersionCompat="$portVersion compat >= $pyShortVer" PATCHES="python$pyShortVer-$portVersion.patchset" ARCHITECTURES="all !x86_gcc2" SECONDARY_ARCHITECTURES="x86" # On x86_gcc2 we don't want to install the commands in bin//, but in bin/. commandSuffix=$secondaryArchSuffix commandBinDir=$binDir if [ "$targetArchitecture" = x86_gcc2 ]; then commandSuffix= commandBinDir=$prefix/bin fi GLOBAL_WRITABLE_FILES=" non-packaged/lib/python$pyShortVer/site-packages directory keep-old " # [RECIPE OPTIONS]>>> # If this is not intended to be the "default" Python version, set to "false", so "make altinstall" # is used, and only version-suffixed commands are used in PROVIDES. installAsDefaultPython=false # Set to "true" if we should build the "tkinter" module. # Disabled for now, as tkinter deadlocks on Haiku. Try again when tk drops undroidwish for xlibe. enableTkinter=false # Set to "true" to package all the tests into a separate "_tests" package (around 30 MB in size). # Tests are discarded if set to "false". packageTests=false # Set to "false" for faster local/test builds. Around 4 to 5 times faster that way. optimizedBuild=true # Generally, we disable parallel builds if "optimizedBuild == true" as they can fail. forceParallelBuild=false # Run all tests by default. Set to "true" to make "hp --test" only run then known failing tests. runOnlyKnownFailingTests=false # Run only the tests that are generally excluded. Expect LOTS of hangs/crashes/etc. runOnlyExcludedTests=false # <<<[RECIPE OPTIONS] PROVIDES=" python$pyShortVer$secondaryArchSuffix = $pyVersionCompat cmd:2to3_$pyShortVer = $pyVersionCompat cmd:pydoc$pyShortVer = $pyVersionCompat cmd:python$pyShortVer = $pyVersionCompat cmd:python${pyShortVer}_config = $pyVersionCompat devel:libpython$pyShortVer$secondaryArchSuffix = 1.0 lib:libpython$pyShortVer$secondaryArchSuffix = 1.0 " REQUIRES=" haiku$secondaryArchSuffix cmd:file lib:libbz2$secondaryArchSuffix lib:libedit$secondaryArchSuffix lib:libexpat$secondaryArchSuffix lib:libffi$secondaryArchSuffix lib:libintl$secondaryArchSuffix lib:liblzma$secondaryArchSuffix lib:libncursesw$secondaryArchSuffix lib:libsqlite3$secondaryArchSuffix lib:libssl$secondaryArchSuffix lib:libz$secondaryArchSuffix " BUILD_REQUIRES=" haiku${secondaryArchSuffix}_devel devel:libbz2$secondaryArchSuffix devel:libedit$secondaryArchSuffix devel:libexpat$secondaryArchSuffix devel:libffi$secondaryArchSuffix devel:liblzma$secondaryArchSuffix devel:libncursesw$secondaryArchSuffix devel:libsqlite3$secondaryArchSuffix devel:libssl$secondaryArchSuffix devel:libz$secondaryArchSuffix " BUILD_PREREQUIRES=" autoconf_archive cmd:aclocal cmd:autoconf cmd:find cmd:gcc$secondaryArchSuffix cmd:ld$secondaryArchSuffix cmd:libtoolize$secondaryArchSuffix cmd:make cmd:pkg_config$secondaryArchSuffix # cmd:python3 >= 3.10 # needed if PYTHON_FOR_REGEN is invoked for any reason. " if $installAsDefaultPython; then PROVIDES+=" cmd:2to3 = $portVersion compat >= $pyShortVer cmd:python3 = $portVersion compat >= $pyShortVer cmd:pydoc3 = $portVersion compat >= $pyShortVer cmd:python3_config = $portVersion compat >= $pyShortVer " fi if $enableTkinter; then PROVIDES+=" cmd:idle$pyShortVer = $pyVersionCompat " if $installAsDefaultPython; then PROVIDES+=" cmd:idle3 = $portVersion compat >= $pyShortVer " fi BUILD_REQUIRES+=" devel:libtclstub8.6$secondaryArchSuffix devel:libtk8.6$secondaryArchSuffix " fi if $packageTests; then PROVIDES_tests=" python$pyShortVer${secondaryArchSuffix}_tests = $portVersion " REQUIRES_tests=" python$pyShortVer$secondaryArchSuffix == $portVersion base " fi BUILD() { autoreconf -fi # From ./configure: # "compiler flags are generated in two sets, BASECFLAGS and OPT. OPT is just # for debug/optimization stuff. BASECFLAGS is for flags that are required # just to get things to compile and link." # If not provided, the Makefile ends up with: # BASECFLAGS= -fno-strict-overflow -Wsign-compare # OPT= -DNDEBUG -g -O3 -Wall # -NDEBUG gets added by ./configure unless "--with-assertions" is used. export BASECFLAGS="-pipe -D_BSD_SOURCE" export OPT=" -Wall" # Unless cmd:python3 >= 3.10 is available (by being listed on BUILD_PREREQUIRES), we'll # get "python3: command not found" when the build tries to generate some files. # # If attempting to bootstrap, we can try forcing the use of the "./python" built on the # chroot instead: # export PYTHON_FOR_REGEN="LD_PRELOAD=./libpython3.nn.so.1.0 ./python" if $optimizedBuild; then export OPT+=" -O3" maybeEnableOptimizations="--enable-optimizations" else export OPT+=" -O0" maybeEnableOptimizations= fi runConfigure --omit-dirs binDir,includeDir ./configure \ --bindir=$commandBinDir \ --includedir=$developDir/headers \ $maybeEnableOptimizations \ --enable-shared \ --with-ensurepip=no \ --with-readline=editline \ --with-system-expat \ --with-tzpath=$(findpaths -c : B_FIND_PATH_DATA_DIRECTORY zoneinfo) \ --without-static-libpython # --disable-test-modules interferes with the PGO tests. don't use it. # # --with-lto # Issues with enabling this flag: # - Is too CPU intensive (at least 2.5x slower build times). # - 30% final package size increase, unless "-g" is removed from 'LTOFLAGS="$LTOFLAGS -g"' # on "configure.ac". # but resulting Python is about %5 faster, at least on the "pystone.py" syntetic benchmark. # Uncomment when doing repeated builds (for testing different flags/options). # echo "[.recipe] Cleaning before rebuild:" && make clean && rm -f python # NOTE: When using "--enable-optimizations" above, using "make $jobArgs" might be unreliable. # Can see several instances of, for example: # # libgcov profiling error:/sources/Python-3.xx.x/Objects/.gcda:Merge mismatch for function # # Build might end OK (with only some "missing profile" warnings later on), or it can fail # with something like: # # "Parser/parser.c:38718:1: error: corrupted profile info: invalid time profile" # # Not using multiple jobs for make solves both the warnings and the possible error. if $optimizedBuild && ! $forceParallelBuild; then echo "Running make with: -j 1" make -j 1 else echo "Running make with: $jobArgs" make $jobArgs fi } INSTALL() { if $installAsDefaultPython; then make install else # altinstall avoids clobbering $prefix/bin/{idle3,pydoc3,python3,python3-config} make altinstall fi rm $libDir/libpython3.so # No point in having this if we don't have a working tkinter. if ! $enableTkinter; then rm $prefix/bin/idle$pyShortVer if $installAsDefaultPython; then rm -f $prefix/bin/idle3 fi fi if [ "$targetArchitecture" = x86_gcc2 ]; then # On x86_gcc2, move lib-dynload to lib/python3.x/ mv $libDir/python$pyShortVer/lib-dynload $prefix/lib/python$pyShortVer/ fi prepareInstalledDevelLib libpython$pyShortVer fixPkgconfig if [ "$targetArchitecture" = x86_gcc2 ]; then # fix pkgconfig to match configure flags sed -i -e 's,headers/x86,headers,' $developLibDir/pkgconfig/python*.pc fi mkdir -p $prefix/lib/python$pyShortVer/vendor-packages echo 'This directory contains packaged python modules.' \ >$prefix/lib/python$pyShortVer/vendor-packages/README mkdir -p $prefix/non-packaged/lib/python$pyShortVer mv $prefix/lib/python$pyShortVer/site-packages $prefix/non-packaged/lib/python$pyShortVer/ if $packageTests; then packageEntries tests \ $prefix/lib/python$pyShortVer/idlelib/idle_test \ $prefix/lib/python$pyShortVer/test else # drop testsuite altogether cd $prefix/lib/python$pyShortVer rm -rf idlelib/idle_test test fi } # Some of the test will crash, invoking the crash dialog, and will hang waiting for # user's interaction. To avoid that, make sure to configure your system by adding # the following lines in the file "~/config/settings/system/debug_server/settings": ##--- # executable_actions { # /sources/Python-3.*/python kill # } ##--- # For some tests that purposefully crash, it would make sense to add support for # crash-report suppression (as done for other platforms) on "tests/support/__init__,py"'s # SuppressCrashReport class. # But that needs support from Haiku's debug_server, as we can't change settings from # the recipe's building environment at the moment (https://dev.haiku-os.org/ticket/10301) # To see the available test-runs options: # > hp -E python3.nn # > LIBRARY_PATH=%A:/boot/system/lib python -m test --help # or: # > LD_PRELOAD=./libpython3.nn.so.1.0 python -m test --help # # To only execute a particular test (from the $sourceDir): # # > LD_PRELOAD=./libpython3.nn.so.1.0 python -m test test_datetime -W # # Beware that running tests that way can cause some tests to fail, while they work fine under # "hp --test"'s chroot. (test_sysconfig.MakefileTests.test_parse_makefile, for example). # Problem is "os.getcwd()" will return wrong data, causing some file operations to fail. # For reference, results on hrev57937+129 (64 bits VMware): # Total duration: 10 min 30 sec # Total tests: run=35,223 failures=634 skipped=1,009 # Total test files: run=448/435 failed=21 skipped=32 resource_denied=8 rerun=21 # # results on hrev58812 (32 bits bare metal): # Total duration: 4 min 41 sec # Total tests: run=36,581 failures=552 skipped=1,342 # Total test files: run=454/445 failed=17 skipped=32 resource_denied=8 rerun=17 TEST() { # Remove tests data left-overs, if any: # rm -f -r /boot/system/cache/tmp/ # rm -f -d -r build/test_python* make $jobArgs test EXTRATESTOPTS="--cleanup" local test_options=( # --single-process # overrides "-jN", if also given. # Use this to get same test order on different runs (actual value not important). --randseed 7858065 # Print the names of the 10 slowest tests. --slowest # Possibly useful? # --tempdir=/another_drive/tmp # Enable/disable certain tests by "resource" type: # -uall,-audio,-cpu,-curses,-decimal,-gui,-largefile,-network,-subprocess,-urlfetch # make test --help says that "-unone" is the default, but the build is doing this: # "resources: all,-audio,-gui,-largefile" instead. # # Let's be explicit to avoid surprises: -unone,curses,tzdata ) local tests_to_exclude=( # The following tests invoke the crash dialog, and unless your configure # debug_server default action to "kill" or "report", they will hang waiting for # user input. See comment above TEST(). -x test_subprocess # tends to hang. Causes segfaults in several binaries it calls (/bin/true, for example). -x test_threading # tends to hang. Many "IsADirectoryError" when calling "subprocess._execute_child()" # Many of the tests hang/stall. We have two options: # # 1- Manually remove the problematic test-cases. # 2- Set a TIMEOUT (eg: --timeout=300). # # Option 1: Works, but requires manual identification/mainteinance. # # Option 2: Doesn't requires maintaining a list of stalling tests, but: # at the end of the test run it causes: # - "unmounting failed: Device/File/Resource Busy" errors, as there are # dangling threads running when the tests timeout (requiring `killall python`) # - The time it takes to run the full suite largely increases. # # Let's use Option 1, for now at least. # These hang reliably. -x test_cmd_line # "IsADirectoryError" when calling "subprocess._execute_child()" -x test_concurrent_futures # resource_tracker: process died unexpectedly -x test_interpreters # segfaults when calling: finddir B_USER_NONPACKAGED_DIRECTORY # -x test_multiprocessing_main_handling # "IsADirectoryError" when calling "subprocess._execute_child()" -x test_multiprocessing_spawn -x test_os # Causes segfaults in several binaries it calls. -x test_posix # "Invalid Argument: '@test_94495_tmpæ'" in can_chmod # -x test_socketserver # skipped unless "network" resource is enabled. -x test_threaded_import # RECHECK. test_importlib/test_threaded_import # -x test_tracemalloc # # "IsADirectoryError" when calling "subprocess._execute_child()" -x test_uuid # Causes segfaults in several binaries it calls (ifconfig/netstat). # "test_asyncio" doesn't seems to runs reliably, even after individually skipping # all the problematic test-cases that could be identify by running them one by one. # -x test_asyncio # The following are all under test_asyncio/ -x test_base_events -x test_buffered_proto # Exception on Exception handler. -x test_events -x test_sendfile -x test_server # Exception on Exception handler. -x test_sock_lowlevel -x test_sslproto # Exception on Exception handler. -x test_streams -x test_unix_events # -i TestThreadedServer # in test_asyncio.functional # These not always hang/stall, but they do it enough to warrant skipping for now. -x test_multiprocessing_fork # resource_tracker: process died unexpectedly -x test_multiprocessing_forkserver -x test_imaplib # OK on hrev58812 32 bits, hangs on beta5 64 bits. -x test_signal -x test_socket # OK on hrev58812 32 bits, hangs on beta5 64 bits. -x test_ssl -x test_urllib2_localnet # OK on hrev58812 32 bits, hangs on beta5 64 bits. # 3.11 # -x test_urllib2net # skipped if "network" resource is not enabled. # -x test_venv # recheck # 3.12 Either too slow or hangs; # -x test_builtin # failures related to "Invalid Argument: '@test_95635_tmpæ'" in write_testfile and "IsADirectoryError" when calling "subprocess._execute_child()" # -x test_mailbox # -x test_tempfile # -x test_thread # OK on 32 bits. # 3.12.1 # -x test_queue # OK on 32 bits. # 3.11.8 / 3.12.2 (hang on nightlies, at least) -x test_httplib # "Invalid Argument: '@test_97280_tmpæ'" in open(os_helper.TESTFN, "wb") -x test_logging -x test_pydoc # "Invalid Argument: '@test_97476_tmpæ'" in open(TESTFN, "wb") # Fails while outputing "ResourceWarning: unclosed