]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind: replace deprecated IF statements with Tempita templates 66447/head
authorKefu Chai <k.chai@proxmox.com>
Fri, 28 Nov 2025 12:41:04 +0000 (20:41 +0800)
committerKefu Chai <k.chai@proxmox.com>
Wed, 24 Dec 2025 10:59:16 +0000 (18:59 +0800)
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 <k.chai@proxmox.com>
src/pybind/cephfs/cephfs.pyx
src/pybind/cephfs/setup.py
src/pybind/rados/rados.pxd
src/pybind/rados/rados.pyx
src/pybind/rados/setup.py
src/pybind/rbd/rbd.pyx
src/pybind/rbd/setup.py
src/pybind/rgw/rgw.pyx
src/pybind/rgw/setup.py

index 0aa646a463c9cec77eda32fe3484e48e4be2f1ec..301eaa689a1be832b52119635ea2f81c26fd117c 100644 (file)
@@ -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
index 6195820b810c5950396ab30c622cd75660ecf735..c94ac2037ed7e615d7cec4127a77f3e32dc3c5dd 100755 (executable)
@@ -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
index fec534e8cc70936ecb23b3835ba12e1aa70bf4f6..2bcb49411833f1c677dba3f4b43b44c56a74f1b2 100644 (file)
@@ -4,16 +4,19 @@
 #
 # Copyright 2016 Mehdi Abaakouk <sileht@redhat.com>
 
-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):
index 27fa56e5f28793cceb8c05c92ab232e88b5beaa9..48e9746161ff908077bd375d782b319bcf88e94c 100644 (file)
@@ -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):
index c0aa1aa733473cda863b4f204ec731012170138d..72cfe365dda9c04c83201fdd307d0b963f0f4562 100755 (executable)
@@ -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
index 2185f62e2f179e226b038e19fc4c9f34e0574087..cd491213e7f86add25fc8ebef44dd2469d235bd4 100644 (file)
@@ -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 <rados_t>0
+{{if BUILD_DOC}}
+cdef rados_t convert_rados(rados) nogil:
+    return <rados_t>0
 
-    cdef rados_ioctx_t convert_ioctx(ioctx) nogil:
-        return <rados_ioctx_t>0
-ELSE:
-    cdef rados_t convert_rados(rados.Rados rados) except? NULL:
-        return <rados_t>rados.cluster
+cdef rados_ioctx_t convert_ioctx(ioctx) nogil:
+    return <rados_ioctx_t>0
+{{else}}
+cdef rados_t convert_rados(rados.Rados rados) except? NULL:
+    return <rados_t>rados.cluster
 
-    cdef rados_ioctx_t convert_ioctx(rados.Ioctx ioctx) except? NULL:
-        return <rados_ioctx_t>ioctx.io
+cdef rados_ioctx_t convert_ioctx(rados.Ioctx ioctx) except? NULL:
+    return <rados_ioctx_t>ioctx.io
+{{endif}}
 
 cdef int progress_callback(uint64_t offset, uint64_t total, void* ptr) with gil:
     return (<object>ptr)(offset, total)
index c59c4e8f789eb18e379b74b15d67bf1ac2eeb806..f5e654287c5d9870c3516b14dcf59d55061e4de2 100755 (executable)
@@ -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
index 6da956e2d96f9b5ac75d448eec34bb9921dd58ea..a2689d931858ece4fc156390a41234e8a66e9fca 100644 (file)
@@ -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):
index f48e8550c0b2a87a8db8ca62de4df13d323e76d0..8b9b9ac1fef26e953102916e2ee7582904f752b3 100755 (executable)
@@ -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