Describe the bug
Compiling the generated C code with -DCYTHON_WITHOUT_ASSERTIONS removes asserts. One such assert is in format_from_typeinfo() in MemoryView.pyx:
assert type.fields != NULL and type.fields.type != NULL
The generated code looks like
#ifndef CYTHON_WITHOUT_ASSERTIONS
if (unlikely(!Py_OptimizeFlag)) {
__pyx_t_2 = ((__pyx_v_type->fields != NULL) != 0);
if (__pyx_t_2) {
} else {
__pyx_t_1 = __pyx_t_2;
goto __pyx_L4_bool_binop_done;
}
__pyx_t_2 = ((__pyx_v_type->fields->type != NULL) != 0);
__pyx_t_1 = __pyx_t_2;
__pyx_L4_bool_binop_done:;
if (unlikely(!__pyx_t_1)) {
PyErr_SetNone(PyExc_AssertionError);
__PYX_ERR(1, 1469, __pyx_L1_error)
}
}
#endif
Here __pyx_t_2 is declared at the top of the function (together with other variables), but it is only ever used inside this #ifndef block. Thus, compiling with -DCYTHON_WITHOUT_ASSERTIONS (at least under gcc) emits the warning
warning: unused variable ‘__pyx_t_2’ [-Wunused-variable]
int __pyx_t_2 = 0;
To Reproduce
cdef double[::1] ptr2view(double* ptr):
cdef double[::1] a = <double[:3]>ptr
return a
Environment
- OS: Linux Mint 19.3
- Python version: 3.8.2
- Cython version: 0.29.16
- C compiler: gcc 7.5.0
Proposed fix
The assert in question really asks two separate questions. Splitting them into two separate asserts solves the issue:
assert type.fields != NULL
assert type.fields.type != NULL
Note that as long as the order is preserved, this has the same behaviour as the combined assert. I believe the difference is that now, no additional, intermediate variable is needed to and together the two boolean expressions in the C code.
If we go with this fix, we should probably split all other "combined asserts" in a similar manner. A quick
grep -r 'assert ' | grep '\.pyx' | grep ' and '
reveals that the one in MemoryView.pyx is in fact the only one, not counting test code and documentation. The same goes for two asserts combined with or instead of and.
Bad code is of course still generated if a "combined assert" appears in the user code, e.g.
def f(a, b):
assert a and b
but at least now no warnings will be emitted from Cython itself.
Describe the bug
Compiling the generated C code with
-DCYTHON_WITHOUT_ASSERTIONSremovesasserts. One suchassertis informat_from_typeinfo()inMemoryView.pyx:The generated code looks like
Here
__pyx_t_2is declared at the top of the function (together with other variables), but it is only ever used inside this#ifndefblock. Thus, compiling with-DCYTHON_WITHOUT_ASSERTIONS(at least under gcc) emits the warningTo Reproduce
Environment
Proposed fix
The
assertin question really asks two separate questions. Splitting them into two separateasserts solves the issue:Note that as long as the order is preserved, this has the same behaviour as the combined
assert. I believe the difference is that now, no additional, intermediate variable is needed toandtogether the two boolean expressions in the C code.If we go with this fix, we should probably split all other "combined
asserts" in a similar manner. A quickreveals that the one in
MemoryView.pyxis in fact the only one, not counting test code and documentation. The same goes for twoasserts combined withorinstead ofand.Bad code is of course still generated if a "combined
assert" appears in the user code, e.g.but at least now no warnings will be emitted from Cython itself.