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+.
diff --git a/lib/cpp/CMakeLists.txt b/lib/cpp/CMakeLists.txt
index 5980734..d189922 100644
--- a/lib/cpp/CMakeLists.txt
+++ b/lib/cpp/CMakeLists.txt
@@ -178,6 +178,9 @@
else()
target_link_libraries(thriftnb PUBLIC ${LIBEVENT_LIBRARIES})
endif()
+ if(WIN32)
+ target_link_libraries(thriftnb PUBLIC iphlpapi)
+ endif()
ADD_PKGCONFIG_THRIFT(thrift-nb)
endif()
diff --git a/lib/nodejs/test/package-lock.json b/lib/nodejs/test/package-lock.json
index e7f9543..6faee9d 100644
--- a/lib/nodejs/test/package-lock.json
+++ b/lib/nodejs/test/package-lock.json
@@ -9,7 +9,7 @@
}
},
"../../..": {
- "version": "0.22.0",
+ "version": "0.23.0",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
diff --git a/lib/py/pyproject.toml b/lib/py/pyproject.toml
new file mode 100644
index 0000000..b61373e
--- /dev/null
+++ b/lib/py/pyproject.toml
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools>=61.0", "wheel"]
+build-backend = "setuptools.build_meta"
diff --git a/lib/py/setup.py b/lib/py/setup.py
index a02cc4f..2dd2a77 100644
--- a/lib/py/setup.py
+++ b/lib/py/setup.py
@@ -20,13 +20,10 @@
#
import sys
-try:
- from setuptools import setup, Extension
-except Exception:
- from distutils.core import setup, Extension
-from distutils.command.build_ext import build_ext
-from distutils.errors import CCompilerError, DistutilsExecError, DistutilsPlatformError
+from setuptools import Extension, setup
+from setuptools.command.build_ext import build_ext
+from setuptools.errors import CompileError, ExecError, PlatformError
# Fix to build sdist under vagrant
import os
@@ -39,9 +36,9 @@
include_dirs = ['src']
if sys.platform == 'win32':
include_dirs.append('compat/win32')
- ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError, IOError)
+ ext_errors = (CompileError, ExecError, PlatformError, IOError)
else:
- ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError)
+ ext_errors = (CompileError, ExecError, PlatformError)
class BuildFailed(Exception):
@@ -52,7 +49,7 @@
def run(self):
try:
build_ext.run(self)
- except DistutilsPlatformError:
+ except PlatformError:
raise BuildFailed()
def build_extension(self, ext):
@@ -99,8 +96,8 @@
ssl_deps = []
if sys.hexversion < 0x03050000:
ssl_deps.append('backports.ssl_match_hostname>=3.5')
- tornado_deps = ['tornado>=4.0']
- twisted_deps = ['twisted']
+ tornado_deps = ['tornado>=6.3.0']
+ twisted_deps = ['twisted>=24.3.0', 'zope.interface>=6.1']
setup(name='thrift',
version='0.23.0',
diff --git a/lib/py/src/ext/endian.h b/lib/py/src/ext/endian.h
index 8f9e978..bf21a4f 100644
--- a/lib/py/src/ext/endian.h
+++ b/lib/py/src/ext/endian.h
@@ -29,6 +29,7 @@
#else
#include <netinet/in.h>
+#ifndef ntohll
static inline unsigned long long ntohll(unsigned long long n) {
union {
unsigned long long f;
@@ -43,8 +44,11 @@
| static_cast<unsigned long long>(u.t[5]) << 16
| static_cast<unsigned long long>(u.t[6]) << 8 | static_cast<unsigned long long>(u.t[7]);
}
+#endif
+#ifndef htonll
#define htonll(n) ntohll(n)
+#endif
#endif // !_WIN32
diff --git a/lib/py/test/test_socket.py b/lib/py/test/test_socket.py
index af09515..5e25f1a 100644
--- a/lib/py/test/test_socket.py
+++ b/lib/py/test/test_socket.py
@@ -18,6 +18,7 @@
#
import errno
+import time
import unittest
from test_sslsocket import ServerAcceptor
@@ -98,7 +99,11 @@
acc.close()
self.assertIsNotNone(sock.handle)
- self.assertFalse(sock.isOpen())
+ # Give the kernel a moment to propagate FIN before asserting.
+ deadline = time.monotonic() + 0.5
+ while sock.isOpen() and time.monotonic() < deadline:
+ time.sleep(0.01)
+ self.assertFalse(sock.isOpen(), "socket still open after 0.5s")
# after isOpen() returned False the socket should be closed (THRIFT-5813)
self.assertIsNone(sock.handle)