Skip to content

Commit 62ec929

Browse files
authored
Fix Python 3.12 build issues in thrift Python (#3276)
- Add pyproject.toml with setuptools build requirement for PEP 517 compliance - Replace distutils imports with setuptools equivalents - Use setuptools error names directly (CompileError, ExecError, PlatformError) - Fix macOS header collision with ntohll/htonll macros in endian.h - Add a matrix of MacOS versions (macos-15-intel, macos-14, macos-15, macos-26) - Add a matrix of non-EOL Python versions for testing - Remove MSVC2015 from the test matrix (very old). - Support MSVC2022, the latest in AppVeyor. - Upgrade tornado, twisted, and zope.interface versions to the first that support Python 3.12. - Try to make the test_socket, RunClientServer, and TestServer tests less flaky. This fixes the ModuleNotFoundError: No module named 'distutils' error when building thrift with Python 3.12+.
1 parent dbdb429 commit 62ec929

20 files changed

Lines changed: 305 additions & 100 deletions

File tree

.github/workflows/build.yml

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,42 @@ jobs:
7878
path: compiler/cpp/thrift
7979
retention-days: 3
8080

81+
compiler-macos:
82+
strategy:
83+
matrix:
84+
os: &macos_versions [macos-15-intel, macos-14, macos-15, macos-26]
85+
fail-fast: false
86+
runs-on: ${{ matrix.os }}
87+
steps:
88+
- uses: actions/checkout@v6
89+
90+
- name: Install dependencies
91+
run: |
92+
brew install automake bison flex boost libevent openssl libtool pkg-config
93+
echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH
94+
95+
- name: Run bootstrap
96+
run: ./bootstrap.sh
97+
98+
- name: Run configure
99+
run: ./configure --disable-debug --disable-tests --disable-libs
100+
101+
- name: Run make
102+
run: make -j$(sysctl -n hw.ncpu)
103+
104+
- name: Run install
105+
run: sudo make install
106+
107+
- name: Run thrift version
108+
run: /usr/local/bin/thrift -version
109+
110+
- name: Archive built thrift compiler (macOS)
111+
uses: actions/upload-artifact@v5
112+
with:
113+
name: thrift-compiler-${{ matrix.os }}
114+
path: compiler/cpp/thrift
115+
retention-days: 3
116+
81117
lib-php:
82118
needs: compiler
83119
runs-on: ubuntu-24.04
@@ -495,8 +531,7 @@ jobs:
495531
runs-on: ubuntu-24.04
496532
strategy:
497533
matrix:
498-
python-version:
499-
- "3.13" # Pin to 3.13 for now -> see THRIFT-5900
534+
python-version: &python_versions ["3.10", "3.11", "3.12", "3.13", "3.14"]
500535
fail-fast: false
501536
steps:
502537
- uses: actions/checkout@v6
@@ -514,7 +549,7 @@ jobs:
514549

515550
- name: Python setup
516551
run: |
517-
python -m pip install --upgrade pip setuptools wheel flake8 tornado twisted zope.interface
552+
python -m pip install --upgrade pip setuptools wheel flake8 "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1"
518553
python --version
519554
pip --version
520555
@@ -553,6 +588,65 @@ jobs:
553588
- name: Run make check for python code
554589
run: make -C test/py check
555590

591+
lib-python-macos:
592+
needs: compiler-macos
593+
strategy:
594+
matrix:
595+
os: *macos_versions
596+
python-version: *python_versions
597+
fail-fast: false
598+
runs-on: ${{ matrix.os }}
599+
steps:
600+
- uses: actions/checkout@v6
601+
602+
- name: Install dependencies
603+
run: |
604+
brew install automake bison flex boost libevent openssl libtool pkg-config
605+
echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH
606+
607+
- name: Set up Python
608+
uses: actions/setup-python@v6
609+
with:
610+
python-version: ${{ matrix.python-version }}
611+
612+
- name: Python setup
613+
run: |
614+
python -m pip install --upgrade pip setuptools wheel flake8 "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1"
615+
python --version
616+
pip --version
617+
618+
- name: Run bootstrap
619+
run: ./bootstrap.sh
620+
621+
- name: Run configure
622+
run: ./configure $(echo $CONFIG_ARGS_FOR_LIBS | sed 's/without-py3/with-py3/')
623+
624+
- uses: actions/download-artifact@v6
625+
with:
626+
name: thrift-compiler-${{ matrix.os }}
627+
path: compiler/cpp
628+
629+
- name: Run thrift-compiler
630+
run: |
631+
chmod a+x compiler/cpp/thrift
632+
compiler/cpp/thrift -version
633+
634+
- name: Run make for python
635+
run: make -C lib/py
636+
637+
- name: Run make install for python
638+
run: |
639+
sudo make -C lib/py install PY_PREFIX="$(python -c 'import sys; print(sys.prefix)')"
640+
641+
- name: Run make for python libs
642+
run: make -C lib/py
643+
644+
- name: Run make check for python libs
645+
run: make -C lib/py check
646+
647+
- name: Run make check for python code
648+
run: make -C test/py check
649+
556650
lib-nodejs:
557651
needs: compiler
558652
runs-on: ubuntu-24.04

appveyor.yml

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,31 +33,70 @@ branches:
3333
#matrix:
3434
# fast_finish: true
3535

36+
# See https://www.appveyor.com/docs/windows-images-software/ for available versions.
37+
3638
environment:
3739
matrix:
38-
- PROFILE: MSVC2017
40+
# Python version test matrix (3.10-3.14) using MSVC2022
41+
- PROFILE: MSVC2022
42+
PROFILE_CLASS: MSVC
43+
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
44+
PLATFORM: x64
45+
CONFIGURATION: Release
46+
BUILD_SHARED_LIBS: ON
47+
BOOST_VERSION: 1.89.0
48+
LIBEVENT_VERSION: 2.1.12
49+
PYTHON_VERSION: "3.10"
50+
QT_VERSION: 6.9.3
51+
ZLIB_VERSION: 1.3.1
52+
53+
- PROFILE: MSVC2022
3954
PROFILE_CLASS: MSVC
40-
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
55+
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
4156
PLATFORM: x64
4257
CONFIGURATION: Release
4358
BUILD_SHARED_LIBS: ON
44-
BOOST_VERSION: 1.67.0
45-
LIBEVENT_VERSION: 2.1.8
46-
PYTHON_VERSION: 3.6
47-
QT_VERSION: 5.10
48-
ZLIB_VERSION: 1.2.11
59+
BOOST_VERSION: 1.89.0
60+
LIBEVENT_VERSION: 2.1.12
61+
PYTHON_VERSION: "3.11"
62+
QT_VERSION: 6.9.3
63+
ZLIB_VERSION: 1.3.1
4964

50-
- PROFILE: MSVC2015
65+
- PROFILE: MSVC2022
5166
PROFILE_CLASS: MSVC
52-
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
53-
PLATFORM: x86
54-
CONFIGURATION: Debug
55-
BUILD_SHARED_LIBS: OFF
56-
BOOST_VERSION: 1.62.0
57-
LIBEVENT_VERSION: 2.0.22
58-
PYTHON_VERSION: 3.5
59-
QT_VERSION: 5.8
60-
ZLIB_VERSION: 1.2.8
67+
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
68+
PLATFORM: x64
69+
CONFIGURATION: Release
70+
BUILD_SHARED_LIBS: ON
71+
BOOST_VERSION: 1.89.0
72+
LIBEVENT_VERSION: 2.1.12
73+
PYTHON_VERSION: "3.12"
74+
QT_VERSION: 6.9.3
75+
ZLIB_VERSION: 1.3.1
76+
77+
- PROFILE: MSVC2022
78+
PROFILE_CLASS: MSVC
79+
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
80+
PLATFORM: x64
81+
CONFIGURATION: Release
82+
BUILD_SHARED_LIBS: ON
83+
BOOST_VERSION: 1.89.0
84+
LIBEVENT_VERSION: 2.1.12
85+
PYTHON_VERSION: "3.13"
86+
QT_VERSION: 6.9.3
87+
ZLIB_VERSION: 1.3.1
88+
89+
- PROFILE: MSVC2022
90+
PROFILE_CLASS: MSVC
91+
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
92+
PLATFORM: x64
93+
CONFIGURATION: Release
94+
BUILD_SHARED_LIBS: ON
95+
BOOST_VERSION: 1.89.0
96+
LIBEVENT_VERSION: 2.1.12
97+
PYTHON_VERSION: "3.14"
98+
QT_VERSION: 6.9.3
99+
ZLIB_VERSION: 1.3.1
61100

62101
- PROFILE: MINGW
63102
PROFILE_CLASS: MINGW

build/appveyor/MSVC-appveyor-full.bat

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,7 @@ SET INSTDIR=%APPVEYOR_BUILD_FOLDER%\..\install\%PROFILE%\%PLATFORM%
3131
SET SRCDIR=%APPVEYOR_BUILD_FOLDER%
3232

3333

34-
IF "%PROFILE%" == "MSVC2015" (
35-
IF "%PLATFORM%" == "x86" (
36-
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 || EXIT /B
37-
) ELSE (
38-
CALL "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 || EXIT /B
39-
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 || EXIT /B
40-
)
41-
) ELSE IF "%PROFILE%" == "MSVC2017" (
34+
IF "%PROFILE%" == "MSVC2017" (
4235
IF "%PLATFORM%" == "x86" (
4336
CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat" || EXIT /B
4437
) ELSE (
@@ -50,6 +43,12 @@ IF "%PROFILE%" == "MSVC2015" (
5043
) ELSE (
5144
CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" || EXIT /B
5245
)
46+
) ELSE IF "%PROFILE%" == "MSVC2022" (
47+
IF "%PLATFORM%" == "x86" (
48+
CALL "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat" || EXIT /B
49+
) ELSE (
50+
CALL "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" || EXIT /B
51+
)
5352
) ELSE (
5453
ECHO Unsupported PROFILE=%PROFILE% or PLATFORM=%PLATFORM%
5554
EXIT /B 1
@@ -59,16 +58,24 @@ IF "%PROFILE%" == "MSVC2015" (
5958
@ECHO ON
6059

6160
:: compiler and generator detection
62-
IF /i "%PLATFORM%" == "x64" SET GENARCH= Win64
63-
IF "%PROFILE%" == "MSVC2015" (
64-
SET GENERATOR=Visual Studio 14 2015!GENARCH!
65-
SET COMPILER=vc140
66-
) ELSE IF "%PROFILE%" == "MSVC2017" (
61+
:: VS2017 uses "Generator Win64" syntax, VS2019+ use "-A x64" flag
62+
IF /i "%PLATFORM%" == "x64" (
63+
SET GENARCH= Win64
64+
SET CMAKE_ARCH_FLAG=-A x64
65+
) ELSE (
66+
SET GENARCH=
67+
SET CMAKE_ARCH_FLAG=-A Win32
68+
)
69+
IF "%PROFILE%" == "MSVC2017" (
6770
SET GENERATOR=Visual Studio 15 2017!GENARCH!
6871
SET COMPILER=vc141
72+
SET CMAKE_ARCH_FLAG=
6973
) ELSE IF "%PROFILE%" == "MSVC2019" (
70-
SET GENERATOR=Visual Studio 16 2019!GENARCH!
74+
SET GENERATOR=Visual Studio 16 2019
7175
SET COMPILER=vc142
76+
) ELSE IF "%PROFILE%" == "MSVC2022" (
77+
SET GENERATOR=Visual Studio 17 2022
78+
SET COMPILER=vc143
7279
) ELSE (
7380
ECHO [error] unable to determine the CMake generator and compiler to use from MSVC profile %PROFILE%
7481
EXIT /B 1
@@ -96,7 +103,7 @@ IF "%PYTHON_VERSION%" == "" (
96103
IF /i "%PLATFORM%" == "x64" (SET PTEXT=-x64)
97104
SET PYTHON_ROOT=C:\Python%PYTHON_VERSION:.=%!PTEXT!
98105
SET PATH=!PYTHON_ROOT!\scripts;!PYTHON_ROOT!;!PATH!
99-
SET CMAKE_PYTHON_OPTS=-DPython3_FIND_STRATEGY=LOCATION -DPython3_ROOT=!PYTHON_ROOT!
106+
SET CMAKE_PYTHON_OPTS=-DPython3_FIND_STRATEGY=LOCATION -DPython3_ROOT=!PYTHON_ROOT! -DPython3_EXECUTABLE=!PYTHON_ROOT!\python.exe
100107
)
101108

102109
IF "%CONFIGURATION%" == "Debug" (SET ZLIB_LIB_SUFFIX=d)
@@ -115,15 +122,15 @@ choco feature enable -n allowGlobalConfirmation || EXIT /B
115122

116123
:: Things to install when NOT running in appveyor:
117124
IF "%APPVEYOR_BUILD_ID%" == "" (
118-
cup -y chocolatey || EXIT /B
119-
cinst -y curl || EXIT /B
120-
cinst -y 7zip || EXIT /B
121-
cinst -y python3 || EXIT /B
122-
cinst -y openssl.light || EXIT /B
125+
choco upgrade -y chocolatey || EXIT /B
126+
choco install -y curl || EXIT /B
127+
choco install -y 7zip || EXIT /B
128+
choco install -y python3 || EXIT /B
129+
choco install -y openssl.light || EXIT /B
123130
)
124131

125-
cinst -y jdk8 || EXIT /B
126-
cinst -y winflexbison3 || EXIT /B
132+
choco install -y jdk8 || EXIT /B
133+
choco install -y winflexbison3 || EXIT /B
127134

128135
:: zlib - not available through chocolatey
129136
CD "%APPVEYOR_SCRIPTS%" || EXIT /B
@@ -133,12 +140,17 @@ call build-zlib.bat || EXIT /B
133140
CD "%APPVEYOR_SCRIPTS%" || EXIT /B
134141
call build-libevent.bat || EXIT /B
135142

136-
:: python packages (correct path to pip set above)
137-
pip.exe ^
138-
install backports.ssl_match_hostname ^
139-
ipaddress ^
140-
tornado ^
141-
twisted || EXIT /B
143+
:: python packages (ensure we use the configured Python)
144+
IF "%WITH_PYTHON%" == "ON" (
145+
"!PYTHON_ROOT!\python.exe" -m ensurepip --upgrade || EXIT /B
146+
"!PYTHON_ROOT!\python.exe" -m pip install --upgrade pip setuptools wheel || EXIT /B
147+
"!PYTHON_ROOT!\python.exe" -m pip ^
148+
install backports.ssl_match_hostname ^
149+
ipaddress ^
150+
tornado>=6.3.0 ^
151+
twisted>=24.3.0 ^
152+
zope.interface>=6.1 || EXIT /B
153+
)
142154

143155
:: Adobe Flex SDK 4.6 for ActionScript
144156
MKDIR "C:\Adobe\Flex\SDK\4.6" || EXIT /B
@@ -171,7 +183,7 @@ CD "%BUILDDIR%" || EXIT /B
171183
:: DIR C:\Libraries\boost_1_60_0\lib*
172184

173185
cmake.exe "%SRCDIR%" ^
174-
-G"%GENERATOR%" ^
186+
-G"%GENERATOR%" %CMAKE_ARCH_FLAG% ^
175187
-DBISON_EXECUTABLE="C:\ProgramData\chocolatey\lib\winflexbison3\tools\win_bison.exe" ^
176188
-DBOOST_ROOT="%BOOST_ROOT%" ^
177189
-DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" ^

build/appveyor/build-libevent.bat

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ IF "%APPVEYOR_BUILD_ID%" == "" (
2626
)
2727
7z x "%URLFILE%" -so | 7z x -si -ttar > nul || EXIT /B
2828
CD "libevent-%LIBEVENT_VERSION%-stable" || EXIT /B
29+
:: libevent's nmake config ships with EVENT__HAVE_STDINT_H commented out,
30+
:: but MSVC needs stdint.h for UINT32_MAX in minheap-internal.h.
31+
IF EXIST "WIN32-Code\nmake\event2\event-config.h" (
32+
powershell -NoProfile -Command "(Get-Content 'WIN32-Code\nmake\event2\event-config.h') -replace '/\* #define EVENT__HAVE_STDINT_H 1 \*/', '#define EVENT__HAVE_STDINT_H 1' | Set-Content 'WIN32-Code\nmake\event2\event-config.h'"
33+
) ELSE IF EXIST "WIN32-Code\event2\event-config.h" (
34+
powershell -NoProfile -Command "(Get-Content 'WIN32-Code\event2\event-config.h') -replace '/\* #define EVENT__HAVE_STDINT_H 1 \*/', '#define EVENT__HAVE_STDINT_H 1' | Set-Content 'WIN32-Code\event2\event-config.h'"
35+
)
2936
nmake -f Makefile.nmake static_libs || EXIT /B
3037

3138
:: in libevent 2.0 there is no nmake subdirectory in WIN32-Code, but in 2.1 there is

build/cmake/BoostMacros.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ if(POLICY CMP0167)
2323
cmake_policy(SET CMP0167 OLD)
2424
endif()
2525

26+
# CMake 3.27+ warns and ignores upper-case <PACKAGENAME>_ROOT variables unless
27+
# CMP0144 is set. We pass BOOST_ROOT on Windows builds, so enable NEW behavior.
28+
if(POLICY CMP0144)
29+
cmake_policy(SET CMP0144 NEW)
30+
endif()
31+
2632
# Force using FindBoost instead of Boost's own BoostConfig.cmake.
2733
# BoostConfig.cmake does not populate ${Boost_LIBRARIES} the same way,
2834
# which causes linking failures on Windows.

build/docker/ubuntu-focal/Dockerfile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,9 @@ RUN apt-get install -y --no-install-recommends \
261261
python3-all-dev \
262262
python3-pip \
263263
python3-setuptools \
264-
python3-tornado \
265-
python3-twisted \
266-
python3-wheel \
267-
python3-zope.interface
264+
python3-wheel
265+
266+
RUN python3 -m pip install --no-cache-dir --upgrade "tornado>=6.3.0" "twisted>=24.3.0" "zope.interface>=6.1"
268267

269268
RUN apt-get install -y --no-install-recommends \
270269
`# Ruby dependencies` \

0 commit comments

Comments
 (0)