Skip to content

Commit 3615a15

Browse files
Upgrade Cython to version 3
While looking at #333, I hypothesized that upgrading Cython might solve the issue. It didn't. But upgrading should still happen at some point. This is my work in progress on that. The tests pass, but there are two main things missing: Problem (1): Starting with Cython 3, you can only do `except+` or `except +reraise_kj_exception` on `extern` functions coming from C++. (This makes sense, and the way things were declared in Pycapnp wasn't too good.) As a result, I had to remove a lot of these declaration. This results in some segmentation faults, because Cython no longer detects C++ exceptions and converts them to Python exceptions in some places. To solve this, all `extern` declarations in `.pxd` files have to be examined and `except +reraise_kj_exception` clauses need to be added to anything that might throw. Previously, this was done really inconsistently. The lazy solution would be to just add the clause everywhere, but I'm not sure what the performance implications are. Problem (2): The compilation output of `python setup.py build_ext --inplace` is now full of messages like these: ``` capnp/lib/capnp.cpp: In function ‘PyObject* __pyx_f_5capnp_3lib_5capnp_18_DynamicListReader__get(__pyx_obj_5capnp_3lib_5capnp__DynamicListReader*, int64_t, int)’: capnp/lib/capnp.cpp:4871:51: warning: moving a temporary object prevents copy elision [-Wpessimizing-move] 4871 | #define __PYX_STD_MOVE_IF_SUPPORTED(x) std::move(x) | ~~~~~~~~~^~~ capnp/lib/capnp.cpp:20944:59: note: in expansion of macro ‘__PYX_STD_MOVE_IF_SUPPORTED’ 20944 | __pyx_t_2 = __pyx_f_5capnp_3lib_5capnp_to_python_reader(__PYX_STD_MOVE_IF_SUPPORTED((( ::capnp::DynamicValue::Reader)__pyx_t_7)), __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 419, __pyx_L1_error) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ capnp/lib/capnp.cpp:4871:51: note: remove ‘std::move’ call 4871 | #define __PYX_STD_MOVE_IF_SUPPORTED(x) std::move(x) | ~~~~~~~~~^~~ capnp/lib/capnp.cpp:20944:59: note: in expansion of macro ‘__PYX_STD_MOVE_IF_SUPPORTED’ 20944 | __pyx_t_2 = __pyx_f_5capnp_3lib_5capnp_to_python_reader(__PYX_STD_MOVE_IF_SUPPORTED((( ::capnp::DynamicValue::Reader)__pyx_t_7)), __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 419, __pyx_L1_error) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` There are to many `move` calls inserted. I'm not sure if this is a Cython issue, or if we are somehow annotating things wrong. Might be worth asking the Cython people. I'm not planning on working on this further in the short term. If someone wants to take over on this, feel free.
1 parent 941f018 commit 3615a15

File tree

7 files changed

+82
-101
lines changed

7 files changed

+82
-101
lines changed

capnp/helpers/helpers.pxd

+3-6
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,17 @@ cdef extern from "capnp/helpers/fixMaybe.h":
1616

1717
cdef extern from "capnp/helpers/capabilityHelper.h":
1818
PyPromise then(PyPromise promise, Own[PyRefCounter] func, Own[PyRefCounter] error_func)
19-
DynamicCapability.Client new_client(InterfaceSchema&, PyObject *)
20-
DynamicValue.Reader new_server(InterfaceSchema&, PyObject *)
21-
Capability.Client server_to_client(InterfaceSchema&, PyObject *)
2219
PyPromise convert_to_pypromise(RemotePromise)
2320
PyPromise convert_to_pypromise(VoidPromise)
2421
VoidPromise taskToPromise(Own[PyRefCounter] coroutine, PyObject* callback)
2522
void init_capnp_api()
2623

2724
cdef extern from "capnp/helpers/rpcHelper.h":
28-
Capability.Client bootstrapHelper(RpcSystem&)
29-
Capability.Client bootstrapHelperServer(RpcSystem&)
25+
Own[Capability.Client] bootstrapHelper(RpcSystem&) except +reraise_kj_exception
26+
Own[Capability.Client] bootstrapHelperServer(RpcSystem&) except +reraise_kj_exception
3027

3128
cdef extern from "capnp/helpers/serialize.h":
32-
ByteArray messageToPackedBytes(MessageBuilder &, size_t wordCount)
29+
ByteArray messageToPackedBytes(MessageBuilder &, size_t wordCount) except +reraise_kj_exception
3330

3431
cdef extern from "capnp/helpers/deserialize.h":
3532
Node.Reader toReader(DynamicStruct.Reader reader) except +reraise_kj_exception

capnp/helpers/rpcHelper.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@
66
#include "Python.h"
77
#include "capabilityHelper.h"
88

9-
capnp::Capability::Client bootstrapHelper(capnp::RpcSystem<capnp::rpc::twoparty::SturdyRefHostId>& client) {
9+
kj::Own<capnp::Capability::Client> bootstrapHelper(capnp::RpcSystem<capnp::rpc::twoparty::SturdyRefHostId>& client) {
1010
capnp::MallocMessageBuilder hostIdMessage(8);
1111
auto hostId = hostIdMessage.initRoot<capnp::rpc::twoparty::SturdyRefHostId>();
1212
hostId.setSide(capnp::rpc::twoparty::Side::SERVER);
13-
return client.bootstrap(hostId);
13+
return kj::heap<capnp::Capability::Client>(client.bootstrap(hostId));
1414
}
1515

16-
capnp::Capability::Client bootstrapHelperServer(capnp::RpcSystem<capnp::rpc::twoparty::SturdyRefHostId>& client) {
16+
kj::Own<capnp::Capability::Client> bootstrapHelperServer(capnp::RpcSystem<capnp::rpc::twoparty::SturdyRefHostId>& client) {
1717
capnp::MallocMessageBuilder hostIdMessage(8);
1818
auto hostId = hostIdMessage.initRoot<capnp::rpc::twoparty::SturdyRefHostId>();
1919
hostId.setSide(capnp::rpc::twoparty::Side::CLIENT);
20-
return client.bootstrap(hostId);
20+
return kj::heap<capnp::Capability::Client>(client.bootstrap(hostId));
2121
}

capnp/includes/capnp_cpp.pxd

+4-18
Original file line numberDiff line numberDiff line change
@@ -57,26 +57,12 @@ cdef extern from "kj/async.h" namespace " ::kj":
5757
cdef cppclass Promise[T] nogil:
5858
Promise(Promise)
5959
Promise(T)
60-
T wait(WaitScope) except +reraise_kj_exception
61-
bool poll(WaitScope) except +reraise_kj_exception
62-
# ForkedPromise<T> fork()
63-
# Promise<T> exclusiveJoin(Promise<T>&& other)
64-
# Promise[T] eagerlyEvaluate()
65-
# void detach(ErrorFunc)
6660
String trace()
6761
Promise[T] attach(Own[PyRefCounter] &)
6862
Promise[T] attach(Own[PyRefCounter] &, Own[PyRefCounter] &)
6963
Promise[T] attach(Own[PyRefCounter] &, Own[PyRefCounter] &, Own[PyRefCounter] &)
7064
Promise[T] attach(Own[PyRefCounter] &, Own[PyRefCounter] &, Own[PyRefCounter] &, Own[PyRefCounter] &)
7165

72-
cdef cppclass Canceler nogil:
73-
Canceler()
74-
Promise[T] wrap[T](Promise[T] promise)
75-
void cancel(StringPtr cancelReason)
76-
void cancel(Exception& exception)
77-
void release()
78-
bool isEmpty()
79-
8066
ctypedef Promise[Own[PyRefCounter]] PyPromise
8167
ctypedef Promise[void] VoidPromise
8268

@@ -109,8 +95,8 @@ cdef extern from "kj/array.h" namespace " ::kj":
10995

11096
cdef extern from "kj/async-io.h" namespace " ::kj":
11197
cdef cppclass AsyncIoStream nogil:
112-
Promise[size_t] read(void*, size_t, size_t)
113-
Promise[void] write(const void*, size_t)
98+
Promise[size_t] read(void*, size_t, size_t) except +reraise_kj_exception
99+
Promise[void] write(const void*, size_t) except +reraise_kj_exception
114100

115101
cdef extern from "capnp/schema.capnp.h" namespace " ::capnp":
116102
enum TypeWhich" ::capnp::schema::Type::Which":
@@ -297,7 +283,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
297283
Client()
298284
Client(Client&)
299285
Client(Own[PythonInterfaceDynamicImpl])
300-
Client upcast(InterfaceSchema requestedSchema)
286+
Client upcast(InterfaceSchema requestedSchema) except +reraise_kj_exception
301287
DynamicCapability.Client castAs"castAs< ::capnp::DynamicCapability>"(InterfaceSchema)
302288
InterfaceSchema getSchema()
303289
Request newRequest(char * methodName)
@@ -447,7 +433,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
447433
Type getType()
448434

449435
cdef extern from "capnp/schema-loader.h" namespace " ::capnp":
450-
cdef cppclass SchemaLoader:
436+
cdef cppclass SchemaLoader nogil:
451437
SchemaLoader()
452438
Schema load(Node.Reader reader) except +reraise_kj_exception
453439
Schema get(uint64_t id_) except +reraise_kj_exception

capnp/includes/schema_cpp.pxd

+6-6
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ cdef extern from "capnp/message.h" namespace " ::capnp":
673673
Annotation.Builder getRootAnnotation'getRoot< ::capnp::schema::Annotation>'()
674674
Annotation.Builder initRootAnnotation'initRoot< ::capnp::schema::Annotation>'()
675675

676-
DynamicStruct_Builder getRootDynamicStruct'getRoot< ::capnp::DynamicStruct>'(StructSchema)
676+
DynamicStruct_Builder getRootDynamicStruct'getRoot< ::capnp::DynamicStruct>'(StructSchema) except +reraise_kj_exception
677677
DynamicStruct_Builder initRootDynamicStruct'initRoot< ::capnp::DynamicStruct>'(StructSchema)
678678
void setRootDynamicStruct'setRoot< ::capnp::DynamicStruct::Reader>'(DynamicStruct.Reader)
679679

@@ -696,7 +696,7 @@ cdef extern from "capnp/message.h" namespace " ::capnp":
696696
StructNode.Reader getRootStructNode'getRoot< ::capnp::schema::StructNode>'()
697697
Annotation.Reader getRootAnnotation'getRoot< ::capnp::schema::Annotation>'()
698698

699-
DynamicStruct.Reader getRootDynamicStruct'getRoot< ::capnp::DynamicStruct>'(StructSchema)
699+
DynamicStruct.Reader getRootDynamicStruct'getRoot< ::capnp::DynamicStruct>'(StructSchema) except +reraise_kj_exception
700700
AnyPointer.Reader getRootAnyPointer'getRoot< ::capnp::AnyPointer>'()
701701

702702
cdef cppclass MallocMessageBuilder(MessageBuilder) nogil:
@@ -798,7 +798,7 @@ cdef extern from "capnp/serialize.h" namespace " ::capnp":
798798
FlatArrayMessageReader(WordArrayPtr array, ReaderOptions) except +reraise_kj_exception
799799
const word* getEnd() const
800800

801-
void writeMessageToFd(int, MessageBuilder&) nogil except +reraise_kj_exception
801+
void writeMessageToFd(int, MessageBuilder&) except +reraise_kj_exception nogil
802802

803803
WordArray messageToFlatArray(MessageBuilder &) nogil
804804

@@ -816,6 +816,6 @@ cdef extern from "capnp/serialize-packed.h" namespace " ::capnp":
816816
PackedFdMessageReader(int) except +reraise_kj_exception
817817
PackedFdMessageReader(int, ReaderOptions) except +reraise_kj_exception
818818

819-
void writePackedMessage(BufferedOutputStream&, MessageBuilder&) nogil except +reraise_kj_exception
820-
void writePackedMessage(OutputStream&, MessageBuilder&) nogil except +reraise_kj_exception
821-
void writePackedMessageToFd(int, MessageBuilder&) nogil except +reraise_kj_exception
819+
void writePackedMessage(BufferedOutputStream&, MessageBuilder&) except +reraise_kj_exception nogil
820+
void writePackedMessage(OutputStream&, MessageBuilder&) except +reraise_kj_exception nogil
821+
void writePackedMessageToFd(int, MessageBuilder&) except +reraise_kj_exception nogil

capnp/lib/capnp.pxd

+12-12
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ cdef class _StringArrayPtr:
2828
cdef StringPtr * thisptr
2929
cdef object parent
3030
cdef size_t size
31-
cdef ArrayPtr[StringPtr] asArrayPtr(self) except +reraise_kj_exception
31+
cdef ArrayPtr[StringPtr] asArrayPtr(self)
3232

3333
cdef class SchemaLoader:
3434
cdef C_SchemaLoader * thisptr
@@ -38,7 +38,7 @@ cdef class SchemaParser:
3838
cdef public dict modules_by_id
3939
cdef list _all_imports
4040
cdef _StringArrayPtr _last_import_array
41-
cpdef _parse_disk_file(self, displayName, diskPath, imports) except +reraise_kj_exception
41+
cpdef _parse_disk_file(self, displayName, diskPath, imports)
4242

4343
cdef class _DynamicOrphan:
4444
cdef C_DynamicOrphan thisptr
@@ -79,10 +79,10 @@ cdef class _DynamicStructBuilder:
7979
cdef _init(self, DynamicStruct_Builder other, object parent, bint isRoot=?, bint tryRegistry=?)
8080

8181
cdef _check_write(self)
82-
cpdef to_bytes(_DynamicStructBuilder self) except +reraise_kj_exception
83-
cpdef to_segments(_DynamicStructBuilder self) except +reraise_kj_exception
84-
cpdef _to_bytes_packed_helper(_DynamicStructBuilder self, word_count) except +reraise_kj_exception
85-
cpdef to_bytes_packed(_DynamicStructBuilder self) except +reraise_kj_exception
82+
cpdef to_bytes(_DynamicStructBuilder self)
83+
cpdef to_segments(_DynamicStructBuilder self)
84+
cpdef _to_bytes_packed_helper(_DynamicStructBuilder self, word_count)
85+
cpdef to_bytes_packed(_DynamicStructBuilder self)
8686

8787
cpdef _get(self, field)
8888
cpdef _set(self, field, value)
@@ -128,7 +128,7 @@ cdef class _DynamicEnum:
128128
cdef public object _parent
129129

130130
cdef _init(self, capnp.DynamicEnum other, object parent)
131-
cpdef _as_str(self) except +reraise_kj_exception
131+
cpdef _as_str(self)
132132

133133
cdef class _DynamicListBuilder:
134134
cdef C_DynamicList.Builder thisptr
@@ -146,11 +146,11 @@ cdef class _DynamicListBuilder:
146146
cdef class _MessageBuilder:
147147
cdef schema_cpp.MessageBuilder * thisptr
148148
cpdef init_root(self, schema)
149-
cpdef get_root(self, schema) except +reraise_kj_exception
150-
cpdef get_root_as_any(self) except +reraise_kj_exception
151-
cpdef set_root(self, value) except +reraise_kj_exception
152-
cpdef get_segments_for_output(self) except +reraise_kj_exception
153-
cpdef new_orphan(self, schema) except +reraise_kj_exception
149+
cpdef get_root(self, schema)
150+
cpdef get_root_as_any(self)
151+
cpdef set_root(self, value)
152+
cpdef get_segments_for_output(self)
153+
cpdef new_orphan(self, schema)
154154

155155
cdef to_python_reader(C_DynamicValue.Reader self, object parent)
156156
cdef to_python_builder(C_DynamicValue.Builder self, object parent)

0 commit comments

Comments
 (0)