File 0018-54670-wip-cython-3.patch of Package ceph-ceph-15.2.17

diff --git a/src/pybind/rbd/setup.py b/src/pybind/rbd/setup.py
index 634484f1402..6c211e86c68 100755
--- a/src/pybind/rbd/setup.py
+++ b/src/pybind/rbd/setup.py
@@ -10,6 +10,7 @@ import textwrap
 from distutils.ccompiler import new_compiler
 from distutils.errors import CompileError, LinkError
 from itertools import filterfalse, takewhile
+from packaging import version
 import distutils.sysconfig
 
 
@@ -142,11 +143,22 @@ 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 __version__ as cython_version
 
     cmdclass = {'build_ext': build_ext}
+
+    # Needed for building with Cython 0.x and Cython 3 from the same file,
+    # preserving the same behavior.
+    # When Cython 0.x builds go away, replace this compiler directive with
+    # noexcept on rbd_callback_t and librbd_progress_fn_t (or consider doing
+    # something similar to except? -9000 on rbd_diff_iterate2() callback for
+    # progress callbacks to propagate exceptions).
+    if version.parse(cython_version) >= version.parse('3'):
+        compiler_directives['legacy_implicit_noexcept'] = True
 except ImportError:
     print("WARNING: Cython is not installed.")
 
@@ -191,7 +203,7 @@ setup(
                 **get_python_flags(['rbd', 'rados'])
             )
         ],
-        compiler_directives={'language_level': sys.version_info.major},
+        compiler_directives=compiler_directives,
         build_dir=os.environ.get("CYTHON_BUILD_DIR", None),
         include_path=[
             os.path.join(os.path.dirname(__file__), "..", "rados")
diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py
index 03ecdde691c..79761523f47 100644
--- a/src/test/pybind/test_rbd.py
+++ b/src/test/pybind/test_rbd.py
@@ -388,6 +388,18 @@ def test_remove_canceled():
     assert_raises(OperationCanceled, RBD().remove, ioctx, image_name,
                   on_progress=progress_cb)
 
+@with_setup(create_image)
+def test_remove_with_progress_except():
+    d = {'received_callback': False}
+    def progress_cb(current, total):
+        d['received_callback'] = True
+        raise Exception()
+
+    # exception is logged and ignored with a Cython warning:
+    #   Exception ignored in: 'rbd.progress_callback'
+    RBD().remove(ioctx, image_name, on_progress=progress_cb)
+    eq(True, d['received_callback'])
+
 @with_setup(create_image, remove_image)
 def test_rename():
     rbd = RBD()
@@ -1205,6 +1217,16 @@ class TestImage(object):
         assert(comp.get_return_value() < 0)
         eq(sys.getrefcount(comp), 2)
 
+        # test3: except case
+        def cbex(_, buf):
+            raise KeyError()
+
+        def test3():
+            comp = self.image.aio_read(IMG_SIZE, 20, cbex)
+            comp.wait_for_complete_and_cb()
+
+        assert_raises(KeyError, test3)
+
     def test_aio_write(self):
         retval = [None]
         def cb(comp):
openSUSE Build Service is sponsored by