Skip to content

Commit

Permalink
Make reraise_kj_exception available to downstream
Browse files Browse the repository at this point in the history
I'm using Pycapnp in a project, where we compile `.capnp` files directly to
Cython instead of using the dynamic interface (for speed). For this, we need
access to the `reraise_kj_exception` C function defined by Pycapnp. This is not
possible, because Cython does not automatically make this function available to
downstream users.

My previous solution, in #301, was rather flawed. The  file `capabilityHelper.cpp`, where
`reraise_kj_exception` is defined, was bundled into the distribution, so that
this file could be included in downstream libraries. This turns out to be a
terrible idea, because it redefines a bunch of other things like
`ReadPromiseAdapter`. For reasons not entirely clear to me, this leads to
segmentation faults. This PR revers #301.

Instead, in this PR I've made `reraise_kj_exception` a Cython-level function,
that can be used by downstream libraries. The C-level variant has been renamed
to `c_reraise_kj_exception`.
  • Loading branch information
LasseBlaauwbroek committed Oct 31, 2023
1 parent c9bea05 commit c850d37
Show file tree
Hide file tree
Showing 9 changed files with 11 additions and 8 deletions.
2 changes: 1 addition & 1 deletion capnp/helpers/capabilityHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ::kj::Promise<kj::Own<PyRefCounter>> convert_to_pypromise(capnp::RemotePromise<c
return stealPyRef(wrap_dynamic_struct_reader(response)); } );
}

void reraise_kj_exception() {
void c_reraise_kj_exception() {
GILAcquire gil;
try {
if (PyErr_Occurred())
Expand Down
2 changes: 1 addition & 1 deletion capnp/helpers/capabilityHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ inline ::kj::Promise<kj::Own<PyRefCounter>> convert_to_pypromise(kj::Promise<voi
});
}

void reraise_kj_exception();
void c_reraise_kj_exception();

void check_py_error();

Expand Down
2 changes: 1 addition & 1 deletion capnp/helpers/helpers.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ from capnp.includes.capnp_cpp cimport (

from capnp.includes.schema_cpp cimport ByteArray

from non_circular cimport reraise_kj_exception
from non_circular cimport c_reraise_kj_exception as reraise_kj_exception

from cpython.ref cimport PyObject

Expand Down
2 changes: 1 addition & 1 deletion capnp/helpers/non_circular.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ from cpython.ref cimport PyObject
from libcpp cimport bool

cdef extern from "capnp/helpers/capabilityHelper.h":
void reraise_kj_exception()
void c_reraise_kj_exception()
cdef cppclass PyRefCounter:
PyRefCounter(PyObject *)
PyObject * obj
2 changes: 1 addition & 1 deletion capnp/includes/capnp_cpp.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cdef extern from "capnp/helpers/checkCompiler.h":

from libcpp cimport bool
from capnp.helpers.non_circular cimport (
reraise_kj_exception, PyRefCounter,
c_reraise_kj_exception as reraise_kj_exception, PyRefCounter,
)
from capnp.includes.schema_cpp cimport (
Node, Data, StructNode, EnumNode, InterfaceNode, MessageBuilder, MessageReader, ReaderOptions,
Expand Down
2 changes: 1 addition & 1 deletion capnp/includes/schema_cpp.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# distutils: language = c++

from libc.stdint cimport *
from capnp.helpers.non_circular cimport reraise_kj_exception
from capnp.helpers.non_circular cimport c_reraise_kj_exception as reraise_kj_exception

from capnp.includes.types cimport *

Expand Down
2 changes: 1 addition & 1 deletion capnp/lib/capnp.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ from capnp.includes.capnp_cpp cimport (
)
from capnp.includes.schema_cpp cimport Node as C_Node, EnumNode as C_EnumNode
from capnp.includes.types cimport *
from capnp.helpers.non_circular cimport reraise_kj_exception
from capnp.helpers cimport helpers

cdef void reraise_kj_exception()

cdef class _StructSchemaField:
cdef C_StructSchema.Field thisptr
Expand Down
4 changes: 4 additions & 0 deletions capnp/lib/capnp.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ cdef api object wrap_kj_exception_for_reraise(capnp.Exception & exception) with
return ret


cdef void reraise_kj_exception():
helpers.reraise_kj_exception()


cdef api object get_exception_info(object exc_type, object exc_obj, object exc_tb) with gil:
try:
return (exc_tb.tb_frame.f_code.co_filename.encode(),
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ def run(self): # noqa: C901
"*.capnp",
"helpers/*.pxd",
"helpers/*.h",
"helpers/*.cpp",
"includes/*.pxd",
"lib/*.pxd",
"lib/*.py",
Expand Down

0 comments on commit c850d37

Please sign in to comment.