New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] make_unique
not annotated with except +
#5560
Comments
make_unique in Cython's libcpp headers is not annotated with `except +`. As a consequence, if the constructor throws, we do not catch it in Python. To work around this (see cython/cython#5560 for details), provide our own implementation. Due to the way assignments occur to temporaries, we need to now explicitly wrap all calls to `make_unique` in `move`, but that is arguably preferable to not being able to catch exceptions. - Closes rapidsai#13743
make_unique in Cython's libcpp headers is not annotated with `except +`. As a consequence, if the constructor throws, we do not catch it in Python. To work around this (see cython/cython#5560 for details), provide our own implementation. Due to the way assignments occur to temporaries, we need to now explicitly wrap all calls to `make_unique` in `move`, but that is arguably preferable to not being able to catch exceptions. - Closes rapidsai#13743
Maybe I'm missing some detail of C++, but I believe the explicit call to
If that's the case there's basically no reason not to add |
I think that is correct. From some quick local testing that does appear to work. I'm going to try rebuilding a few of my libraries with this change to verify that there are no surprises. |
make_unique in Cython's libcpp headers is not annotated with `except +`. As a consequence, if the constructor throws, we do not catch it in Python. To work around this (see cython/cython#5560 for details), provide our own implementation. Due to the way assignments occur to temporaries, we need to now explicitly wrap all calls to `make_unique` in `move`, but that is arguably preferable to not being able to catch exceptions. - Closes rapidsai#13743
I was (also) testing with Cython < 3 which transpiles this example: from libcpp.utility cimport move
from libcpp.memory cimport unique_ptr
from libcpp.vector cimport vector
cdef extern from "<memory>" namespace "std" nogil:
unique_ptr[T] make_unique[T](...) except +
def some_function(int n):
cdef unique_ptr[vector[double]] vec
with nogil:
vec = make_unique[vector[double]](n)
return vec.get().size() to /*try:*/ {
/* "cython_except.pyx":12
*
* with nogil:
* vec = make_unique[vector[double]](n) # <<<<<<<<<<<<<<
*
* return vec.get().size()
*/
try {
__pyx_t_1 = std::make_unique<std::vector<double> >(__pyx_v_n);
} catch(...) {
#ifdef WITH_THREAD
PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
#endif
__Pyx_CppExn2PyErr();
#ifdef WITH_THREAD
__Pyx_PyGILState_Release(__pyx_gilstate_save);
#endif
__PYX_ERR(0, 12, __pyx_L4_error)
}
__pyx_v_vec = __pyx_t_1;
} However, with cython 3 we get /*try:*/ {
/* "cython_except.pyx":12
*
* with nogil:
* vec = make_unique[vector[double]](n) # <<<<<<<<<<<<<<
*
* return vec.get().size()
*/
try {
__pyx_t_1 = std::make_unique<std::vector<double> >(__pyx_v_n);
} catch(...) {
#ifdef WITH_THREAD
PyGILState_STATE __pyx_gilstate_save = __Pyx_PyGILState_Ensure();
#endif
__Pyx_CppExn2PyErr();
#ifdef WITH_THREAD
__Pyx_PyGILState_Release(__pyx_gilstate_save);
#endif
__PYX_ERR(0, 12, __pyx_L4_error)
}
__pyx_v_vec = __PYX_STD_MOVE_IF_SUPPORTED(__pyx_t_1);
} So I agree it looks like the explicit |
make_unique in Cython's libcpp headers is not annotated with `except +`. As a consequence, if the constructor throws, we do not catch it in Python. To work around this (see cython/cython#5560 for details), provide our own implementation. Due to the way assignments occur to temporaries, we need to now explicitly wrap all calls to `make_unique` in `move`, but that is arguably preferable to not being able to catch exceptions, and will not be necessary once we move to Cython 3. - Closes rapidsai#13743
`make_unique` in Cython's libcpp headers is not annotated with `except +`. As a consequence, if the constructor throws, we do not catch it in Python. To work around this (see cython/cython#5560 for details), provide our own implementation. Due to the way assignments occur to temporaries, we need to now explicitly wrap all calls to `make_unique` in `move`, but that is arguably preferable to not being able to catch exceptions, and will not be necessary once we move to Cython 3. - Closes #13743 Authors: - Lawrence Mitchell (https://github.com/wence-) Approvers: - Ashwin Srinath (https://github.com/shwina) URL: #13746
Also tweak the selection for move-if-supported. This now lets the user enable it by a define even if the compiler support isn't detected. This is useful because the new signature for make_unique kind of relies on move-if-supported to work. Fixes cython#5560
I don't think this should be backported since it needs updated features to work. I've proposed a change. I've also changed how we detect |
Also tweak the selection for move-if-supported by adding a feature flag `CYTHON_USE_CPP_STD_MOVE`. This now lets the user enable it even if the compiler support isn't detected. This is useful because the new signature for `make_unique()` kind of relies on move-if-supported to work. Fixes #5560
Describe the bug
When
make_unique
was provided inmemory.pxd
in #487, it didn't come with anexcept +
annotation. At the time, this was due to the Cython compiler not emitting the correctstd::move(...)
in the subsequent assignment in the transpiled source code.AFAICT this can be worked around in a reasonable manner by explicitly putting a
move
call in the rvalue of the assignment, and although that is less ergonomic, perhaps it is better because exceptions will actually be caught.In the intervening years, it looks like this restriction has gone, and so
except +
should be reintroduced. The issue here is that a (potentially) throwing constructor wrapped bymake_unique
does notCode to reproduce the behaviour:
Expected behaviour
I expect this to be transpiled to:
Whereas in fact it is transpiled to:
OS
Linux
Python version
3.10.6
Cython version
3.0.0
Additional context
No response
The text was updated successfully, but these errors were encountered: