Skip to content

Commit c13b3d1

Browse files
ychinchrisbra
authored andcommitted
patch 9.0.1776: No support for stable Python 3 ABI
Problem: No support for stable Python 3 ABI Solution: Support Python 3 stable ABI Commits: 1) Support Python 3 stable ABI to allow mixed version interoperatbility Vim currently supports embedding Python for use with plugins, and the "dynamic" linking option allows the user to specify a locally installed version of Python by setting `pythonthreedll`. However, one caveat is that the Python 3 libs are not binary compatible across minor versions, and mixing versions can potentially be dangerous (e.g. let's say Vim was linked against the Python 3.10 SDK, but the user sets `pythonthreedll` to a 3.11 lib). Usually, nothing bad happens, but in theory this could lead to crashes, memory corruption, and other unpredictable behaviors. It's also difficult for the user to tell something is wrong because Vim has no way of reporting what Python 3 version Vim was linked with. For Vim installed via a package manager, this usually isn't an issue because all the dependencies would already be figured out. For prebuilt Vim binaries like MacVim (my motivation for working on this), AppImage, and Win32 installer this could potentially be an issue as usually a single binary is distributed. This is more tricky when a new Python version is released, as there's a chicken-and-egg issue with deciding what Python version to build against and hard to keep in sync when a new Python version just drops and we have a mix of users of different Python versions, and a user just blindly upgrading to a new Python could lead to bad interactions with Vim. Python 3 does have a solution for this problem: stable ABI / limited API (see https://docs.python.org/3/c-api/stable.html). The C SDK limits the API to a set of functions that are promised to be stable across versions. This pull request adds an ifdef config that allows us to turn it on when building Vim. Vim binaries built with this option should be safe to freely link with any Python 3 libraies without having the constraint of having to use the same minor version. Note: Python 2 has no such concept and this doesn't change how Python 2 integration works (not that there is going to be a new version of Python 2 that would cause compatibility issues in the future anyway). --- Technical details: ====== The stable ABI can be accessed when we compile with the Python 3 limited API (by defining `Py_LIMITED_API`). The Python 3 code (in `if_python3.c` and `if_py_both.h`) would now handle this and switch to limited API mode. Without it set, Vim will still use the full API as before so this is an opt-in change. The main difference is that `PyType_Object` is now an opaque struct that we can't directly create "static types" out of, and we have to create type objects as "heap types" instead. This is because the struct is not stable and changes from version to version (e.g. 3.8 added a `tp_vectorcall` field to it). I had to change all the types to be allocated on the heap instead with just a pointer to them. Other functions are also simply missing in limited API, or they are introduced too late (e.g. `PyUnicode_AsUTF8AndSize` in 3.10) to it that we need some other ways to do the same thing, so I had to abstract a few things into macros, and sometimes re-implement functions like `PyObject_NEW`. One caveat is that in limited API, `OutputType` (used for replacing `sys.stdout`) no longer inherits from `PyStdPrinter_Type` which I don't think has any real issue other than minor differences in how they convert to a string and missing a couple functions like `mode()` and `fileno()`. Also fixed an existing bug where `tp_basicsize` was set incorrectly for `BufferObject`, `TabListObject, `WinListObject`. Technically, there could be a small performance drop, there is a little more indirection with accessing type objects, and some APIs like `PyUnicode_AsUTF8AndSize` are missing, but in practice I didn't see any difference, and any well-written Python plugin should try to avoid excessing callbacks to the `vim` module in Python anyway. I only tested limited API mode down to Python 3.7, which seemes to compile and work fine. I haven't tried earlier Python versions. 2) Fix PyIter_Check on older Python vers / type##Ptr unused warning For PyIter_Check, older versions exposed them as either macros (used in full API), or a function (for use in limited API). A previous change exposed PyIter_Check to the dynamic build because Python just moved it to function-only in 3.10 anyway. Because of that, just make sure we always grab the function in dynamic builds in earlier versions since that's what Python eventually did anyway. 3) Move Py_LIMITED_API define to configure script Can now use --with-python-stable-abi flag to customize what stable ABI version to target. Can also use an env var to do so as well. 4) Show +python/dyn-stable in :version, and allow has() feature query Not sure if the "/dyn-stable" suffix would break things, or whether we should do it another way. Or just don't show it in version and rely on has() feature checking. 5) Documentation first draft. Still need to implement v:python3_version 6) Fix PyIter_Check build breaks when compiling against Python 3.8 7) Add CI coverage stable ABI on Linux/Windows / make configurable on Windows This adds configurable options for Windows make files (both MinGW and MSVC). CI will also now exercise both traditional full API and stable ABI for Linux and Windows in the matrix for coverage. Also added a "dynamic" option to Linux matrix as a drive-by change to make other scripting languages like Ruby / Perl testable under both static and dynamic builds. 8) Fix inaccuracy in Windows docs Python's own docs are confusing but you don't actually want to use `python3.dll` for the dynamic linkage. 9) Add generated autoconf file 10) Add v:python3_version support This variable indicates the version of Python3 that Vim was built against (PY_VERSION_HEX), and will be useful to check whether the Python library you are loading in dynamically actually fits it. When built with stable ABI, it will be the limited ABI version instead (`Py_LIMITED_API`), which indicates the minimum version of Python 3 the user should have, rather than the exact match. When stable ABI is used, we won't be exposing PY_VERSION_HEX in this var because it just doesn't seem necessary to do so (the whole point of stable ABI is the promise that it will work across versions), and I don't want to confuse the user with too many variables. Also, cleaned up some documentation, and added help tags. 11) Fix Python 3.7 compat issues Fix a couple issues when using limited API < 3.8 - Crash on exit: In Python 3.7, if a heap-allocated type is destroyed before all instances are, it would cause a crash later. This happens when we destroyed `OptionsType` before calling `Py_Finalize` when using the limited API. To make it worse, later versions changed the semantics and now each instance has a strong reference to its own type and the recommendation has changed to have each instance de-ref its own type and have its type in GC traversal. To avoid dealing with these cross-version variations, we just don't free the heap type. They are static types in non-limited-API anyway and are designed to last through the entirety of the app, and we also don't restart the Python runtime and therefore do not need it to have absolutely 0 leaks. See: - https://docs.python.org/3/whatsnew/3.8.html#changes-in-the-c-api - https://docs.python.org/3/whatsnew/3.9.html#changes-in-the-c-api - PyIter_Check: This function is not provided in limited APIs older than 3.8. Previously I was trying to mock it out using manual PyType_GetSlot() but it was brittle and also does not actually work properly for static types (it will generate a Python error). Just return false. It does mean using limited API < 3.8 is not recommended as you lose the functionality to handle iterators, but from playing with plugins I couldn't find it to be an issue. - Fix loading of PyIter_Check so it will be done when limited API < 3.8. Otherwise loading a 3.7 Python lib will fail even if limited API was specified to use it. 12) Make sure to only load `PyUnicode_AsUTF8AndSize` in needed in limited API We don't use this function unless limited API >= 3.10, but we were loading it regardless. Usually it's ok in Unix-like systems where Python just has a single lib that we load from, but in Windows where there is a separate python3.dll this would not work as the symbol would not have been exposed in this more limited DLL file. This makes it much clearer under what condition is this function needed. closes: #12032 Signed-off-by: Christian Brabandt <[email protected]> Co-authored-by: Yee Cheng Chin <[email protected]>
1 parent 20cd869 commit c13b3d1

18 files changed

+769
-153
lines changed

Diff for: .github/workflows/ci.yml

+30-3
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,15 @@ jobs:
5050
shadow: ./src/shadow
5151
- features: huge
5252
coverage: true
53+
- features: huge
54+
compiler: clang
55+
extra: none
56+
interface: dynamic
57+
python3: stable-abi
5358
- features: huge
5459
compiler: gcc
5560
coverage: true
61+
interface: dynamic
5662
extra: testgui
5763
uchar: true
5864
luaver: lua5.4
@@ -141,7 +147,16 @@ jobs:
141147
;;
142148
huge)
143149
echo "TEST=scripttests test_libvterm"
144-
echo "CONFOPT=--enable-perlinterp --enable-pythoninterp --enable-python3interp --enable-rubyinterp --enable-luainterp --enable-tclinterp"
150+
if ${{ matrix.interface == 'dynamic' }}; then
151+
if ${{ matrix.python3 == 'stable-abi' }}; then
152+
PYTHON3_FLAGS="--with-python3-stable-abi=3.8"
153+
else
154+
PYTHON3_FLAGS=""
155+
fi
156+
echo "CONFOPT=--enable-perlinterp=dynamic --enable-pythoninterp=dynamic --enable-python3interp=dynamic --enable-rubyinterp=dynamic --enable-luainterp=dynamic --enable-tclinterp=dynamic ${PYTHON3_FLAGS}"
157+
else
158+
echo "CONFOPT=--enable-perlinterp --enable-pythoninterp --enable-python3interp --enable-rubyinterp --enable-luainterp --enable-tclinterp"
159+
fi
145160
;;
146161
esac
147162
@@ -369,8 +384,8 @@ jobs:
369384
fail-fast: false
370385
matrix:
371386
include:
372-
- { features: HUGE, toolchain: msvc, VIMDLL: no, GUI: no, arch: x64 }
373-
- { features: HUGE, toolchain: mingw, VIMDLL: yes, GUI: yes, arch: x86, coverage: yes }
387+
- { features: HUGE, toolchain: msvc, VIMDLL: no, GUI: no, arch: x64, python3: stable }
388+
- { features: HUGE, toolchain: mingw, VIMDLL: yes, GUI: yes, arch: x86, python3: stable, coverage: yes }
374389
- { features: HUGE, toolchain: msvc, VIMDLL: no, GUI: yes, arch: x86 }
375390
- { features: HUGE, toolchain: mingw, VIMDLL: yes, GUI: no, arch: x64, coverage: yes }
376391
- { features: NORMAL, toolchain: msvc, VIMDLL: yes, GUI: no, arch: x86 }
@@ -501,13 +516,19 @@ jobs:
501516
) else (
502517
set GUI=${{ matrix.GUI }}
503518
)
519+
if "${{ matrix.python3 }}"=="stable" (
520+
set PYTHON3_STABLE=yes
521+
) else (
522+
set PYTHON3_STABLE=no
523+
)
504524
if "${{ matrix.features }}"=="HUGE" (
505525
nmake -nologo -f Make_mvc.mak ^
506526
FEATURES=${{ matrix.features }} ^
507527
GUI=%GUI% IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} ^
508528
DYNAMIC_LUA=yes LUA=%LUA_DIR% ^
509529
DYNAMIC_PYTHON=yes PYTHON=%PYTHON_DIR% ^
510530
DYNAMIC_PYTHON3=yes PYTHON3=%PYTHON3_DIR% ^
531+
DYNAMIC_PYTHON3_STABLE_ABI=%PYTHON3_STABLE% ^
511532
DYNAMIC_SODIUM=yes SODIUM=%SODIUM_DIR%
512533
) else (
513534
nmake -nologo -f Make_mvc.mak ^
@@ -525,13 +546,19 @@ jobs:
525546
else
526547
GUI=${{ matrix.GUI }}
527548
fi
549+
if [ "${{ matrix.python3 }}" = "stable" ]; then
550+
PYTHON3_STABLE=yes
551+
else
552+
PYTHON3_STABLE=no
553+
fi
528554
if [ "${{ matrix.features }}" = "HUGE" ]; then
529555
mingw32-make -f Make_ming.mak -j2 \
530556
FEATURES=${{ matrix.features }} \
531557
GUI=$GUI IME=yes ICONV=yes VIMDLL=${{ matrix.VIMDLL }} \
532558
DYNAMIC_LUA=yes LUA=${LUA_DIR_SLASH} \
533559
DYNAMIC_PYTHON=yes PYTHON=${PYTHON_DIR} \
534560
DYNAMIC_PYTHON3=yes PYTHON3=${PYTHON3_DIR} \
561+
DYNAMIC_PYTHON3_STABLE_ABI=${PYTHON3_STABLE} \
535562
DYNAMIC_SODIUM=yes SODIUM=${SODIUM_DIR} \
536563
STATIC_STDCPLUS=yes COVERAGE=${{ matrix.coverage }}
537564
else

Diff for: runtime/doc/builtin.txt

+1
Original file line numberDiff line numberDiff line change
@@ -10986,6 +10986,7 @@ python_dynamic Python 2.x interface is dynamically loaded. |has-python|
1098610986
python3 Python 3.x interface available. |has-python|
1098710987
python3_compiled Compiled with Python 3.x interface. |has-python|
1098810988
python3_dynamic Python 3.x interface is dynamically loaded. |has-python|
10989+
python3_stable Python 3.x interface is using Python Stable ABI. |has-python|
1098910990
pythonx Python 2.x and/or 3.x interface available. |python_x|
1099010991
qnx QNX version of Vim.
1099110992
quickfix Compiled with |quickfix| support.

Diff for: runtime/doc/eval.txt

+19
Original file line numberDiff line numberDiff line change
@@ -2424,6 +2424,25 @@ v:progpath Contains the command with which Vim was invoked, in a form
24242424
".exe" is not added to v:progpath.
24252425
Read-only.
24262426

2427+
*v:python3_version* *python3-version-variable*
2428+
v:python3_version
2429+
Version of Python 3 that Vim was built against. When
2430+
Python is loaded dynamically (|python-dynamic|), this version
2431+
should exactly match the Python library up to the minor
2432+
version (e.g. 3.10.2 and 3.10.3 are compatible as the minor
2433+
version is "10", whereas 3.9.4 and 3.10.3 are not compatible).
2434+
When |python-stable-abi| is used, this will be the minimum Python
2435+
version that you can use instead. (e.g. if v:python3_version
2436+
indicates 3.9, you can use 3.9, 3.10, or anything above).
2437+
2438+
This number is encoded as a hex number following Python ABI
2439+
versioning conventions. Do the following to have a
2440+
human-readable full version in hex: >
2441+
echo printf("%08X", v:python3_version)
2442+
< You can obtain only the minor version by doing: >
2443+
echo and(v:python3_version>>16,0xff)
2444+
< Read-only.
2445+
24272446
*v:register* *register-variable*
24282447
v:register The name of the register in effect for the current normal mode
24292448
command (regardless of whether that command actually used a

Diff for: runtime/doc/if_pyth.txt

+25-1
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,19 @@ Unix ~
769769
The 'pythondll' or 'pythonthreedll' option can be used to specify the Python
770770
shared library file instead of DYNAMIC_PYTHON_DLL or DYNAMIC_PYTHON3_DLL file
771771
what were specified at compile time. The version of the shared library must
772-
match the Python 2.x or Python 3 version Vim was compiled with.
772+
match the Python 2.x or Python 3 version (|v:python3_version|) Vim was
773+
compiled with unless using |python3-stable-abi|.
774+
775+
776+
Stable ABI and mixing Python versions ~
777+
*python-stable* *python-stable-abi* *python3-stable-abi*
778+
If Vim was not compiled with Stable ABI (only available for Python 3), the
779+
version of the Python shared library must match the version that Vim was
780+
compiled with. Otherwise, mixing versions could result in unexpected crashes
781+
and failures. With Stable ABI, this restriction is relaxed, and any Python 3
782+
library with version of at least |v:python3_version| will work. See
783+
|has-python| for how to check if Stable ABI is supported, or see if version
784+
output includes |+python3/dyn-stable|.
773785

774786
==============================================================================
775787
10. Python 3 *python3*
@@ -881,6 +893,18 @@ python support: >
881893
endif
882894
endif
883895
896+
When loading the library dynamically, Vim can be compiled to support Python 3
897+
Stable ABI (|python3-stable-abi|) which allows you to load a different version
898+
of Python 3 library than the one Vim was compiled with. To check it: >
899+
if has('python3_dynamic')
900+
if has('python3_stable')
901+
echo 'support Python 3 Stable ABI.'
902+
else
903+
echo 'does not support Python 3 Stable ABI.'
904+
echo 'only use Python 3 version ' .. v:python3_version
905+
endif
906+
endif
907+
884908
This also tells you whether Python is dynamically loaded, which will fail if
885909
the runtime library cannot be found.
886910

Diff for: runtime/doc/tags

+6
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,7 @@ $quote eval.txt /*$quote*
14341434
+python/dyn various.txt /*+python\/dyn*
14351435
+python3 various.txt /*+python3*
14361436
+python3/dyn various.txt /*+python3\/dyn*
1437+
+python3/dyn-stable various.txt /*+python3\/dyn-stable*
14371438
+quickfix various.txt /*+quickfix*
14381439
+reltime various.txt /*+reltime*
14391440
+rightleft various.txt /*+rightleft*
@@ -9294,6 +9295,8 @@ python-path_hook if_pyth.txt /*python-path_hook*
92949295
python-pyeval if_pyth.txt /*python-pyeval*
92959296
python-range if_pyth.txt /*python-range*
92969297
python-special-path if_pyth.txt /*python-special-path*
9298+
python-stable if_pyth.txt /*python-stable*
9299+
python-stable-abi if_pyth.txt /*python-stable-abi*
92979300
python-strwidth if_pyth.txt /*python-strwidth*
92989301
python-tabpage if_pyth.txt /*python-tabpage*
92999302
python-tabpages if_pyth.txt /*python-tabpages*
@@ -9306,6 +9309,8 @@ python.vim syntax.txt /*python.vim*
93069309
python2-directory if_pyth.txt /*python2-directory*
93079310
python3 if_pyth.txt /*python3*
93089311
python3-directory if_pyth.txt /*python3-directory*
9312+
python3-stable-abi if_pyth.txt /*python3-stable-abi*
9313+
python3-version-variable eval.txt /*python3-version-variable*
93099314
python_x if_pyth.txt /*python_x*
93109315
python_x-special-comments if_pyth.txt /*python_x-special-comments*
93119316
pythonx if_pyth.txt /*pythonx*
@@ -10632,6 +10637,7 @@ v:prevcount eval.txt /*v:prevcount*
1063210637
v:profiling eval.txt /*v:profiling*
1063310638
v:progname eval.txt /*v:progname*
1063410639
v:progpath eval.txt /*v:progpath*
10640+
v:python3_version eval.txt /*v:python3_version*
1063510641
v:register eval.txt /*v:register*
1063610642
v:scrollstart eval.txt /*v:scrollstart*
1063710643
v:searchforward eval.txt /*v:searchforward*

Diff for: runtime/doc/various.txt

+2
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,8 @@ m *+python* Python 2 interface |python|
450450
m *+python/dyn* Python 2 interface |python-dynamic| |/dyn|
451451
m *+python3* Python 3 interface |python|
452452
m *+python3/dyn* Python 3 interface |python-dynamic| |/dyn|
453+
m *+python3/dyn-stable*
454+
Python 3 interface |python-dynamic| |python-stable| |/dyn|
453455
N *+quickfix* |:make| and |quickfix| commands
454456
N *+reltime* |reltime()| function, 'hlsearch'/'incsearch' timeout,
455457
'redrawtime' option

Diff for: src/Make_cyg_ming.mak

+6
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ PYTHON3INC=-I $(PYTHON3)/include
412412
else
413413
PYTHON3INC=-I $(PYTHON3)/win32inc
414414
endif
415+
ifeq ($(DYNAMIC_PYTHON3_STABLE_ABI),yes)
416+
PYTHON3INC += -DPy_LIMITED_API=0x3080000
417+
endif
415418
endif
416419
endif
417420

@@ -594,6 +597,9 @@ ifdef PYTHON3
594597
CFLAGS += -DFEAT_PYTHON3
595598
ifeq (yes, $(DYNAMIC_PYTHON3))
596599
CFLAGS += -DDYNAMIC_PYTHON3 -DDYNAMIC_PYTHON3_DLL=\"$(DYNAMIC_PYTHON3_DLL)\"
600+
ifeq (yes, $(DYNAMIC_PYTHON3_STABLE_ABI))
601+
CFLAGS += -DDYNAMIC_PYTHON3_STABLE_ABI
602+
endif
597603
else
598604
CFLAGS += -DPYTHON3_DLL=\"$(DYNAMIC_PYTHON3_DLL)\"
599605
endif

Diff for: src/Make_mvc.mak

+6
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,13 @@ PYTHON3_INC = /I "$(PYTHON3)\Include" /I "$(PYTHON3)\PC"
950950
! if "$(DYNAMIC_PYTHON3)" == "yes"
951951
CFLAGS = $(CFLAGS) -DDYNAMIC_PYTHON3 \
952952
-DDYNAMIC_PYTHON3_DLL=\"$(DYNAMIC_PYTHON3_DLL)\"
953+
! if "$(DYNAMIC_PYTHON3_STABLE_ABI)" == "yes"
954+
CFLAGS = $(CFLAGS) -DDYNAMIC_PYTHON3_STABLE_ABI
955+
PYTHON3_INC = $(PYTHON3_INC) -DPy_LIMITED_API=0x3080000
956+
PYTHON3_LIB = /nodefaultlib:python3.lib
957+
! else
953958
PYTHON3_LIB = /nodefaultlib:python$(PYTHON3_VER).lib
959+
! endif
954960
! else
955961
CFLAGS = $(CFLAGS) -DPYTHON3_DLL=\"$(DYNAMIC_PYTHON3_DLL)\"
956962
PYTHON3_LIB = "$(PYTHON3)\libs\python$(PYTHON3_VER).lib"

Diff for: src/auto/configure

+45-3
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,7 @@ PYTHON3_SRC
680680
PYTHON3_CFLAGS_EXTRA
681681
PYTHON3_CFLAGS
682682
PYTHON3_LIBS
683+
vi_cv_var_python3_stable_abi
683684
vi_cv_path_python3
684685
PYTHON_OBJ
685686
PYTHON_SRC
@@ -811,6 +812,7 @@ with_python_command
811812
with_python_config_dir
812813
enable_python3interp
813814
with_python3_command
815+
with_python3_stable_abi
814816
with_python3_config_dir
815817
enable_tclinterp
816818
with_tclsh
@@ -1531,6 +1533,7 @@ Optional Packages:
15311533
--with-python-command=NAME name of the Python 2 command (default: python2 or python)
15321534
--with-python-config-dir=PATH Python's config directory (deprecated)
15331535
--with-python3-command=NAME name of the Python 3 command (default: python3 or python)
1536+
--with-python3-stable-abi=VERSION stable ABI version to target (e.g. 3.8)
15341537
--with-python3-config-dir=PATH Python's config directory (deprecated)
15351538
--with-tclsh=PATH which tclsh to use (default: tclsh8.0)
15361539
--with-ruby-command=RUBY name of the Ruby command (default: ruby)
@@ -6753,6 +6756,34 @@ $as_echo_n "checking Python is 3.0 or better... " >&6; }
67536756
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yep" >&5
67546757
$as_echo "yep" >&6; }
67556758

6759+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking --with-python3-stable-abi argument" >&5
6760+
$as_echo_n "checking --with-python3-stable-abi argument... " >&6; }
6761+
6762+
6763+
# Check whether --with-python3-stable-abi was given.
6764+
if test "${with_python3_stable_abi+set}" = set; then :
6765+
withval=$with_python3_stable_abi; vi_cv_var_python3_stable_abi="$withval"; { $as_echo "$as_me:${as_lineno-$LINENO}: result: $vi_cv_var_python3_stable_abi" >&5
6766+
$as_echo "$vi_cv_var_python3_stable_abi" >&6; }
6767+
else
6768+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
6769+
$as_echo "no" >&6; }
6770+
fi
6771+
6772+
if test "X$vi_cv_var_python3_stable_abi" != "X"; then
6773+
if ${vi_cv_var_python3_stable_abi_hex+:} false; then :
6774+
$as_echo_n "(cached) " >&6
6775+
else
6776+
6777+
vi_cv_var_python3_stable_abi_hex=`
6778+
${vi_cv_path_python3} -c \
6779+
"major_minor='${vi_cv_var_python3_stable_abi}'.split('.'); print('0x{0:X}'.format( (int(major_minor.__getitem__(0))<<24) + (int(major_minor.__getitem__(1))<<16) ))"`
6780+
fi
6781+
6782+
if test "X$vi_cv_var_python3_stable_abi_hex" == "X"; then
6783+
as_fn_error $? "can't parse Python 3 stable ABI version. It should be \"<major>.<minor>\"" "$LINENO" 5
6784+
fi
6785+
fi
6786+
67566787
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Python's abiflags" >&5
67576788
$as_echo_n "checking Python's abiflags... " >&6; }
67586789
if ${vi_cv_var_python3_abiflags+:} false; then :
@@ -6897,9 +6928,12 @@ $as_echo "$vi_cv_dll_name_python3" >&6; }
68976928
else
68986929
PYTHON3_CFLAGS="-I${vi_cv_path_python3_pfx}/include/python${vi_cv_var_python3_version}${vi_cv_var_python3_abiflags} -I${vi_cv_path_python3_epfx}/include/python${vi_cv_var_python3_version}${vi_cv_var_python3_abiflags}"
68996930
fi
6900-
if test "X$have_python3_config_dir" = "X1" -a "$enable_python3interp" = "dynamic"; then
6901-
PYTHON3_CFLAGS="${PYTHON3_CFLAGS} -DPYTHON3_HOME='L\"${vi_cv_path_python3_pfx}\"'"
6902-
fi
6931+
if test "X$have_python3_config_dir" = "X1" -a "$enable_python3interp" = "dynamic"; then
6932+
PYTHON3_CFLAGS="${PYTHON3_CFLAGS} -DPYTHON3_HOME='L\"${vi_cv_path_python3_pfx}\"'"
6933+
fi
6934+
if test "X$vi_cv_var_python3_stable_abi_hex" != "X"; then
6935+
PYTHON3_CFLAGS="${PYTHON3_CFLAGS} -DPy_LIMITED_API=${vi_cv_var_python3_stable_abi_hex}"
6936+
fi
69036937
PYTHON3_SRC="if_python3.c"
69046938
PYTHON3_OBJ="objects/if_python3.o"
69056939

@@ -7009,6 +7043,10 @@ if test "$python_ok" = yes && test "$python3_ok" = yes; then
70097043

70107044
$as_echo "#define DYNAMIC_PYTHON3 1" >>confdefs.h
70117045

7046+
if test "X$vi_cv_var_python3_stable_abi_hex" != "X"; then
7047+
$as_echo "#define DYNAMIC_PYTHON3_STABLE_ABI 1" >>confdefs.h
7048+
7049+
fi
70127050
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can do without RTLD_GLOBAL for Python" >&5
70137051
$as_echo_n "checking whether we can do without RTLD_GLOBAL for Python... " >&6; }
70147052
cflags_save=$CFLAGS
@@ -7190,6 +7228,10 @@ rm -f core conftest.err conftest.$ac_objext \
71907228
elif test "$python3_ok" = yes && test "$enable_python3interp" = "dynamic"; then
71917229
$as_echo "#define DYNAMIC_PYTHON3 1" >>confdefs.h
71927230

7231+
if test "X$vi_cv_var_python3_stable_abi_hex" != "X"; then
7232+
$as_echo "#define DYNAMIC_PYTHON3_STABLE_ABI 1" >>confdefs.h
7233+
7234+
fi
71937235
PYTHON3_SRC="if_python3.c"
71947236
PYTHON3_OBJ="objects/if_python3.o"
71957237
PYTHON3_CFLAGS="$PYTHON3_CFLAGS -DDYNAMIC_PYTHON3_DLL=\\\"${vi_cv_dll_name_python3}\\\""

Diff for: src/config.h.in

+3
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@
354354
/* Define for linking via dlopen() or LoadLibrary() */
355355
#undef DYNAMIC_PYTHON3
356356

357+
/* Define if compiled against Python 3 stable ABI / limited API */
358+
#undef DYNAMIC_PYTHON3_STABLE_ABI
359+
357360
/* Define if dynamic python does not require RTLD_GLOBAL */
358361
#undef PY_NO_RTLD_GLOBAL
359362

0 commit comments

Comments
 (0)