File 0018-54670-wip-cython-3.patch of Package ceph-ceph-16.2.15
diff --git a/src/pybind/rbd/setup.py b/src/pybind/rbd/setup.py
index 73ea4555f46..0bf0cd6668d 100755
--- a/src/pybind/rbd/setup.py
+++ b/src/pybind/rbd/setup.py
@@ -16,6 +16,7 @@ else:
from distutils.ccompiler import new_compiler
from distutils.errors import CompileError, LinkError
from itertools import filterfalse, takewhile
+from packaging import version
import distutils.sysconfig
@@ -150,11 +151,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.")
@@ -199,7 +211,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/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py
index d1f4d70ecbd..70b6d5ba5da 100644
--- a/src/test/pybind/test_rbd.py
+++ b/src/test/pybind/test_rbd.py
@@ -403,6 +403,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()
@@ -1239,6 +1251,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):