From 56df09dbc846d6bcea4e1364a045b371bc1921f5 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Thu, 22 Jan 2026 20:06:58 +0800 Subject: [PATCH] pybind: add legacy_implicit_noexcept for Cython 3.x compatibility Add legacy_implicit_noexcept compiler directive to all pybind modules (rados, cephfs, rbd, rgw) when building with Cython 3.x. This maintains compatibility with Cython 0.29 (Ubuntu Jammy) by allowing callback functions to work without explicit noexcept declarations. Cython 3.x requires explicit noexcept declarations for callback functions, but Cython 0.29 doesn't support the noexcept keyword. The legacy_implicit_noexcept directive tells Cython 3.x to use the old behavior, allowing the same code to work with both versions. This fixes errors like: Cannot assign type 'int (*)(uint64_t, uint64_t, void *) except? -1' to 'librbd_progress_fn_t'. Exception values are incompatible. And warnings like: performance hint: Exception check on '__aio_complete_cb' will always require the GIL to be acquired. The rbd module already had this directive, but rados, cephfs, and rgw were missing it. Signed-off-by: Kefu Chai --- src/pybind/cephfs/setup.py | 11 ++++++++++- src/pybind/rados/setup.py | 12 ++++++++++-- src/pybind/rgw/setup.py | 11 ++++++++++- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/pybind/cephfs/setup.py b/src/pybind/cephfs/setup.py index c94ac2037ed..bff66659da3 100755 --- a/src/pybind/cephfs/setup.py +++ b/src/pybind/cephfs/setup.py @@ -156,12 +156,21 @@ else: sys.exit(1) cmdclass = {} +compiler_directives = {'language_level': sys.version_info.major} try: from Cython.Build import cythonize from Cython.Distutils import build_ext from Cython import Tempita + from Cython import __version__ as cython_version + from packaging import version cmdclass = {'build_ext': build_ext} + + # Enable legacy_implicit_noexcept for Cython 3.x to maintain compatibility + # with Cython 0.29 (Ubuntu Jammy). This allows callback functions to work + # without explicit noexcept declarations. + if version.parse(cython_version) >= version.parse('3'): + compiler_directives['legacy_implicit_noexcept'] = True except ImportError: print("WARNING: Cython is not installed.") @@ -226,7 +235,7 @@ setup( **ext_args ) ], - compiler_directives={'language_level': sys.version_info.major}, + compiler_directives=compiler_directives, build_dir=os.environ.get("CYTHON_BUILD_DIR", None), **cythonize_args ), diff --git a/src/pybind/rados/setup.py b/src/pybind/rados/setup.py index 72cfe365dda..34218fe2125 100755 --- a/src/pybind/rados/setup.py +++ b/src/pybind/rados/setup.py @@ -148,12 +148,21 @@ else: sys.exit(1) cmdclass = {} +compiler_directives = {'language_level': sys.version_info.major} try: from Cython.Build import cythonize from Cython.Distutils import build_ext from Cython import Tempita + from Cython import __version__ as cython_version + from packaging import version cmdclass = {'build_ext': build_ext} + + # Enable legacy_implicit_noexcept for Cython 3.x to maintain compatibility + # with Cython 0.29 (Ubuntu Jammy). This allows callback functions to work + # without explicit noexcept declarations. + if version.parse(cython_version) >= version.parse('3'): + compiler_directives['legacy_implicit_noexcept'] = True except ImportError: print("WARNING: Cython is not installed.") @@ -217,8 +226,7 @@ setup( **ext_args ) ], - # use "3str" when Cython 3.0 is available - compiler_directives={'language_level': sys.version_info.major}, + compiler_directives=compiler_directives, compile_time_env=cython_constants, build_dir=os.environ.get("CYTHON_BUILD_DIR", None), ), diff --git a/src/pybind/rgw/setup.py b/src/pybind/rgw/setup.py index 8b9b9ac1fef..54fbd8b0f42 100755 --- a/src/pybind/rgw/setup.py +++ b/src/pybind/rgw/setup.py @@ -157,12 +157,21 @@ else: sys.exit(1) cmdclass = {} +compiler_directives = {'language_level': sys.version_info.major} try: from Cython.Build import cythonize from Cython.Distutils import build_ext from Cython import Tempita + from Cython import __version__ as cython_version + from packaging import version cmdclass = {'build_ext': build_ext} + + # Enable legacy_implicit_noexcept for Cython 3.x to maintain compatibility + # with Cython 0.29 (Ubuntu Jammy). This allows callback functions to work + # without explicit noexcept declarations. + if version.parse(cython_version) >= version.parse('3'): + compiler_directives['legacy_implicit_noexcept'] = True except ImportError: print("WARNING: Cython is not installed.") @@ -226,7 +235,7 @@ setup( **ext_args ) ], - compiler_directives={'language_level': sys.version_info.major}, + compiler_directives=compiler_directives, build_dir=os.environ.get("CYTHON_BUILD_DIR", None), **cythonize_args ), -- 2.47.3