mirror of
https://github.com/pyenv/pyenv.git
synced 2024-11-21 20:47:00 -05:00
Add Python 2.7.18 patches for Apple Silicon machines (#2061)
This commit is contained in:
parent
dcfd715603
commit
1bd397112a
7 changed files with 766 additions and 0 deletions
|
@ -0,0 +1,41 @@
|
||||||
|
From 5495fb4719fa67ea3abeda0434699c8b28c77bb3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takumi Sueda <puhitaku@gmail.com>
|
||||||
|
Date: Sat, 11 Sep 2021 16:50:14 +0900
|
||||||
|
Subject: [PATCH 1/7] Detect arm64 in configure
|
||||||
|
|
||||||
|
---
|
||||||
|
configure | 3 +++
|
||||||
|
configure.ac | 3 +++
|
||||||
|
2 files changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/configure b/configure
|
||||||
|
index 63d675312d..c40ec120de 100755
|
||||||
|
--- a/configure
|
||||||
|
+++ b/configure
|
||||||
|
@@ -8474,6 +8474,9 @@ fi
|
||||||
|
ppc)
|
||||||
|
MACOSX_DEFAULT_ARCH="ppc64"
|
||||||
|
;;
|
||||||
|
+ arm64)
|
||||||
|
+ MACOSX_DEFAULT_ARCH="arm64"
|
||||||
|
+ ;;
|
||||||
|
*)
|
||||||
|
as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5
|
||||||
|
;;
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index efe6922b5d..df05bee87b 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -2066,6 +2066,9 @@ case $ac_sys_system/$ac_sys_release in
|
||||||
|
ppc)
|
||||||
|
MACOSX_DEFAULT_ARCH="ppc64"
|
||||||
|
;;
|
||||||
|
+ arm64)
|
||||||
|
+ MACOSX_DEFAULT_ARCH="arm64"
|
||||||
|
+ ;;
|
||||||
|
*)
|
||||||
|
AC_MSG_ERROR([Unexpected output of 'arch' on OSX])
|
||||||
|
;;
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,237 @@
|
||||||
|
From f17b9e30bd295b1eec68105e3f04568477ce6286 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takumi Sueda <puhitaku@gmail.com>
|
||||||
|
Date: Sat, 11 Sep 2021 17:14:34 +0900
|
||||||
|
Subject: [PATCH 2/7] Fix macOS _tkinter use of Tck/Tk in /Library/Framework
|
||||||
|
|
||||||
|
Modified and imported from https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
|
||||||
|
---
|
||||||
|
setup.py | 148 +++++++++++++++++++++++++++++++++++++++----------------
|
||||||
|
1 file changed, 106 insertions(+), 42 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/setup.py b/setup.py
|
||||||
|
index f764223d06..da1d34efaf 100644
|
||||||
|
--- a/setup.py
|
||||||
|
+++ b/setup.py
|
||||||
|
@@ -50,6 +50,7 @@ def add_dir_to_list(dirlist, dir):
|
||||||
|
dirlist.insert(0, dir)
|
||||||
|
|
||||||
|
MACOS_SDK_ROOT = None
|
||||||
|
+MACOS_SDK_SPECIFIED = None
|
||||||
|
|
||||||
|
def macosx_sdk_root():
|
||||||
|
"""Return the directory of the current macOS SDK.
|
||||||
|
@@ -61,8 +62,9 @@ def macosx_sdk_root():
|
||||||
|
(The SDK may be supplied via Xcode or via the Command Line Tools).
|
||||||
|
The SDK paths used by Apple-supplied tool chains depend on the
|
||||||
|
setting of various variables; see the xcrun man page for more info.
|
||||||
|
+ Also sets MACOS_SDK_SPECIFIED for use by macosx_sdk_specified().
|
||||||
|
"""
|
||||||
|
- global MACOS_SDK_ROOT
|
||||||
|
+ global MACOS_SDK_ROOT, MACOS_SDK_SPECIFIED
|
||||||
|
|
||||||
|
# If already called, return cached result.
|
||||||
|
if MACOS_SDK_ROOT:
|
||||||
|
@@ -72,8 +74,10 @@ def macosx_sdk_root():
|
||||||
|
m = re.search(r'-isysroot\s+(\S+)', cflags)
|
||||||
|
if m is not None:
|
||||||
|
MACOS_SDK_ROOT = m.group(1)
|
||||||
|
+ MACOS_SDK_SPECIFIED = MACOS_SDK_ROOT != '/'
|
||||||
|
else:
|
||||||
|
MACOS_SDK_ROOT = '/'
|
||||||
|
+ MACOS_SDK_SPECIFIED = False
|
||||||
|
cc = sysconfig.get_config_var('CC')
|
||||||
|
tmpfile = '/tmp/setup_sdk_root.%d' % os.getpid()
|
||||||
|
try:
|
||||||
|
@@ -101,6 +105,27 @@ def macosx_sdk_root():
|
||||||
|
|
||||||
|
return MACOS_SDK_ROOT
|
||||||
|
|
||||||
|
+def macosx_sdk_specified():
|
||||||
|
+ """Returns true if an SDK was explicitly configured.
|
||||||
|
+
|
||||||
|
+ True if an SDK was selected at configure time, either by specifying
|
||||||
|
+ --enable-universalsdk=(something other than no or /) or by adding a
|
||||||
|
+ -isysroot option to CFLAGS. In some cases, like when making
|
||||||
|
+ decisions about macOS Tk framework paths, we need to be able to
|
||||||
|
+ know whether the user explicitly asked to build with an SDK versus
|
||||||
|
+ the implicit use of an SDK when header files are no longer
|
||||||
|
+ installed on a running system by the Command Line Tools.
|
||||||
|
+ """
|
||||||
|
+ global MACOS_SDK_SPECIFIED
|
||||||
|
+
|
||||||
|
+ # If already called, return cached result.
|
||||||
|
+ if MACOS_SDK_SPECIFIED:
|
||||||
|
+ return MACOS_SDK_SPECIFIED
|
||||||
|
+
|
||||||
|
+ # Find the sdk root and set MACOS_SDK_SPECIFIED
|
||||||
|
+ macosx_sdk_root()
|
||||||
|
+ return MACOS_SDK_SPECIFIED
|
||||||
|
+
|
||||||
|
def is_macosx_sdk_path(path):
|
||||||
|
"""
|
||||||
|
Returns True if 'path' can be located in an OSX SDK
|
||||||
|
@@ -1834,31 +1859,72 @@ class PyBuildExt(build_ext):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
|
||||||
|
- # The _tkinter module, using frameworks. Since frameworks are quite
|
||||||
|
- # different the UNIX search logic is not sharable.
|
||||||
|
- from os.path import join, exists
|
||||||
|
- framework_dirs = [
|
||||||
|
- '/Library/Frameworks',
|
||||||
|
- '/System/Library/Frameworks/',
|
||||||
|
- join(os.getenv('HOME'), '/Library/Frameworks')
|
||||||
|
- ]
|
||||||
|
+ # Build default _tkinter on macOS using Tcl and Tk frameworks.
|
||||||
|
+ #
|
||||||
|
+ # The macOS native Tk (AKA Aqua Tk) and Tcl are most commonly
|
||||||
|
+ # built and installed as macOS framework bundles. However,
|
||||||
|
+ # for several reasons, we cannot take full advantage of the
|
||||||
|
+ # Apple-supplied compiler chain's -framework options here.
|
||||||
|
+ # Instead, we need to find and pass to the compiler the
|
||||||
|
+ # absolute paths of the Tcl and Tk headers files we want to use
|
||||||
|
+ # and the absolute path to the directory containing the Tcl
|
||||||
|
+ # and Tk frameworks for linking.
|
||||||
|
+ #
|
||||||
|
+ # We want to handle here two common use cases on macOS:
|
||||||
|
+ # 1. Build and link with system-wide third-party or user-built
|
||||||
|
+ # Tcl and Tk frameworks installed in /Library/Frameworks.
|
||||||
|
+ # 2. Build and link using a user-specified macOS SDK so that the
|
||||||
|
+ # built Python can be exported to other systems. In this case,
|
||||||
|
+ # search only the SDK's /Library/Frameworks (normally empty)
|
||||||
|
+ # and /System/Library/Frameworks.
|
||||||
|
+ #
|
||||||
|
+ # Any other use case should be able to be handled explicitly by
|
||||||
|
+ # using the options described above in detect_tkinter_explicitly().
|
||||||
|
+ # In particular it would be good to handle here the case where
|
||||||
|
+ # you want to build and link with a framework build of Tcl and Tk
|
||||||
|
+ # that is not in /Library/Frameworks, say, in your private
|
||||||
|
+ # $HOME/Library/Frameworks directory or elsewhere. It turns
|
||||||
|
+ # out to be difficult to make that work automtically here
|
||||||
|
+ # without bringing into play more tools and magic. That case
|
||||||
|
+ # can be hamdled using a recipe with the right arguments
|
||||||
|
+ # to detect_tkinter_explicitly().
|
||||||
|
+ #
|
||||||
|
+ # Note also that the fallback case here is to try to use the
|
||||||
|
+ # Apple-supplied Tcl and Tk frameworks in /System/Library but
|
||||||
|
+ # be forewarned that they are deprecated by Apple and typically
|
||||||
|
+ # out-of-date and buggy; their use should be avoided if at
|
||||||
|
+ # all possible by installing a newer version of Tcl and Tk in
|
||||||
|
+ # /Library/Frameworks before bwfore building Python without
|
||||||
|
+ # an explicit SDK or by configuring build arguments explicitly.
|
||||||
|
|
||||||
|
- sysroot = macosx_sdk_root()
|
||||||
|
+ from os.path import join, exists
|
||||||
|
+ sysroot = macosx_sdk_root() # path to the SDK or '/'
|
||||||
|
+
|
||||||
|
+ if macosx_sdk_specified():
|
||||||
|
+ # Use case #2: an SDK other than '/' was specified.
|
||||||
|
+ # Only search there.
|
||||||
|
+ framework_dirs = [
|
||||||
|
+ join(sysroot, 'Library', 'Frameworks'),
|
||||||
|
+ join(sysroot, 'System', 'Library', 'Frameworks'),
|
||||||
|
+ ]
|
||||||
|
+ else:
|
||||||
|
+ # Use case #1: no explicit SDK selected.
|
||||||
|
+ # Search the local system-wide /Library/Frameworks,
|
||||||
|
+ # not the one in the default SDK, othewise fall back to
|
||||||
|
+ # /System/Library/Frameworks whose header files may be in
|
||||||
|
+ # the default SDK or, on older systems, actually installed.
|
||||||
|
+ framework_dirs = [
|
||||||
|
+ join('/', 'Library', 'Frameworks'),
|
||||||
|
+ join(sysroot, 'System', 'Library', 'Frameworks'),
|
||||||
|
+ ]
|
||||||
|
|
||||||
|
- # Find the directory that contains the Tcl.framework and Tk.framework
|
||||||
|
- # bundles.
|
||||||
|
- # XXX distutils should support -F!
|
||||||
|
+ # Find the directory that contains the Tcl.framework and
|
||||||
|
+ # Tk.framework bundles.
|
||||||
|
for F in framework_dirs:
|
||||||
|
# both Tcl.framework and Tk.framework should be present
|
||||||
|
-
|
||||||
|
-
|
||||||
|
for fw in 'Tcl', 'Tk':
|
||||||
|
- if is_macosx_sdk_path(F):
|
||||||
|
- if not exists(join(sysroot, F[1:], fw + '.framework')):
|
||||||
|
- break
|
||||||
|
- else:
|
||||||
|
- if not exists(join(F, fw + '.framework')):
|
||||||
|
- break
|
||||||
|
+ if not exists(join(F, fw + '.framework')):
|
||||||
|
+ break
|
||||||
|
else:
|
||||||
|
# ok, F is now directory with both frameworks. Continure
|
||||||
|
# building
|
||||||
|
@@ -1868,32 +1934,20 @@ class PyBuildExt(build_ext):
|
||||||
|
# will now resume.
|
||||||
|
return 0
|
||||||
|
|
||||||
|
- # For 8.4a2, we must add -I options that point inside the Tcl and Tk
|
||||||
|
- # frameworks. In later release we should hopefully be able to pass
|
||||||
|
- # the -F option to gcc, which specifies a framework lookup path.
|
||||||
|
- #
|
||||||
|
include_dirs = [
|
||||||
|
join(F, fw + '.framework', H)
|
||||||
|
for fw in 'Tcl', 'Tk'
|
||||||
|
- for H in 'Headers', 'Versions/Current/PrivateHeaders'
|
||||||
|
+ for H in ('Headers',)
|
||||||
|
]
|
||||||
|
|
||||||
|
- # For 8.4a2, the X11 headers are not included. Rather than include a
|
||||||
|
- # complicated search, this is a hard-coded path. It could bail out
|
||||||
|
- # if X11 libs are not found...
|
||||||
|
- include_dirs.append('/usr/X11R6/include')
|
||||||
|
- frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
|
||||||
|
+ # Add the base framework directory as well
|
||||||
|
+ compile_args = ['-F', F]
|
||||||
|
|
||||||
|
- # All existing framework builds of Tcl/Tk don't support 64-bit
|
||||||
|
- # architectures.
|
||||||
|
+ # Do not build tkinter for archs that this Tk was not built with.
|
||||||
|
cflags = sysconfig.get_config_vars('CFLAGS')[0]
|
||||||
|
archs = re.findall('-arch\s+(\w+)', cflags)
|
||||||
|
|
||||||
|
- if is_macosx_sdk_path(F):
|
||||||
|
- fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(os.path.join(sysroot, F[1:]),))
|
||||||
|
- else:
|
||||||
|
- fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(F,))
|
||||||
|
-
|
||||||
|
+ fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(F,))
|
||||||
|
detected_archs = []
|
||||||
|
for ln in fp:
|
||||||
|
a = ln.split()[-1]
|
||||||
|
@@ -1901,16 +1955,26 @@ class PyBuildExt(build_ext):
|
||||||
|
detected_archs.append(ln.split()[-1])
|
||||||
|
fp.close()
|
||||||
|
|
||||||
|
+ arch_args = []
|
||||||
|
for a in detected_archs:
|
||||||
|
- frameworks.append('-arch')
|
||||||
|
- frameworks.append(a)
|
||||||
|
+ arch_args.append('-arch')
|
||||||
|
+ arch_args.append(a)
|
||||||
|
+
|
||||||
|
+ compile_args += arch_args
|
||||||
|
+ link_args = [','.join(['-Wl', '-F', F, '-framework', 'Tcl', '-framework', 'Tk'])] + arch_args
|
||||||
|
+
|
||||||
|
+ # The X11/xlib.h file bundled in the Tk sources can cause function
|
||||||
|
+ # prototype warnings from the compiler. Since we cannot easily fix
|
||||||
|
+ # that, suppress the warnings here instead.
|
||||||
|
+ if '-Wstrict-prototypes' in cflags.split():
|
||||||
|
+ compile_args.append('-Wno-strict-prototypes')
|
||||||
|
|
||||||
|
ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
|
||||||
|
define_macros=[('WITH_APPINIT', 1)],
|
||||||
|
include_dirs = include_dirs,
|
||||||
|
libraries = [],
|
||||||
|
- extra_compile_args = frameworks[2:],
|
||||||
|
- extra_link_args = frameworks,
|
||||||
|
+ extra_compile_args = compile_args,
|
||||||
|
+ extra_link_args = link_args,
|
||||||
|
)
|
||||||
|
self.extensions.append(ext)
|
||||||
|
return 1
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
From d93a26fee21a5f91c51d8cb14ecaf29122f1b222 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takumi Sueda <puhitaku@gmail.com>
|
||||||
|
Date: Sat, 11 Sep 2021 17:25:00 +0900
|
||||||
|
Subject: [PATCH 3/7] Support "arm64" in Mac/Tools/pythonw
|
||||||
|
|
||||||
|
Imported from: https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
|
||||||
|
---
|
||||||
|
Mac/Tools/pythonw.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/Mac/Tools/pythonw.c b/Mac/Tools/pythonw.c
|
||||||
|
index 76734c1063..ebe5e8d975 100644
|
||||||
|
--- a/Mac/Tools/pythonw.c
|
||||||
|
+++ b/Mac/Tools/pythonw.c
|
||||||
|
@@ -116,10 +116,16 @@ setup_spawnattr(posix_spawnattr_t* spawnattr)
|
||||||
|
|
||||||
|
#elif defined(__ppc__)
|
||||||
|
cpu_types[0] = CPU_TYPE_POWERPC;
|
||||||
|
+
|
||||||
|
#elif defined(__i386__)
|
||||||
|
cpu_types[0] = CPU_TYPE_X86;
|
||||||
|
+
|
||||||
|
+#elif defined(__arm64__)
|
||||||
|
+ cpu_types[0] = CPU_TYPE_ARM64;
|
||||||
|
+
|
||||||
|
#else
|
||||||
|
# error "Unknown CPU"
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (posix_spawnattr_setbinpref_np(spawnattr, count,
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
From a1b08c7de72c27d80a86b92c263d1f5b351e581b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takumi Sueda <puhitaku@gmail.com>
|
||||||
|
Date: Sat, 11 Sep 2021 18:07:48 +0900
|
||||||
|
Subject: [PATCH 4/7] Use system libffi for Mac OS 10.15 and up
|
||||||
|
|
||||||
|
Modified and imported from: https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
|
||||||
|
---
|
||||||
|
setup.py | 37 ++++++++++++++++++++++++++++---------
|
||||||
|
1 file changed, 28 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/setup.py b/setup.py
|
||||||
|
index da1d34efaf..c92d0552e3 100644
|
||||||
|
--- a/setup.py
|
||||||
|
+++ b/setup.py
|
||||||
|
@@ -126,6 +126,13 @@ def macosx_sdk_specified():
|
||||||
|
macosx_sdk_root()
|
||||||
|
return MACOS_SDK_SPECIFIED
|
||||||
|
|
||||||
|
+def is_macosx_at_least(vers):
|
||||||
|
+ if host_platform == 'darwin':
|
||||||
|
+ dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
|
||||||
|
+ if dep_target:
|
||||||
|
+ return tuple(map(int, str(dep_target).split('.'))) >= vers
|
||||||
|
+ return False
|
||||||
|
+
|
||||||
|
def is_macosx_sdk_path(path):
|
||||||
|
"""
|
||||||
|
Returns True if 'path' can be located in an OSX SDK
|
||||||
|
@@ -2180,7 +2187,11 @@ class PyBuildExt(build_ext):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def detect_ctypes(self, inc_dirs, lib_dirs):
|
||||||
|
- self.use_system_libffi = False
|
||||||
|
+ if not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and is_macosx_at_least((10,15)):
|
||||||
|
+ self.use_system_libffi = True
|
||||||
|
+ else:
|
||||||
|
+ self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS")
|
||||||
|
+
|
||||||
|
include_dirs = []
|
||||||
|
extra_compile_args = []
|
||||||
|
extra_link_args = []
|
||||||
|
@@ -2224,15 +2235,24 @@ class PyBuildExt(build_ext):
|
||||||
|
sources=['_ctypes/_ctypes_test.c'])
|
||||||
|
self.extensions.extend([ext, ext_test])
|
||||||
|
|
||||||
|
- if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"):
|
||||||
|
- return
|
||||||
|
+ ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
|
||||||
|
+ ffi_lib = None
|
||||||
|
|
||||||
|
+ #inc_dirs = self.inc_dirs.copy()
|
||||||
|
+ inc_dirs = self.compiler.include_dirs[:]
|
||||||
|
if host_platform == 'darwin':
|
||||||
|
- # OS X 10.5 comes with libffi.dylib; the include files are
|
||||||
|
- # in /usr/include/ffi
|
||||||
|
- inc_dirs.append('/usr/include/ffi')
|
||||||
|
+ if not self.use_system_libffi:
|
||||||
|
+ return
|
||||||
|
+ ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
|
||||||
|
+ if os.path.exists(ffi_in_sdk):
|
||||||
|
+ ffi_inc = [ffi_in_sdk]
|
||||||
|
+ ffi_lib = 'ffi'
|
||||||
|
+ sources.remove('_ctypes/malloc_closure.c')
|
||||||
|
+ else:
|
||||||
|
+ # OS X 10.5 comes with libffi.dylib; the include files are
|
||||||
|
+ # in /usr/include/ffi
|
||||||
|
+ inc_dirs.append('/usr/include/ffi')
|
||||||
|
|
||||||
|
- ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
|
||||||
|
if not ffi_inc or ffi_inc[0] == '':
|
||||||
|
ffi_inc = find_file('ffi.h', [], inc_dirs)
|
||||||
|
if ffi_inc is not None:
|
||||||
|
@@ -2247,8 +2267,7 @@ class PyBuildExt(build_ext):
|
||||||
|
ffi_inc = None
|
||||||
|
print('Header file {} does not define LIBFFI_H or '
|
||||||
|
'ffi_wrapper_h'.format(ffi_h))
|
||||||
|
- ffi_lib = None
|
||||||
|
- if ffi_inc is not None:
|
||||||
|
+ if ffi_lib is None and ffi_inc is not None:
|
||||||
|
for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
|
||||||
|
if (self.compiler.find_library_file(lib_dirs, lib_name)):
|
||||||
|
ffi_lib = lib_name
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,221 @@
|
||||||
|
From 4394ec26842b04335b30b9a0595fcc8591c68496 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takumi Sueda <puhitaku@gmail.com>
|
||||||
|
Date: Sat, 11 Sep 2021 18:59:44 +0900
|
||||||
|
Subject: [PATCH 5/7] ctypes: use the correct ABI for variadic functions
|
||||||
|
|
||||||
|
Modified and imported from https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
|
||||||
|
---
|
||||||
|
Doc/library/ctypes.rst | 6 +++++
|
||||||
|
Lib/test/test_str.py | 2 ++
|
||||||
|
Lib/test/test_unicode.py | 3 +++
|
||||||
|
Modules/_ctypes/_ctypes.c | 31 +++++++++++++++++++++++
|
||||||
|
Modules/_ctypes/callproc.c | 51 +++++++++++++++++++++++++++++---------
|
||||||
|
Modules/_ctypes/ctypes.h | 1 +
|
||||||
|
6 files changed, 82 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst
|
||||||
|
index 6a5299145f..ec97da607f 100644
|
||||||
|
--- a/Doc/library/ctypes.rst
|
||||||
|
+++ b/Doc/library/ctypes.rst
|
||||||
|
@@ -1584,6 +1584,12 @@ They are instances of a private class:
|
||||||
|
value usable as argument (integer, string, ctypes instance). This allows
|
||||||
|
defining adapters that can adapt custom objects as function parameters.
|
||||||
|
|
||||||
|
+ .. attribute:: variadic
|
||||||
|
+
|
||||||
|
+ Assign a boolean to specify that the function takes a variable number of
|
||||||
|
+ arguments. This does not matter on most platforms, but for Apple arm64
|
||||||
|
+ platforms variadic functions have a different calling convention than
|
||||||
|
+ normal functions.
|
||||||
|
|
||||||
|
.. attribute:: errcheck
|
||||||
|
|
||||||
|
diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py
|
||||||
|
index 73ed542a51..131f6d13e0 100644
|
||||||
|
--- a/Lib/test/test_str.py
|
||||||
|
+++ b/Lib/test/test_str.py
|
||||||
|
@@ -489,6 +489,8 @@ class CAPITest(unittest.TestCase):
|
||||||
|
c_char_p)
|
||||||
|
|
||||||
|
PyString_FromFormat = pythonapi.PyString_FromFormat
|
||||||
|
+ PyString_FromFormat.variadic = True
|
||||||
|
+ PyString_FromFormat.argtypes = (c_char_p,)
|
||||||
|
PyString_FromFormat.restype = py_object
|
||||||
|
|
||||||
|
# basic tests
|
||||||
|
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
|
||||||
|
index 92476f68a5..23e9e643e0 100644
|
||||||
|
--- a/Lib/test/test_unicode.py
|
||||||
|
+++ b/Lib/test/test_unicode.py
|
||||||
|
@@ -1676,6 +1676,7 @@ class CAPITest(unittest.TestCase):
|
||||||
|
def test_from_format(self):
|
||||||
|
test_support.import_module('ctypes')
|
||||||
|
from ctypes import (
|
||||||
|
+ c_char_p,
|
||||||
|
pythonapi, py_object, sizeof,
|
||||||
|
c_int, c_long, c_longlong, c_ssize_t,
|
||||||
|
c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p)
|
||||||
|
@@ -1684,6 +1685,8 @@ class CAPITest(unittest.TestCase):
|
||||||
|
else:
|
||||||
|
name = "PyUnicodeUCS4_FromFormat"
|
||||||
|
_PyUnicode_FromFormat = getattr(pythonapi, name)
|
||||||
|
+ _PyUnicode_FromFormat.argtypes = (c_char_p,)
|
||||||
|
+ _PyUnicode_FromFormat.variadic = True
|
||||||
|
_PyUnicode_FromFormat.restype = py_object
|
||||||
|
|
||||||
|
def PyUnicode_FromFormat(format, *args):
|
||||||
|
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
|
||||||
|
index bef251ef04..d03b98d09c 100644
|
||||||
|
--- a/Modules/_ctypes/_ctypes.c
|
||||||
|
+++ b/Modules/_ctypes/_ctypes.c
|
||||||
|
@@ -3253,6 +3253,34 @@ PyCFuncPtr_get_restype(PyCFuncPtrObject *self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+PyCFuncPtr_set_variadic(PyCFuncPtrObject *self, PyObject *ob)
|
||||||
|
+{
|
||||||
|
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
|
||||||
|
+ assert(dict);
|
||||||
|
+ int r = PyObject_IsTrue(ob);
|
||||||
|
+ if (r == 1) {
|
||||||
|
+ dict->flags |= FUNCFLAG_VARIADIC;
|
||||||
|
+ return 0;
|
||||||
|
+ } else if (r == 0) {
|
||||||
|
+ dict->flags &= ~FUNCFLAG_VARIADIC;
|
||||||
|
+ return 0;
|
||||||
|
+ } else {
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static PyObject *
|
||||||
|
+PyCFuncPtr_get_variadic(PyCFuncPtrObject *self)
|
||||||
|
+{
|
||||||
|
+ StgDictObject *dict = PyObject_stgdict((PyObject *)self);
|
||||||
|
+ assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
|
||||||
|
+ if (dict->flags & FUNCFLAG_VARIADIC)
|
||||||
|
+ Py_RETURN_TRUE;
|
||||||
|
+ else
|
||||||
|
+ Py_RETURN_FALSE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob)
|
||||||
|
{
|
||||||
|
@@ -3299,6 +3327,8 @@ static PyGetSetDef PyCFuncPtr_getsets[] = {
|
||||||
|
{ "argtypes", (getter)PyCFuncPtr_get_argtypes,
|
||||||
|
(setter)PyCFuncPtr_set_argtypes,
|
||||||
|
"specify the argument types", NULL },
|
||||||
|
+ { "variadic", (getter)PyCFuncPtr_get_variadic, (setter)PyCFuncPtr_set_variadic,
|
||||||
|
+ "specify if function takes variable number of arguments", NULL },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -5838,6 +5868,7 @@ init_ctypes(void)
|
||||||
|
PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyInt_FromLong(FUNCFLAG_USE_ERRNO));
|
||||||
|
PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyInt_FromLong(FUNCFLAG_USE_LASTERROR));
|
||||||
|
PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
|
||||||
|
+ PyModule_AddObject(m, "FUNCFLAG_VARIADIC", PyInt_FromLong(FUNCFLAG_VARIADIC));
|
||||||
|
PyModule_AddStringConstant(m, "__version__", "1.1.0");
|
||||||
|
|
||||||
|
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
|
||||||
|
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
|
||||||
|
index 066fefc0cc..39a539db47 100644
|
||||||
|
--- a/Modules/_ctypes/callproc.c
|
||||||
|
+++ b/Modules/_ctypes/callproc.c
|
||||||
|
@@ -88,6 +88,9 @@
|
||||||
|
#define DONT_USE_SEH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#if defined(__APPLE__) && __arm64__
|
||||||
|
+#define HAVE_FFI_PREP_CIF_VAR 1
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#define CTYPES_CAPSULE_ERROROBJ "_ctypes/callproc.c error object"
|
||||||
|
CTYPES_CAPSULE_INSTANTIATE_DESTRUCTOR(CTYPES_CAPSULE_ERROROBJ)
|
||||||
|
@@ -773,7 +776,8 @@ static int _call_function_pointer(int flags,
|
||||||
|
ffi_type **atypes,
|
||||||
|
ffi_type *restype,
|
||||||
|
void *resmem,
|
||||||
|
- int argcount)
|
||||||
|
+ int argcount,
|
||||||
|
+ int argtypecount)
|
||||||
|
{
|
||||||
|
#ifdef WITH_THREAD
|
||||||
|
PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
|
||||||
|
@@ -801,15 +805,39 @@ static int _call_function_pointer(int flags,
|
||||||
|
if ((flags & FUNCFLAG_CDECL) == 0)
|
||||||
|
cc = FFI_STDCALL;
|
||||||
|
#endif
|
||||||
|
- if (FFI_OK != ffi_prep_cif(&cif,
|
||||||
|
- cc,
|
||||||
|
- argcount,
|
||||||
|
- restype,
|
||||||
|
- atypes)) {
|
||||||
|
- PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
- "ffi_prep_cif failed");
|
||||||
|
- return -1;
|
||||||
|
+
|
||||||
|
+#if HAVE_FFI_PREP_CIF_VAR
|
||||||
|
+ /* Everyone SHOULD set f.variadic=True on variadic function pointers, but
|
||||||
|
+ * lots of existing code will not. If there's at least one arg and more
|
||||||
|
+ * args are passed than are defined in the prototype, then it must be a
|
||||||
|
+ * variadic function. */
|
||||||
|
+ if ((flags & FUNCFLAG_VARIADIC) ||
|
||||||
|
+ (argtypecount != 0 && argcount > argtypecount))
|
||||||
|
+ {
|
||||||
|
+ if (FFI_OK != ffi_prep_cif_var(&cif,
|
||||||
|
+ cc,
|
||||||
|
+ argtypecount,
|
||||||
|
+ argcount,
|
||||||
|
+ restype,
|
||||||
|
+ atypes)) {
|
||||||
|
+ PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
+ "ffi_prep_cif_var failed");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+#endif
|
||||||
|
+ if (FFI_OK != ffi_prep_cif(&cif,
|
||||||
|
+ cc,
|
||||||
|
+ argcount,
|
||||||
|
+ restype,
|
||||||
|
+ atypes)) {
|
||||||
|
+ PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
+ "ffi_prep_cif failed");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+#if HAVE_FFI_PREP_CIF_VAR
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
|
||||||
|
error_object = _ctypes_get_errobj(&space);
|
||||||
|
@@ -1181,9 +1209,8 @@ PyObject *_ctypes_callproc(PPROC pProc,
|
||||||
|
|
||||||
|
if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
|
||||||
|
rtype, resbuf,
|
||||||
|
- Py_SAFE_DOWNCAST(argcount,
|
||||||
|
- Py_ssize_t,
|
||||||
|
- int)))
|
||||||
|
+ Py_SAFE_DOWNCAST(argcount, Py_ssize_t, int),
|
||||||
|
+ Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
|
||||||
|
index 12b56c4342..8aec3d1ade 100644
|
||||||
|
--- a/Modules/_ctypes/ctypes.h
|
||||||
|
+++ b/Modules/_ctypes/ctypes.h
|
||||||
|
@@ -325,6 +325,7 @@ PyObject *_ctypes_callproc(PPROC pProc,
|
||||||
|
#define FUNCFLAG_PYTHONAPI 0x4
|
||||||
|
#define FUNCFLAG_USE_ERRNO 0x8
|
||||||
|
#define FUNCFLAG_USE_LASTERROR 0x10
|
||||||
|
+#define FUNCFLAG_VARIADIC 0x20
|
||||||
|
|
||||||
|
#define TYPEFLAG_ISPOINTER 0x100
|
||||||
|
#define TYPEFLAG_HASPOINTER 0x200
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
From 43819cd35cddd189cbe513032e76f1c1a6ec6d8c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takumi Sueda <puhitaku@gmail.com>
|
||||||
|
Date: Sat, 11 Sep 2021 19:14:50 +0900
|
||||||
|
Subject: [PATCH 6/7] ctypes: probe libffi for ffi_closure_alloc and
|
||||||
|
ffi_prep_cif_var
|
||||||
|
|
||||||
|
Modified and imported from https://github.com/Homebrew/formula-patches/blob/master/python/3.8.7.patch
|
||||||
|
---
|
||||||
|
Modules/_ctypes/callproc.c | 4 ----
|
||||||
|
setup.py | 34 +++++++++++++++++++++++++---------
|
||||||
|
2 files changed, 25 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
|
||||||
|
index 39a539db47..5273e8d246 100644
|
||||||
|
--- a/Modules/_ctypes/callproc.c
|
||||||
|
+++ b/Modules/_ctypes/callproc.c
|
||||||
|
@@ -88,10 +88,6 @@
|
||||||
|
#define DONT_USE_SEH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#if defined(__APPLE__) && __arm64__
|
||||||
|
-#define HAVE_FFI_PREP_CIF_VAR 1
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
#define CTYPES_CAPSULE_ERROROBJ "_ctypes/callproc.c error object"
|
||||||
|
CTYPES_CAPSULE_INSTANTIATE_DESTRUCTOR(CTYPES_CAPSULE_ERROROBJ)
|
||||||
|
|
||||||
|
diff --git a/setup.py b/setup.py
|
||||||
|
index c92d0552e3..beaf60f3e5 100644
|
||||||
|
--- a/setup.py
|
||||||
|
+++ b/setup.py
|
||||||
|
@@ -141,6 +141,13 @@ def is_macosx_sdk_path(path):
|
||||||
|
or path.startswith('/System/')
|
||||||
|
or path.startswith('/Library/') )
|
||||||
|
|
||||||
|
+def grep_headers_for(function, headers):
|
||||||
|
+ for header in headers:
|
||||||
|
+ with open(header, 'r') as f:
|
||||||
|
+ if function in f.read():
|
||||||
|
+ return True
|
||||||
|
+ return False
|
||||||
|
+
|
||||||
|
def find_file(filename, std_dirs, paths):
|
||||||
|
"""Searches for the directory where a given file is located,
|
||||||
|
and returns a possibly-empty list of additional directories, or None
|
||||||
|
@@ -2235,7 +2242,7 @@ class PyBuildExt(build_ext):
|
||||||
|
sources=['_ctypes/_ctypes_test.c'])
|
||||||
|
self.extensions.extend([ext, ext_test])
|
||||||
|
|
||||||
|
- ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
|
||||||
|
+ ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR")
|
||||||
|
ffi_lib = None
|
||||||
|
|
||||||
|
#inc_dirs = self.inc_dirs.copy()
|
||||||
|
@@ -2245,18 +2252,19 @@ class PyBuildExt(build_ext):
|
||||||
|
return
|
||||||
|
ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi")
|
||||||
|
if os.path.exists(ffi_in_sdk):
|
||||||
|
- ffi_inc = [ffi_in_sdk]
|
||||||
|
+ ffi_inc = ffi_in_sdk
|
||||||
|
ffi_lib = 'ffi'
|
||||||
|
- sources.remove('_ctypes/malloc_closure.c')
|
||||||
|
else:
|
||||||
|
# OS X 10.5 comes with libffi.dylib; the include files are
|
||||||
|
# in /usr/include/ffi
|
||||||
|
inc_dirs.append('/usr/include/ffi')
|
||||||
|
|
||||||
|
- if not ffi_inc or ffi_inc[0] == '':
|
||||||
|
- ffi_inc = find_file('ffi.h', [], inc_dirs)
|
||||||
|
- if ffi_inc is not None:
|
||||||
|
- ffi_h = ffi_inc[0] + '/ffi.h'
|
||||||
|
+ if not ffi_inc:
|
||||||
|
+ found = find_file('ffi.h', [], inc_dirs)
|
||||||
|
+ if found:
|
||||||
|
+ ffi_inc = found[0]
|
||||||
|
+ if ffi_inc:
|
||||||
|
+ ffi_h = ffi_inc + '/ffi.h'
|
||||||
|
with open(ffi_h) as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
@@ -2267,14 +2275,22 @@ class PyBuildExt(build_ext):
|
||||||
|
ffi_inc = None
|
||||||
|
print('Header file {} does not define LIBFFI_H or '
|
||||||
|
'ffi_wrapper_h'.format(ffi_h))
|
||||||
|
- if ffi_lib is None and ffi_inc is not None:
|
||||||
|
+ if ffi_lib is None and ffi_inc:
|
||||||
|
for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
|
||||||
|
if (self.compiler.find_library_file(lib_dirs, lib_name)):
|
||||||
|
ffi_lib = lib_name
|
||||||
|
break
|
||||||
|
|
||||||
|
if ffi_inc and ffi_lib:
|
||||||
|
- ext.include_dirs.extend(ffi_inc)
|
||||||
|
+ ffi_headers = glob(os.path.join(ffi_inc, '*.h'))
|
||||||
|
+ if grep_headers_for('ffi_closure_alloc', ffi_headers):
|
||||||
|
+ try:
|
||||||
|
+ sources.remove('_ctypes/malloc_closure.c')
|
||||||
|
+ except ValueError:
|
||||||
|
+ pass
|
||||||
|
+ if grep_headers_for('ffi_prep_cif_var', ffi_headers):
|
||||||
|
+ ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1")
|
||||||
|
+ ext.include_dirs.append(ffi_inc)
|
||||||
|
ext.libraries.append(ffi_lib)
|
||||||
|
self.use_system_libffi = True
|
||||||
|
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
From 41ee254166bb690feb665991fc2442e335631314 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Takumi Sueda <puhitaku@gmail.com>
|
||||||
|
Date: Sat, 11 Sep 2021 19:20:30 +0900
|
||||||
|
Subject: [PATCH 7/7] Remove QuickTime from link args
|
||||||
|
|
||||||
|
---
|
||||||
|
Mac/Modules/qt/setup.py | 2 +-
|
||||||
|
setup.py | 3 +--
|
||||||
|
2 files changed, 2 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Mac/Modules/qt/setup.py b/Mac/Modules/qt/setup.py
|
||||||
|
index 8442011ab9..4b5bc2bc20 100644
|
||||||
|
--- a/Mac/Modules/qt/setup.py
|
||||||
|
+++ b/Mac/Modules/qt/setup.py
|
||||||
|
@@ -6,7 +6,7 @@ from distutils.core import Extension, setup
|
||||||
|
setup(name="QuickTime", version="0.2",
|
||||||
|
ext_modules=[
|
||||||
|
Extension('QuickTime._Qt', ['_Qtmodule.c'],
|
||||||
|
- extra_link_args=['-framework', 'Carbon', '-framework', 'QuickTime'])
|
||||||
|
+ extra_link_args=['-framework', 'Carbon'])
|
||||||
|
],
|
||||||
|
py_modules=['QuickTime.Qt', 'QuickTime.QuickTime'],
|
||||||
|
package_dir={'QuickTime':'../../../Lib/plat-mac/Carbon'}
|
||||||
|
diff --git a/setup.py b/setup.py
|
||||||
|
index beaf60f3e5..ff2298af91 100644
|
||||||
|
--- a/setup.py
|
||||||
|
+++ b/setup.py
|
||||||
|
@@ -1819,8 +1819,7 @@ class PyBuildExt(build_ext):
|
||||||
|
|
||||||
|
exts.append( Extension('_Qt', ['qt/_Qtmodule.c'],
|
||||||
|
extra_compile_args=carbon_extra_compile_args,
|
||||||
|
- extra_link_args=['-framework', 'QuickTime',
|
||||||
|
- '-framework', 'Carbon']) )
|
||||||
|
+ extra_link_args=['-framework', 'Carbon']) )
|
||||||
|
|
||||||
|
|
||||||
|
self.extensions.extend(exts)
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
Loading…
Reference in a new issue