From: Kefu Chai Date: Fri, 28 Nov 2025 12:41:04 +0000 (+0800) Subject: pybind: replace deprecated IF statements with Tempita templates X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=719b74984605b490f23004eb41583a22c934c5fb;p=ceph.git pybind: replace deprecated IF statements with Tempita templates Replace deprecated Cython IF statements with Tempita templates to eliminate warnings and prepare for Cython 3.0+ compatibility. Cython 3.0+ produces deprecation warnings for compile-time IF statements: warning: rados.pxd:7:0: The 'IF' statement is deprecated and will be removed in a future Cython version. Consider using runtime conditions or C macros instead. See https://github.com/cython/cython/issues/4310 Changes for all modules (rados, rbd, rgw, cephfs): - Replace IF BUILD_DOC with Tempita {{if BUILD_DOC}}...{{endif}} - Add Tempita preprocessing to setup.py Changes for rados and rgw (platform-specific errno): - Replace IF UNAME_SYSNAME with Tempita - Use _nodata_errno for FreeBSD ENOATTR vs Linux ENODATA Changes for rados.pxd: - Use C preprocessor conditional (#ifndef BUILD_DOC) - Add C typedef definitions in #else branch for BUILD_DOC mode - Use quoted include path for -iquote compatibility Signed-off-by: Kefu Chai --- diff --git a/src/pybind/cephfs/cephfs.pyx b/src/pybind/cephfs/cephfs.pyx index 0aa646a463c9..301eaa689a1b 100644 --- a/src/pybind/cephfs/cephfs.pyx +++ b/src/pybind/cephfs/cephfs.pyx @@ -10,14 +10,15 @@ from libc.stdint cimport * from libc.stdlib cimport malloc, realloc, free from types cimport * -IF BUILD_DOC: - include "mock_cephfs.pxi" - cdef class Rados: - cdef: - rados_t cluster -ELSE: - from c_cephfs cimport * - from rados cimport Rados +{{if BUILD_DOC}} +include "mock_cephfs.pxi" +cdef class Rados: + cdef: + rados_t cluster +{{else}} +from c_cephfs cimport * +from rados cimport Rados +{{endif}} from collections import namedtuple, deque from datetime import datetime diff --git a/src/pybind/cephfs/setup.py b/src/pybind/cephfs/setup.py index 6195820b810c..c94ac2037ed7 100755 --- a/src/pybind/cephfs/setup.py +++ b/src/pybind/cephfs/setup.py @@ -159,6 +159,7 @@ cmdclass = {} try: from Cython.Build import cythonize from Cython.Distutils import build_ext + from Cython import Tempita cmdclass = {'build_ext': build_ext} except ImportError: @@ -173,7 +174,27 @@ except ImportError: source = "cephfs.c" else: - source = "cephfs.pyx" + # Process Tempita template + source_pyx = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "cephfs.pyx" + ) + + # Read the template from source + with open(source_pyx) as f: + template_content = f.read() + + # Process the template with cython_constants + processed = Tempita.sub(template_content, **cython_constants) + + # Write processed output to current working directory + # (which is the build directory when invoked by CMake) + output_pyx = "cephfs_processed.pyx" + + with open(output_pyx, 'w') as f: + f.write(processed) + + source = output_pyx # Disable cythonification if we're not really building anything if (len(sys.argv) >= 2 and diff --git a/src/pybind/rados/rados.pxd b/src/pybind/rados/rados.pxd index fec534e8cc70..2bcb49411833 100644 --- a/src/pybind/rados/rados.pxd +++ b/src/pybind/rados/rados.pxd @@ -4,16 +4,19 @@ # # Copyright 2016 Mehdi Abaakouk -IF BUILD_DOC: - cdef: - ctypedef void* rados_t - ctypedef void* rados_config_t - ctypedef void* rados_ioctx_t -ELSE: - cdef extern from "rados/librados.h" nogil: - ctypedef void* rados_t - ctypedef void* rados_config_t - ctypedef void* rados_ioctx_t +cdef extern from *: + """ + #ifdef BUILD_DOC + typedef void* rados_t; + typedef void* rados_config_t; + typedef void* rados_ioctx_t; + #else + #include "rados/librados.h" + #endif + """ + ctypedef void* rados_t + ctypedef void* rados_config_t + ctypedef void* rados_ioctx_t cdef class Rados(object): diff --git a/src/pybind/rados/rados.pyx b/src/pybind/rados/rados.pyx index 27fa56e5f287..48e9746161ff 100644 --- a/src/pybind/rados/rados.pyx +++ b/src/pybind/rados/rados.pyx @@ -18,10 +18,12 @@ from cpython.pycapsule cimport * from libc cimport errno from libc.stdint cimport * from libc.stdlib cimport malloc, realloc, free -IF BUILD_DOC: - include "mock_rados.pxi" -ELSE: - from c_rados cimport * + +{{if BUILD_DOC}} +include "mock_rados.pxi" +{{else}} +from c_rados cimport * +{{endif}} import threading import time @@ -232,42 +234,45 @@ class ConnectionShutdown(OSError): "RADOS connection was shutdown (%s)" % message, errno) -IF UNAME_SYSNAME == "FreeBSD": - cdef errno_to_exception = { - errno.EPERM : PermissionError, - errno.ENOENT : ObjectNotFound, - errno.EIO : IOError, - errno.ENOSPC : NoSpace, - errno.EEXIST : ObjectExists, - errno.EBUSY : ObjectBusy, - errno.ENOATTR : NoData, - errno.EINTR : InterruptedOrTimeoutError, - errno.ETIMEDOUT : TimedOut, - errno.EACCES : PermissionDeniedError, - errno.EINPROGRESS : InProgress, - errno.EISCONN : IsConnected, - errno.EINVAL : InvalidArgumentError, - errno.ENOTCONN : NotConnected, - errno.ESHUTDOWN : ConnectionShutdown, - } -ELSE: - cdef errno_to_exception = { - errno.EPERM : PermissionError, - errno.ENOENT : ObjectNotFound, - errno.EIO : IOError, - errno.ENOSPC : NoSpace, - errno.EEXIST : ObjectExists, - errno.EBUSY : ObjectBusy, - errno.ENODATA : NoData, - errno.EINTR : InterruptedOrTimeoutError, - errno.ETIMEDOUT : TimedOut, - errno.EACCES : PermissionDeniedError, - errno.EINPROGRESS : InProgress, - errno.EISCONN : IsConnected, - errno.EINVAL : InvalidArgumentError, - errno.ENOTCONN : NotConnected, - errno.ESHUTDOWN : ConnectionShutdown, - } +# Build errno mapping based on platform +# FreeBSD uses ENOATTR while Linux uses ENODATA +{{if UNAME_SYSNAME == "FreeBSD"}} +cdef errno_to_exception = { + errno.EPERM : PermissionError, + errno.ENOENT : ObjectNotFound, + errno.EIO : IOError, + errno.ENOSPC : NoSpace, + errno.EEXIST : ObjectExists, + errno.EBUSY : ObjectBusy, + errno.ENOATTR : NoData, + errno.EINTR : InterruptedOrTimeoutError, + errno.ETIMEDOUT : TimedOut, + errno.EACCES : PermissionDeniedError, + errno.EINPROGRESS : InProgress, + errno.EISCONN : IsConnected, + errno.EINVAL : InvalidArgumentError, + errno.ENOTCONN : NotConnected, + errno.ESHUTDOWN : ConnectionShutdown, +} +{{else}} +cdef errno_to_exception = { + errno.EPERM : PermissionError, + errno.ENOENT : ObjectNotFound, + errno.EIO : IOError, + errno.ENOSPC : NoSpace, + errno.EEXIST : ObjectExists, + errno.EBUSY : ObjectBusy, + errno.ENODATA : NoData, + errno.EINTR : InterruptedOrTimeoutError, + errno.ETIMEDOUT : TimedOut, + errno.EACCES : PermissionDeniedError, + errno.EINPROGRESS : InProgress, + errno.EISCONN : IsConnected, + errno.EINVAL : InvalidArgumentError, + errno.ENOTCONN : NotConnected, + errno.ESHUTDOWN : ConnectionShutdown, +} +{{endif}} cdef make_ex(ret: int, msg: str): diff --git a/src/pybind/rados/setup.py b/src/pybind/rados/setup.py index c0aa1aa73347..72cfe365dda9 100755 --- a/src/pybind/rados/setup.py +++ b/src/pybind/rados/setup.py @@ -11,6 +11,7 @@ from distutils.ccompiler import new_compiler from itertools import filterfalse, takewhile import os +import platform import shutil import sys import tempfile @@ -138,11 +139,11 @@ def check_sanity(): if 'BUILD_DOC' in os.environ or 'READTHEDOCS' in os.environ: - ext_args = {} - cython_constants = dict(BUILD_DOC=True) + ext_args = dict(extra_compile_args=['-DBUILD_DOC']) + cython_constants = dict(BUILD_DOC=True, UNAME_SYSNAME=platform.system()) elif check_sanity(): ext_args = get_python_flags(['rados']) - cython_constants = dict(BUILD_DOC=False) + cython_constants = dict(BUILD_DOC=False, UNAME_SYSNAME=platform.system()) else: sys.exit(1) @@ -150,6 +151,7 @@ cmdclass = {} try: from Cython.Build import cythonize from Cython.Distutils import build_ext + from Cython import Tempita cmdclass = {'build_ext': build_ext} except ImportError: @@ -164,7 +166,27 @@ except ImportError: source = "rados.c" else: - source = "rados.pyx" + # Process Tempita template + source_pyx = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "rados.pyx" + ) + + # Read the template from source + with open(source_pyx) as f: + template_content = f.read() + + # Process the template with cython_constants + processed = Tempita.sub(template_content, **cython_constants) + + # Write processed output to current working directory + # (which is the build directory when invoked by CMake) + output_pyx = "rados_processed.pyx" + + with open(output_pyx, 'w') as f: + f.write(processed) + + source = output_pyx # Disable cythonification if we're not really building anything if (len(sys.argv) >= 2 and diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index 2185f62e2f17..cd491213e7f8 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -34,11 +34,12 @@ import errno from itertools import chain import time -IF BUILD_DOC: - include "mock_rbd.pxi" -ELSE: - from c_rbd cimport * - cimport rados +{{if BUILD_DOC}} +include "mock_rbd.pxi" +{{else}} +from c_rbd cimport * +cimport rados +{{endif}} cdef extern from "Python.h": @@ -373,18 +374,19 @@ cdef make_ex(ret, msg, exception_map=errno_to_exception): return OSError(msg, errno=ret) -IF BUILD_DOC: - cdef rados_t convert_rados(rados) nogil: - return 0 +{{if BUILD_DOC}} +cdef rados_t convert_rados(rados) nogil: + return 0 - cdef rados_ioctx_t convert_ioctx(ioctx) nogil: - return 0 -ELSE: - cdef rados_t convert_rados(rados.Rados rados) except? NULL: - return rados.cluster +cdef rados_ioctx_t convert_ioctx(ioctx) nogil: + return 0 +{{else}} +cdef rados_t convert_rados(rados.Rados rados) except? NULL: + return rados.cluster - cdef rados_ioctx_t convert_ioctx(rados.Ioctx ioctx) except? NULL: - return ioctx.io +cdef rados_ioctx_t convert_ioctx(rados.Ioctx ioctx) except? NULL: + return ioctx.io +{{endif}} cdef int progress_callback(uint64_t offset, uint64_t total, void* ptr) with gil: return (ptr)(offset, total) diff --git a/src/pybind/rbd/setup.py b/src/pybind/rbd/setup.py index c59c4e8f789e..f5e654287c5d 100755 --- a/src/pybind/rbd/setup.py +++ b/src/pybind/rbd/setup.py @@ -160,6 +160,7 @@ try: from Cython.Build import cythonize from Cython.Distutils import build_ext from Cython import __version__ as cython_version + from Cython import Tempita cmdclass = {'build_ext': build_ext} @@ -183,7 +184,25 @@ except ImportError: source = "rbd.c" else: - source = "rbd.pyx" + # Process Tempita template + source_pyx = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "rbd.pyx" + ) + + # Read the template from source + with open(source_pyx) as f: + template_content = f.read() + + # Process the template with cython_constants + processed = Tempita.sub(template_content, **cython_constants) + + # Write processed output to current working directory + # (which is the build directory when invoked by CMake) + source = "rbd_processed.pyx" + + with open(source, 'w') as f: + f.write(processed) # Disable cythonification if we're not really building anything if (len(sys.argv) >= 2 and diff --git a/src/pybind/rgw/rgw.pyx b/src/pybind/rgw/rgw.pyx index 6da956e2d96f..a2689d931858 100644 --- a/src/pybind/rgw/rgw.pyx +++ b/src/pybind/rgw/rgw.pyx @@ -9,11 +9,12 @@ from libc.stdlib cimport malloc, realloc, free from cstat cimport stat cimport libcpp -IF BUILD_DOC: - include "mock_rgw.pxi" -ELSE: - from c_rgw cimport * - cimport rados +{{if BUILD_DOC}} +include "mock_rgw.pxi" +{{else}} +from c_rgw cimport * +cimport rados +{{endif}} from collections import namedtuple from datetime import datetime @@ -90,32 +91,36 @@ class WouldBlock(Error): class OutOfRange(Error): pass -IF UNAME_SYSNAME == "FreeBSD": - cdef errno_to_exception = { - errno.EPERM : PermissionError, - errno.ENOENT : ObjectNotFound, - errno.EIO : IOError, - errno.ENOSPC : NoSpace, - errno.EEXIST : ObjectExists, - errno.ENOATTR : NoData, - errno.EINVAL : InvalidValue, - errno.EOPNOTSUPP : OperationNotSupported, - errno.ERANGE : OutOfRange, - errno.EWOULDBLOCK: WouldBlock, - } -ELSE: - cdef errno_to_exception = { - errno.EPERM : PermissionError, - errno.ENOENT : ObjectNotFound, - errno.EIO : IOError, - errno.ENOSPC : NoSpace, - errno.EEXIST : ObjectExists, - errno.ENODATA : NoData, - errno.EINVAL : InvalidValue, - errno.EOPNOTSUPP : OperationNotSupported, - errno.ERANGE : OutOfRange, - errno.EWOULDBLOCK: WouldBlock, - } + +# Build errno mapping based on platform +# FreeBSD uses ENOATTR while Linux uses ENODATA +{{if UNAME_SYSNAME == "FreeBSD"}} +cdef errno_to_exception = { + errno.EPERM : PermissionError, + errno.ENOENT : ObjectNotFound, + errno.EIO : IOError, + errno.ENOSPC : NoSpace, + errno.EEXIST : ObjectExists, + errno.ENOATTR : NoData, + errno.EINVAL : InvalidValue, + errno.EOPNOTSUPP : OperationNotSupported, + errno.ERANGE : OutOfRange, + errno.EWOULDBLOCK: WouldBlock, +} +{{else}} +cdef errno_to_exception = { + errno.EPERM : PermissionError, + errno.ENOENT : ObjectNotFound, + errno.EIO : IOError, + errno.ENOSPC : NoSpace, + errno.EEXIST : ObjectExists, + errno.ENODATA : NoData, + errno.EINVAL : InvalidValue, + errno.EOPNOTSUPP : OperationNotSupported, + errno.ERANGE : OutOfRange, + errno.EWOULDBLOCK: WouldBlock, +} +{{endif}} cdef class FileHandle(object): diff --git a/src/pybind/rgw/setup.py b/src/pybind/rgw/setup.py index f48e8550c0b2..8b9b9ac1fef2 100755 --- a/src/pybind/rgw/setup.py +++ b/src/pybind/rgw/setup.py @@ -141,13 +141,15 @@ def check_sanity(): shutil.rmtree(tmp_dir) +import platform + if 'BUILD_DOC' in os.environ or 'READTHEDOCS' in os.environ: ext_args = {} - cython_constants = dict(BUILD_DOC=True) + cython_constants = dict(BUILD_DOC=True, UNAME_SYSNAME=platform.system()) cythonize_args = dict(compile_time_env=cython_constants) elif check_sanity(): ext_args = get_python_flags(['rados', 'rgw']) - cython_constants = dict(BUILD_DOC=False) + cython_constants = dict(BUILD_DOC=False, UNAME_SYSNAME=platform.system()) include_path = [os.path.join(os.path.dirname(__file__), "..", "rados")] cythonize_args = dict(compile_time_env=cython_constants, include_path=include_path) @@ -158,6 +160,7 @@ cmdclass = {} try: from Cython.Build import cythonize from Cython.Distutils import build_ext + from Cython import Tempita cmdclass = {'build_ext': build_ext} except ImportError: @@ -172,7 +175,27 @@ except ImportError: source = "rgw.c" else: - source = "rgw.pyx" + # Process Tempita template + source_pyx = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "rgw.pyx" + ) + + # Read the template from source + with open(source_pyx) as f: + template_content = f.read() + + # Process the template with cython_constants + processed = Tempita.sub(template_content, **cython_constants) + + # Write processed output to current working directory + # (which is the build directory when invoked by CMake) + output_pyx = "rgw_processed.pyx" + + with open(output_pyx, 'w') as f: + f.write(processed) + + source = output_pyx # Disable cythonification if we're not really building anything if (len(sys.argv) >= 2 and