Files
haikuports/dev-lang/python/patches/python3.12-3.12.9.patchset

1169 lines
41 KiB
Plaintext

From ced60ec5539b7f2c9da08140ab83bcabc8acee1c Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Sun, 8 Oct 2023 01:02:25 -0300
Subject: initial Haiku patch
Based on the patch from Jerome Duval, modified to make it apply cleanly
over 3.12's sources.
Parts of that original patch were split into specific commit/patches.
diff --git a/Include/pyport.h b/Include/pyport.h
index e2bac3b..0d8b825 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -691,7 +691,7 @@ extern char * _getpty(int *, int, mode_t, int);
# define _Py_FORCE_UTF8_LOCALE
#endif
-#if defined(_Py_FORCE_UTF8_LOCALE) || defined(__APPLE__)
+#if defined(_Py_FORCE_UTF8_LOCALE) || defined(__APPLE__) || defined(__HAIKU__)
// Use UTF-8 as the filesystem encoding.
// See PyUnicode_DecodeFSDefaultAndSize(), PyUnicode_EncodeFSDefault(),
// Py_DecodeLocale() and Py_EncodeLocale().
diff --git a/Lib/plat-haiku1/regen b/Lib/plat-haiku1/regen
new file mode 100644
index 0000000..4372ee2
--- /dev/null
+++ b/Lib/plat-haiku1/regen
@@ -0,0 +1,4 @@
+#! /bin/sh
+HEADERS=/boot/develop/headers
+set -v
+eval $PYTHON_FOR_BUILD ../../Tools/scripts/h2py.py -i "'(u_long)'" $HEADERS/posix/netinet/in.h
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 689f33d..fb2195b 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -147,7 +147,7 @@ BINDIR= @bindir@
LIBDIR= @libdir@
MANDIR= @mandir@
INCLUDEDIR= @includedir@
-CONFINCLUDEDIR= $(exec_prefix)/include
+CONFINCLUDEDIR= $(INCLUDEDIR)
PLATLIBDIR= @PLATLIBDIR@
SCRIPTDIR= $(prefix)/$(PLATLIBDIR)
ABIFLAGS= @ABIFLAGS@
diff --git a/Modules/resource.c b/Modules/resource.c
index 3c89468..3ea22bf 100644
--- a/Modules/resource.c
+++ b/Modules/resource.c
@@ -124,6 +124,7 @@ resource_getrusage_impl(PyObject *module, int who)
PyFloat_FromDouble(doubletime(ru.ru_utime)));
PyStructSequence_SET_ITEM(result, 1,
PyFloat_FromDouble(doubletime(ru.ru_stime)));
+#ifndef __HAIKU__
PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(ru.ru_maxrss));
PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(ru.ru_ixrss));
PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(ru.ru_idrss));
@@ -138,7 +139,22 @@ resource_getrusage_impl(PyObject *module, int who)
PyStructSequence_SET_ITEM(result, 13, PyLong_FromLong(ru.ru_nsignals));
PyStructSequence_SET_ITEM(result, 14, PyLong_FromLong(ru.ru_nvcsw));
PyStructSequence_SET_ITEM(result, 15, PyLong_FromLong(ru.ru_nivcsw));
-
+#else
+ PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 7, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 8, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 9, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 10, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 11, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 12, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 13, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 14, PyLong_FromLong(0));
+ PyStructSequence_SET_ITEM(result, 15, PyLong_FromLong(0));
+#endif
if (PyErr_Occurred()) {
Py_DECREF(result);
return NULL;
@@ -387,19 +403,19 @@ resource_exec(PyObject *module)
}
/* insert constants */
-#ifdef RLIMIT_CPU
+#if !defined(__HAIKU__) && defined(RLIMIT_CPU)
ADD_INT(module, RLIMIT_CPU);
#endif
-#ifdef RLIMIT_FSIZE
+#if !defined(__HAIKU__) && defined(RLIMIT_FSIZE)
ADD_INT(module, RLIMIT_FSIZE);
#endif
-#ifdef RLIMIT_DATA
+#if !defined(__HAIKU__) && defined(RLIMIT_DATA)
ADD_INT(module, RLIMIT_DATA);
#endif
-#ifdef RLIMIT_STACK
+#if !defined(__HAIKU__) && defined(RLIMIT_STACK)
ADD_INT(module, RLIMIT_STACK);
#endif
@@ -411,31 +427,31 @@ resource_exec(PyObject *module)
ADD_INT(module, RLIMIT_NOFILE);
#endif
-#ifdef RLIMIT_OFILE
+#if !defined(__HAIKU__) && defined(RLIMIT_OFILE)
ADD_INT(module, RLIMIT_OFILE);
#endif
-#ifdef RLIMIT_VMEM
+#if !defined(__HAIKU__) && defined(RLIMIT_VMEM)
ADD_INT(module, RLIMIT_VMEM);
#endif
-#ifdef RLIMIT_AS
+#if !defined(__HAIKU__) && defined(RLIMIT_AS)
ADD_INT(module, RLIMIT_AS);
#endif
-#ifdef RLIMIT_RSS
+#if !defined(__HAIKU__) && defined(RLIMIT_RSS)
ADD_INT(module, RLIMIT_RSS);
#endif
-#ifdef RLIMIT_NPROC
+#if !defined(__HAIKU__) && defined(RLIMIT_NPROC)
ADD_INT(module, RLIMIT_NPROC);
#endif
-#ifdef RLIMIT_MEMLOCK
+#if !defined(__HAIKU__) && defined(RLIMIT_MEMLOCK)
ADD_INT(module, RLIMIT_MEMLOCK);
#endif
-#ifdef RLIMIT_SBSIZE
+#if !defined(__HAIKU__) && defined(RLIMIT_SBSIZE)
ADD_INT(module, RLIMIT_SBSIZE);
#endif
diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h
index f5ca004..1ed1819 100644
--- a/Modules/socketmodule.h
+++ b/Modules/socketmodule.h
@@ -111,6 +111,10 @@ typedef int socklen_t;
# undef AF_QIPCRTR
#endif
+#if defined(__HAIKU__)
+#undef HAVE_BLUETOOTH_BLUETOOTH_H
+#endif
+
#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c
index 13f1115..45f477c 100644
--- a/Modules/spwdmodule.c
+++ b/Modules/spwdmodule.c
@@ -9,6 +9,7 @@
#ifdef HAVE_SHADOW_H
#include <shadow.h>
#endif
+#include <errno.h>
#include "clinic/spwdmodule.c.h"
@@ -148,7 +149,12 @@ spwd_getspnam_impl(PyObject *module, PyObject *arg)
if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)
goto out;
if ((p = getspnam(name)) == NULL) {
+// Haiku sets ENOENT if invalid user is specified. Ignore it to make KeyError is set.
+#ifdef __HAIKU__
+ if (errno != 0 && errno != ENOENT)
+#else
if (errno != 0)
+#endif
PyErr_SetFromErrno(PyExc_OSError);
else
PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
diff --git a/configure.ac b/configure.ac
index 1a02d19..63a3bd3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1527,6 +1527,16 @@ if test $enable_shared = "yes"; then
PY3LIBRARY=libpython3.so
fi
;;
+ Haiku*)
+ LDLIBRARY='libpython$(LDVERSION).so'
+ BLDLIBRARY='-L. -lpython$(LDVERSION)'
+ RUNSHARED=LIBRARY_PATH=`pwd`${LIBRARY_PATH:+:${LIBRARY_PATH}}
+ INSTSONAME="$LDLIBRARY".$SOVERSION
+ if test "$with_pydebug" != yes
+ then
+ PY3LIBRARY=libpython3.so
+ fi
+ ;;
hp*|HP*)
case `uname -m` in
ia64)
@@ -1672,6 +1682,7 @@ AC_PROG_MKDIR_P
AC_SUBST([LN])
if test -z "$LN" ; then
case $ac_sys_system in
+ Haiku*) LN="ln -s";;
CYGWIN*) LN="ln -s";;
*) LN=ln;;
esac
@@ -3465,7 +3476,7 @@ then
else CCSHARED="+z";
fi;;
Linux-android*) ;;
- Linux*|GNU*) CCSHARED="-fPIC";;
+ Linux*|GNU*|Haiku*) CCSHARED="-fPIC";;
Emscripten*|WASI*)
AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [
CCSHARED="-fPIC"
@@ -3498,7 +3509,7 @@ then
LINKFORSHARED="-Wl,-E -Wl,+s";;
# LINKFORSHARED="-Wl,-E -Wl,+s -Wl,+b\$(BINLIBDEST)/lib-dynload";;
Linux-android*) LINKFORSHARED="-pie -Xlinker -export-dynamic";;
- Linux*|GNU*) LINKFORSHARED="-Xlinker -export-dynamic";;
+ Linux*|GNU*|Haiku*) LINKFORSHARED="-Xlinker -export-dynamic";;
# -u libsys_s pulls in all symbols in libsys
Darwin/*)
LINKFORSHARED="$extra_undefs -framework CoreFoundation"
@@ -5648,6 +5659,7 @@ AC_CHECK_FUNC([__fpu_control],
AC_SUBST([LIBM])
case $ac_sys_system in
Darwin) ;;
+Haiku) ;;
*) LIBM=-lm
esac
AC_MSG_CHECKING([for --with-libm=STRING])
--
2.45.2
From 5a4db8cc635464695177f95df45557fb08c8b8fe Mon Sep 17 00:00:00 2001
From: Jerome Duval <jerome.duval@gmail.com>
Date: Sun, 16 Apr 2017 10:05:42 +0200
Subject: fix for negative errnos
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 3ec39ca..6ae03cd 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -1948,6 +1948,8 @@ class Popen:
SubprocessError)
if issubclass(child_exception_type, OSError) and hex_errno:
errno_num = int(hex_errno, 16)
+ if sys.platform.startswith('haiku'):
+ errno_num = -errno_num;
if err_msg == "noexec:chdir":
err_msg = ""
# The error must be from chdir(cwd).
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index 35ea2ac..ccc25ed 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -756,6 +756,10 @@ error:
char *cur;
_Py_write_noraise(errpipe_write, "OSError:", 8);
cur = hex_errno + sizeof(hex_errno);
+#ifdef __HAIKU__
+ if (saved_errno < 0)
+ saved_errno = -saved_errno;
+#endif
while (saved_errno != 0 && cur != hex_errno) {
*--cur = Py_hexdigits[saved_errno % 16];
saved_errno /= 16;
--
2.45.2
From 110187fb1fa288006bd2f83a9bf55796fc582038 Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Sun, 8 Oct 2023 20:06:31 -0300
Subject: Implement CTypes's find_library for Haiku
This combines:
- the original patch by Philippe Houdoin <philippe.houdoin@gmail.com>
- A slight variation of Adrien Destugues' fix for x86_gcc2.
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index c550883..6b23423 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -1,4 +1,5 @@
import os
+import platform
import shutil
import subprocess
import sys
@@ -268,6 +269,60 @@ elif os.name == "posix":
def find_library(name, is64 = False):
return _get_soname(_findLib_crle(name, is64) or _findLib_gcc(name))
+ elif sys.platform.startswith("haiku"):
+
+ def _num_version(libname):
+ # "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ]
+ parts = libname.split('.')
+ nums = []
+ try:
+ while parts:
+ nums.insert(0, int(parts.pop()))
+ except ValueError:
+ pass
+ return nums or [sys.maxint]
+
+ def find_library(name):
+ if name in ('c', 'm'):
+ return find_library('root')
+ for directory in os.environ['LIBRARY_PATH'].split(os.pathsep):
+ if directory.startswith("%A/"):
+ directory = directory.replace('%A',
+ os.path.dirname(os.path.abspath(sys.argv[0] or os.getcwd())))
+
+ # Are we on x86 32 bits?:
+ if platform.machine() == 'BePC':
+ directory = os.path.join(directory, "x86")
+
+ if not os.path.isdir(directory):
+ continue
+
+ # try direct match
+ fname = os.path.join(directory, name)
+ if os.path.isfile(fname):
+ return fname
+
+ fname = os.path.join(directory, 'lib%s.so' % name)
+ if os.path.isfile(fname):
+ return fname
+
+ # no exact matching in this directroy
+ # collect versioned candidates, if any
+ candidates = []
+ pattern = re.compile(r'lib%s\.so\.\S+' % re.escape(name))
+ for entry in os.listdir(directory):
+ if not os.path.isfile(os.path.join(directory, entry)):
+ continue
+
+ if re.match(pattern, entry):
+ candidates.append(os.path.join(directory, entry))
+
+ if candidates:
+ # return latest version found
+ candidates.sort(key=_num_version)
+ return candidates[-1]
+
+ return None
else:
def _findSoname_ldconfig(name):
@@ -370,6 +425,12 @@ def test():
print(f"crypt\t:: {cdll.LoadLibrary(find_library('crypt'))}")
print(f"crypto\t:: {find_library('crypto')}")
print(f"crypto\t:: {cdll.LoadLibrary(find_library('crypto'))}")
+ elif sys.platform.startswith("haiku"):
+ print(find_library("libbz2.so.1.0"))
+ print(find_library("tracker"))
+ print(find_library("media"))
+ print(cdll.LoadLibrary(find_library("tracker")))
+ print(cdll.LoadLibrary("libmedia.so"))
else:
print(cdll.LoadLibrary("libm.so"))
print(cdll.LoadLibrary("libcrypt.so"))
--
2.45.2
From 3451f6920a611b5af13fefed644b05b708a82a0e Mon Sep 17 00:00:00 2001
From: Philipp Wolfer <phil@parolu.io>
Date: Mon, 23 Sep 2019 09:14:58 +0200
Subject: webbrowser: Support for default browsers on Haiku
diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py
index 13b9e85..7d81178 100755
--- a/Lib/webbrowser.py
+++ b/Lib/webbrowser.py
@@ -480,6 +480,12 @@ def register_standard_browsers():
# SerenityOS webbrowser, simply called "Browser".
register("Browser", None, BackgroundBrowser("Browser"))
+ if sys.platform[:5] == "haiku":
+ # First try to use the default configured browser
+ register("haiku-default", None, GenericBrowser("open"))
+ # Fall back to WebPositive as the standard browser of Haiku
+ register("webpositive", None, BackgroundBrowser("WebPositive"))
+
if sys.platform[:3] == "win":
# First try to use the default Windows browser
register("windows-default", WindowsDefault)
--
2.45.2
From c8f5fd71384b15cd2a88c824de4b8a809c349a28 Mon Sep 17 00:00:00 2001
From: Jerome Duval <jerome.duval@gmail.com>
Date: Fri, 4 Oct 2019 22:02:35 +0200
Subject: since 3.8, don't reinit locks on fork.
diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
index 22d3198..f369a88 100644
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -250,7 +250,7 @@ def _releaseLock():
# Prevent a held logging lock from blocking a child from logging.
-if not hasattr(os, 'register_at_fork'): # Windows and friends.
+if sys.platform.startswith('haiku') or not hasattr(os, 'register_at_fork'): # Windows and friends.
def _register_at_fork_reinit_lock(instance):
pass # no-op when os.register_at_fork does not exist.
else:
--
2.45.2
From f47a1e3fd1963f75b48439573d0860a35bc8e80b Mon Sep 17 00:00:00 2001
From: Jerome Duval <jerome.duval@gmail.com>
Date: Fri, 15 May 2020 15:20:57 +0200
Subject: handle errors returned by internal_connect()
upstream bug #40628 by Ryan C. Gordon
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 7f2ebba..47e56d1 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -3492,7 +3492,7 @@ sock_connect(PySocketSockObject *s, PyObject *addro)
}
res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 1);
- if (res < 0)
+ if (res == -1)
return NULL;
Py_RETURN_NONE;
@@ -3523,7 +3523,7 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro)
}
res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 0);
- if (res < 0)
+ if (res == -1)
return NULL;
return PyLong_FromLong((long) res);
--
2.45.2
From b122dd23f732a49fa4fa1c5d1d088693933f1a97 Mon Sep 17 00:00:00 2001
From: Jerome Duval <jerome.duval@gmail.com>
Date: Mon, 19 Oct 2020 18:03:09 +0200
Subject: ttyname_r can use MAXPATHLEN
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index c21c6f0..51421e1 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -3253,11 +3253,14 @@ static PyObject *
os_ttyname_impl(PyObject *module, int fd)
/*[clinic end generated code: output=c424d2e9d1cd636a input=9ff5a58b08115c55]*/
{
-
+#ifndef __HAIKU__
long size = sysconf(_SC_TTY_NAME_MAX);
if (size == -1) {
return posix_error();
}
+#else
+ long size = MAXPATHLEN;
+#endif
char *buffer = (char *)PyMem_RawMalloc(size);
if (buffer == NULL) {
return PyErr_NoMemory();
--
2.45.2
From 2ea7ad4feb7d3a2bb940b102cf1bb457e6859a2d Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Mon, 24 Oct 2022 20:04:10 -0300
Subject: Lib/test: require the "largefile" usage flag for I/O heavy tests.
The same is done for Windows and macOS already.
This avoids needing several GBs of storage to run the tests
(unless the "largefile" resource usage flag is enabled).
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index d85040a..4e3d67c 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -634,7 +634,7 @@ class IOTest(unittest.TestCase):
# On Windows and Mac OSX this test consumes large resources; It takes
# a long time to build the >2 GiB file and takes >2 GiB of disk space
# therefore the resource must be enabled to run this test.
- if sys.platform[:3] == 'win' or sys.platform == 'darwin':
+ if sys.platform[:3] == 'win' or sys.platform == 'darwin' or sys.platform[:5] == 'haiku':
support.requires(
'largefile',
'test requires %s bytes and a long time to run' % self.LARGE)
diff --git a/Lib/test/test_largefile.py b/Lib/test/test_largefile.py
index 282400c..6448a8d 100644
--- a/Lib/test/test_largefile.py
+++ b/Lib/test/test_largefile.py
@@ -274,7 +274,7 @@ def setUpModule():
# takes a long time to build the >2 GiB file and takes >2 GiB of disk
# space therefore the resource must be enabled to run this test.
# If not, nothing after this line stanza will be executed.
- if sys.platform[:3] == 'win' or sys.platform == 'darwin':
+ if sys.platform[:3] == 'win' or sys.platform == 'darwin' or sys.platform[:5] == 'haiku':
requires('largefile',
'test requires %s bytes and a long time to run' % str(size))
else:
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index 1867e8c..e4fab02 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -1009,7 +1009,7 @@ class LargeMmapTests(unittest.TestCase):
unlink(TESTFN)
def _make_test_file(self, num_zeroes, tail):
- if sys.platform[:3] == 'win' or sys.platform == 'darwin':
+ if sys.platform[:3] == 'win' or sys.platform == 'darwin' or sys.platform[:5] == 'haiku':
requires('largefile',
'test requires %s bytes and a long time to run' % str(0x180000000))
f = open(TESTFN, 'w+b')
--
2.45.2
From d2240d3f6402cc0982184a306780c8345de084cb Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Fri, 26 Jul 2024 19:18:56 -0300
Subject: _getuserbase(), getsitepackages(), and INSTALL_SCHEMES for Haiku.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This combines (at least parts of) previous "commits" on older ".patchset"s:
* Initial Haiku patch.
* default schemes for Haiku
from Jérôme Duval
* syncronize both _getuserbase() copies on site.py and sysconfig.py.
* Add missing 'platinclude' to sysconfig's _INSTALL_SCHEMES.
* Adjust test_sysconfig.test_get_scheme_names for Haiku.
by me, plus:
* new changes to allow Python to find modules installed via 'pkgman -H'.
* Attempt to support the "venv" install scheme (untested).
The idea was to have all _getuserbase()/INSTALL_SCHEMES related changes in "one place".
diff --git a/Lib/site.py b/Lib/site.py
index aed254a..d3612a0 100644
--- a/Lib/site.py
+++ b/Lib/site.py
@@ -302,6 +302,14 @@ def _getuserbase():
return joinuser("~", "Library", sys._framework,
"%d.%d" % sys.version_info[:2])
+ if sys.platform.startswith('haiku'):
+ try:
+ import subprocess
+ return subprocess.check_output(
+ ['finddir', 'B_USER_NONPACKAGED_DIRECTORY']).rstrip().decode('utf-8')
+ except:
+ pass
+
return joinuser("~", ".local")
@@ -382,7 +390,31 @@ def getsitepackages(prefixes=None):
continue
seen.add(prefix)
- if os.sep == '/':
+ if sys.platform.startswith('haiku'):
+ # Locations under /system/
+ sitepackages.append(os.path.join(prefix, "non-packaged", "lib",
+ "python%d.%d" % sys.version_info[:2],
+ "site-packages"))
+ sitepackages.append(os.path.join(prefix, "lib",
+ "python%d.%d" % sys.version_info[:2],
+ "vendor-packages"))
+
+ # For .hpkg installed under ~/config/ (pkgman install -H)
+ # ("pip install --user" uses ~/config/non-packaged/, and gets
+ # handled by the "haiku_user" install scheme.
+ try:
+ import subprocess
+ _home_prefix = subprocess.check_output(
+ ['finddir', 'B_USER_CONFIG_DIRECTORY']).rstrip().decode('utf-8')
+ except:
+ # print("'finddir B_USER_CONFIG_DIRECTORY' failed.")
+ _home_prefix = None
+
+ if _home_prefix is not None:
+ sitepackages.append(os.path.join(_home_prefix, "lib",
+ "python%d.%d" % sys.version_info[:2],
+ "vendor-packages"))
+ elif os.sep == '/':
libdirs = [sys.platlibdir]
if sys.platlibdir != "lib":
libdirs.append("lib")
diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
index 7dd63b9..e608b5e 100644
--- a/Lib/sysconfig.py
+++ b/Lib/sysconfig.py
@@ -47,6 +47,36 @@ _INSTALL_SCHEMES = {
'scripts': '{base}/bin',
'data': '{base}',
},
+ 'haiku': {
+ 'stdlib': '{installed_base}/lib/python{py_version_short}',
+ 'platstdlib': '{platbase}/lib/python{py_version_short}',
+ 'purelib': '{base}/non-packaged/lib/python{py_version_short}/site-packages',
+ 'platlib': '{platbase}/non-packaged/lib/python{py_version_short}/site-packages',
+ 'include': '{installed_base}/non-packaged/develop/headers/python{py_version_short}',
+ 'platinclude': '{installed_platbase}/develop/headers/python{py_version_short}',
+ 'scripts': '{base}/non-packaged/bin',
+ 'data' : '{base}/non-packaged',
+ },
+ 'haiku_vendor': {
+ 'stdlib': '{installed_base}/lib/python{py_version_short}',
+ 'platstdlib': '{platbase}/lib/python{py_version_short}',
+ 'purelib': '{base}/lib/python{py_version_short}/vendor-packages',
+ 'platlib': '{platbase}/lib/python{py_version_short}/vendor-packages',
+ 'include': '{installed_base}/develop/headers/python{py_version_short}',
+ 'platinclude': '{installed_platbase}/develop/headers/python{py_version_short}',
+ 'scripts': '{base}/bin',
+ 'data' : '{base}',
+ },
+ 'haiku_home': {
+ 'stdlib': '{installed_base}/lib/python{py_version_short}',
+ 'platstdlib': '{base}/lib/python{py_version_short}',
+ 'purelib': '{base}/lib/python{py_version_short}',
+ 'platlib': '{base}/lib/python{py_version_short}',
+ 'include': '{installed_base}/develop/headers/python{py_version_short}',
+ 'platinclude': '{installed_base}/develop/headers/python{py_version_short}',
+ 'scripts': '{base}/bin',
+ 'data': '{base}',
+ },
'nt': {
'stdlib': '{installed_base}/Lib',
'platstdlib': '{base}/Lib',
@@ -86,6 +116,16 @@ _INSTALL_SCHEMES = {
'scripts': '{base}/bin',
'data': '{base}',
},
+ 'haiku_venv': {
+ 'stdlib': '{installed_base}/lib/python{py_version_short}',
+ 'platstdlib': '{platbase}/lib/python{py_version_short}',
+ 'purelib': '{base}/non-packaged/lib/python{py_version_short}/site-packages',
+ 'platlib': '{platbase}/non-packaged/lib/python{py_version_short}/site-packages',
+ 'include': '{installed_base}/non-packaged/develop/headers/python{py_version_short}',
+ 'platinclude': '{installed_platbase}/develop/headers/python{py_version_short}',
+ 'scripts': '{base}/non-packaged/bin',
+ 'data' : '{base}/non-packaged',
+ },
'nt_venv': {
'stdlib': '{installed_base}/Lib',
'platstdlib': '{base}/Lib',
@@ -101,6 +141,8 @@ _INSTALL_SCHEMES = {
# For the OS-native venv scheme, we essentially provide an alias:
if os.name == 'nt':
_INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['nt_venv']
+elif sys.platform.startswith('haiku'):
+ _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['haiku_venv']
else:
_INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv']
@@ -127,6 +169,14 @@ def _getuserbase():
return joinuser("~", "Library", sys._framework,
f"{sys.version_info[0]}.{sys.version_info[1]}")
+ if sys.platform.startswith('haiku'):
+ try:
+ import subprocess
+ return subprocess.check_output(
+ ['finddir', 'B_USER_NONPACKAGED_DIRECTORY']).rstrip().decode('utf-8')
+ except:
+ pass
+
return joinuser("~", ".local")
_HAS_USER_BASE = (_getuserbase() is not None)
@@ -152,6 +202,15 @@ if _HAS_USER_BASE:
'scripts': '{userbase}/bin',
'data': '{userbase}',
},
+ 'haiku_user': {
+ 'stdlib': '{userbase}/lib/python{py_version_short}',
+ 'platstdlib': '{userbase}/lib/python{py_version_short}',
+ 'purelib': '{userbase}/lib/python{py_version_short}/site-packages',
+ 'platlib': '{userbase}/lib/python{py_version_short}/site-packages',
+ 'include': '{userbase}/develop/headers/python{py_version_short}',
+ 'scripts': '{userbase}/bin',
+ 'data': '{userbase}',
+ },
'osx_framework_user': {
'stdlib': '{userbase}/lib/python',
'platstdlib': '{userbase}/lib/python',
@@ -280,6 +339,18 @@ def _expand_vars(scheme, vars):
def _get_preferred_schemes():
+ if sys.platform.startswith('haiku'):
+ if os.environ.get('HAIKU_USE_VENDOR_DIRECTORIES') == '1':
+ return {
+ 'prefix': 'haiku_vendor',
+ 'home': 'haiku_home',
+ 'user': 'haiku_user',
+ }
+ return {
+ 'prefix': 'haiku',
+ 'home': 'haiku_home',
+ 'user': 'haiku_user',
+ }
if os.name == 'nt':
return {
'prefix': 'nt',
diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py
index 3468d0c..35bea57 100644
--- a/Lib/test/test_sysconfig.py
+++ b/Lib/test/test_sysconfig.py
@@ -353,9 +353,10 @@ class TestSysConfig(unittest.TestCase):
self.assertTrue(os.path.isfile(config_h), config_h)
def test_get_scheme_names(self):
- wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv']
+ wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv', 'haiku',
+ 'haiku_home', 'haiku_vendor']
if HAS_USER_BASE:
- wanted.extend(['nt_user', 'osx_framework_user', 'posix_user'])
+ wanted.extend(['nt_user', 'osx_framework_user', 'posix_user', 'haiku_user'])
self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))
@skip_unless_symlink
--
2.45.2
From 5e9a20c305c91090979f5d1bfe5a0717e163ca75 Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Fri, 26 Jul 2024 19:01:05 -0300
Subject: Fix location of REPL's history file.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From "initial Haiku patch" by Jérôme Duval.
diff --git a/Lib/site.py b/Lib/site.py
index d3612a0..3a714a0 100644
--- a/Lib/site.py
+++ b/Lib/site.py
@@ -519,8 +519,16 @@ def enablerlcompleter():
# each interpreter exit when readline was already configured
# through a PYTHONSTARTUP hook, see:
# http://bugs.python.org/issue5845#msg198636
- history = os.path.join(os.path.expanduser('~'),
- '.python_history')
+ import subprocess
+ try:
+ history = os.path.join(subprocess.check_output(
+ ['finddir', 'B_USER_VAR_DIRECTORY']).rstrip().decode('utf-8'),
+ 'python', 'history')
+ if not os.path.exists(os.path.dirname(history)):
+ os.makedirs(os.path.dirname(history))
+ except subprocess.CalledProcessError:
+ history = os.path.join(os.path.expanduser('~'),
+ '.python_history')
try:
readline.read_history_file(history)
except OSError:
--
2.45.2
From 2ab0f0054255bf3b7060184e4cecba14ac6448d3 Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Sun, 8 Oct 2023 17:02:19 -0300
Subject: Use spawn instead of fork for multiprocessing.
Without this change, we get:
```
Fatal Python error: PyOS_AfterFork_Child:
the function must be called with the GIL held, after Python initialization
and before Python finalization, but the GIL is released (the current Python
thread state is NULL)
```
when running "test_re.py" (as part of the "--with-optimizations" build) without
using spawn instead of fork in multiprocessing/context.py.
and also:
```
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/sources/Python-3.12.0/Lib/multiprocessing/forkserver.py", line 202, in main
signal.set_wakeup_fd(sig_w)
ValueError: the fd 6 must be in non-blocking mode
```
when running the "compileall" step of "make install".
From:
https://docs.python.org/3.12/library/multiprocessing.html#contexts-and-start-methods
"The default start method will change away from fork in Python 3.14."
So, we might be in the clear switching to "spawn" now.
diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py
index de8a264..02a301e 100644
--- a/Lib/multiprocessing/context.py
+++ b/Lib/multiprocessing/context.py
@@ -320,7 +320,7 @@ if sys.platform != 'win32':
'spawn': SpawnContext(),
'forkserver': ForkServerContext(),
}
- if sys.platform == 'darwin':
+ if sys.platform == 'darwin' or sys.platform[:5] == 'haiku':
# bpo-33725: running arbitrary code after fork() is no longer reliable
# on macOS since macOS 10.14 (Mojave). Use spawn by default instead.
_default_context = DefaultContext(_concrete_contexts['spawn'])
--
2.45.2
From 206c6c3cc6371c5f526ea29e5fdccfdb7ef282c8 Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Sun, 10 Dec 2023 19:50:22 -0300
Subject: Miscellaneous "Lib/test/" fixes for Haiku.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
test_fileio.py fix from "initial Haiku patch" by Jérôme Duval.
diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py
index 903a43a..287624f 100644
--- a/Lib/test/datetimetester.py
+++ b/Lib/test/datetimetester.py
@@ -5973,6 +5973,9 @@ def pairs(iterable):
class ZoneInfo(tzinfo):
zoneroot = '/usr/share/zoneinfo'
+ if sys.platform.startswith('haiku'):
+ zoneroot = '/system/data/zoneinfo'
+
def __init__(self, ut, ti):
"""
diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py
index ebfcffd..0517b87 100644
--- a/Lib/test/test_fileio.py
+++ b/Lib/test/test_fileio.py
@@ -391,6 +391,7 @@ class OtherFileTests:
self.assertEqual(f.writable(), True)
if sys.platform != "darwin" and \
'bsd' not in sys.platform and \
+ 'haiku' not in sys.platform and \
not sys.platform.startswith(('sunos', 'aix')):
# Somehow /dev/tty appears seekable on some BSDs
self.assertEqual(f.seekable(), False)
--
2.45.2
From d16a22d00038e54c32a4358a7febfca32ba93528 Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Sat, 10 Feb 2024 06:01:25 -0300
Subject: Fix build on nightlies, following the addition of kqueue.
See HaikuPorts issue #10001.
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 50788e5..82fd9d9 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -2722,13 +2722,20 @@ _select_exec(PyObject *m)
#ifdef EVFILT_SIGNAL
PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
#endif
+#ifdef EVFILT_TIMER
PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
-
+#endif
/* event flags */
PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
+#ifdef EV_ENABLE
PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
+#else
+ PyModule_AddIntConstant(m, "KQ_EV_ENABLE", 0); // "test_kqueue.py" assumes KQ_EV_ENABLE exists
+#endif
+#ifdef EV_DISABLE
PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
+#endif
PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
@@ -2761,14 +2768,28 @@ _select_exec(PyObject *m)
/* PROC filter flags */
#ifdef EVFILT_PROC
PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
+#ifdef NOTE_FORK
PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
+#endif
+#ifdef NOTE_EXEC
PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
+#endif
+#ifdef NOTE_PCTRLMASK
PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
+#endif
+#ifdef NOTE_PDATAMASK
PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
+#endif
+#ifdef NOTE_TRACK
PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
+#endif
+#ifdef NOTE_CHILD
PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
+#endif
+#ifdef NOTE_TRACKERR
PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
+#endif
#endif
/* NETDEV filter flags */
--
2.45.2
From e188d6f612aa90014e3eb4dc2591797b694f3775 Mon Sep 17 00:00:00 2001
From: Alexander von Gluck IV <kallisti5@unixzen.com>
Date: Thu, 14 Mar 2024 12:54:33 -0500
Subject: config.guess: Update to universal haiku arch guessing
* Matches upstream config.guess as of 2022, python just
ships a really old one
diff --git a/config.guess b/config.guess
index e81d3ae..366429c 100755
--- a/config.guess
+++ b/config.guess
@@ -1364,8 +1364,11 @@ EOF
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
GUESS=i586-pc-haiku
;;
- x86_64:Haiku:*:*)
- GUESS=x86_64-unknown-haiku
+ ppc:Haiku:*:*)
+ GUESS=powerpc-apple-haiku
+ ;;
+ *:Haiku:*:*)
+ GUESS=$UNAME_MACHINE-unknown-haiku
;;
SX-4:SUPER-UX:*:*)
GUESS=sx4-nec-superux$UNAME_RELEASE
--
2.45.2
From 62187db712b992fd67fefd1bfe5a4ee974f26af6 Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Fri, 9 Aug 2024 13:38:28 -0300
Subject: fix test_utf8_mode.
diff --git a/Lib/test/test_utf8_mode.py b/Lib/test/test_utf8_mode.py
index f668810..a55a8e4 100644
--- a/Lib/test/test_utf8_mode.py
+++ b/Lib/test/test_utf8_mode.py
@@ -226,7 +226,7 @@ class UTF8ModeTests(unittest.TestCase):
with self.subTest(LC_ALL=loc):
check('utf8', [arg_utf8], LC_ALL=loc)
- if sys.platform == 'darwin' or support.is_android or VXWORKS:
+ if sys.platform == 'darwin' or support.is_android or VXWORKS or sys.platform[:5] == 'haiku':
c_arg = arg_utf8
elif sys.platform.startswith("aix"):
c_arg = arg.decode('iso-8859-1')
--
2.45.2
From 1aaae4cbef0f3e832506d71be41b06164a440dd3 Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Fri, 9 Aug 2024 14:35:04 -0300
Subject: Fix test_site.
test_site expects a specific set of modules to be imported.
By importing "subprocess" (for calling `finddir`) we end up breaking
that assumption.
Also, site.py should avoid costly imports to help startup times.
Hardcoding a few paths avoids having to import subprocess, that
causes many other subsequent imports.
diff --git a/Lib/site.py b/Lib/site.py
index 3a714a0..2124aa1 100644
--- a/Lib/site.py
+++ b/Lib/site.py
@@ -303,12 +303,8 @@ def _getuserbase():
"%d.%d" % sys.version_info[:2])
if sys.platform.startswith('haiku'):
- try:
- import subprocess
- return subprocess.check_output(
- ['finddir', 'B_USER_NONPACKAGED_DIRECTORY']).rstrip().decode('utf-8')
- except:
- pass
+ # 'B_USER_NONPACKAGED_DIRECTORY'
+ return joinuser("~", "config", "non-packaged")
return joinuser("~", ".local")
@@ -402,16 +398,8 @@ def getsitepackages(prefixes=None):
# For .hpkg installed under ~/config/ (pkgman install -H)
# ("pip install --user" uses ~/config/non-packaged/, and gets
# handled by the "haiku_user" install scheme.
- try:
- import subprocess
- _home_prefix = subprocess.check_output(
- ['finddir', 'B_USER_CONFIG_DIRECTORY']).rstrip().decode('utf-8')
- except:
- # print("'finddir B_USER_CONFIG_DIRECTORY' failed.")
- _home_prefix = None
-
- if _home_prefix is not None:
- sitepackages.append(os.path.join(_home_prefix, "lib",
+ _home_prefix = os.path.expanduser(os.path.join("~", "config"))
+ sitepackages.append(os.path.join(_home_prefix, "lib",
"python%d.%d" % sys.version_info[:2],
"vendor-packages"))
elif os.sep == '/':
diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py
index 1a9c81d..09e612f 100644
--- a/Lib/test/test_site.py
+++ b/Lib/test/test_site.py
@@ -322,7 +322,21 @@ class HelperFunctionsTests(unittest.TestCase):
def test_getsitepackages(self):
site.PREFIXES = ['xoxo']
dirs = site.getsitepackages()
- if os.sep == '/':
+ if sys.platform[:5] == 'haiku':
+ self.assertEqual(len(dirs), 3) # site-packages + sys/user vendor-packages
+ wanted = os.path.join('xoxo', 'non-packaged', 'lib',
+ 'python%d.%d' % sys.version_info[:2],
+ 'site-packages')
+ self.assertEqual(dirs[0], wanted)
+ wanted = os.path.join('xoxo', sys.platlibdir,
+ 'python%d.%d' % sys.version_info[:2],
+ 'vendor-packages')
+ self.assertEqual(dirs[1], wanted)
+ wanted = os.path.join('xoxo', os.path.expanduser('~/config'), 'lib',
+ 'python%d.%d' % sys.version_info[:2],
+ 'vendor-packages')
+ self.assertEqual(dirs[2], wanted)
+ elif os.sep == '/':
# OS X, Linux, FreeBSD, etc
if sys.platlibdir != "lib":
self.assertEqual(len(dirs), 2)
--
2.45.2
From 08a6fc4f113001e8601ef50eed14b9a3fd9b2f5d Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Fri, 9 Aug 2024 15:37:13 -0300
Subject: Fix test_sysconfig.
diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py
index 35bea57..04c136f 100644
--- a/Lib/test/test_sysconfig.py
+++ b/Lib/test/test_sysconfig.py
@@ -210,6 +210,19 @@ class TestSysConfig(unittest.TestCase):
sysconfig.get_path('purelib', scheme='venv'),
sysconfig.get_path('purelib', scheme='nt_venv')
)
+ elif sys.platform[:5] == 'haiku':
+ self.assertEqual(
+ sysconfig.get_path('scripts', scheme='venv'),
+ sysconfig.get_path('scripts', scheme='haiku_venv')
+ )
+ self.assertEqual(
+ sysconfig.get_path('include', scheme='venv'),
+ sysconfig.get_path('include', scheme='haiku_venv')
+ )
+ self.assertEqual(
+ sysconfig.get_path('purelib', scheme='venv'),
+ sysconfig.get_path('purelib', scheme='haiku_venv')
+ )
else:
self.assertEqual(
sysconfig.get_path('scripts', scheme='venv'),
@@ -354,7 +367,7 @@ class TestSysConfig(unittest.TestCase):
def test_get_scheme_names(self):
wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv', 'haiku',
- 'haiku_home', 'haiku_vendor']
+ 'haiku_home', 'haiku_vendor', 'haiku_venv']
if HAS_USER_BASE:
wanted.extend(['nt_user', 'osx_framework_user', 'posix_user', 'haiku_user'])
self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))
--
2.45.2
From b9c25f918355e58eceb0a92e506ea86ce355cce5 Mon Sep 17 00:00:00 2001
From: Oscar Lesta <oscar.lesta@gmail.com>
Date: Fri, 9 Aug 2024 15:45:45 -0300
Subject: Fix test_compileall by skipping tests that need hardlink support.
Just a quick fix. Python 3.13 has "@os_helper.skip_unless_hardlink"
which reads better (albeit we need to patch a bit too).
diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py
index 5832f84..2e736db 100644
--- a/Lib/test/test_compileall.py
+++ b/Lib/test/test_compileall.py
@@ -921,6 +921,7 @@ class CommandLineTestsBase:
# only for more than one optimization level
self.assertRunNotOK(self.directory, "-o 1", "--hardlink-dupes")
+ @unittest.skipUnless(sys.platform[:5] != 'haiku', 'requires hardlink support')
def test_hardlink(self):
# 'a = 0' code produces the same bytecode for the 3 optimization
# levels. All three .pyc files must have the same inode (hardlinks).
@@ -958,7 +959,7 @@ class CommandLineTestsNoSourceEpoch(CommandLineTestsBase,
-@unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
+@unittest.skipUnless(hasattr(os, 'link') and sys.platform[:5] != 'haiku', 'requires os.link')
class HardlinkDedupTestsBase:
# Test hardlink_dupes parameter of compileall.compile_dir()
--
2.45.2