From 1d2996c6c0465f5b77316aab4bcab40f2b49e84e Mon Sep 17 00:00:00 2001 From: Celine Mercier Date: Wed, 5 Jul 2017 14:45:43 +0200 Subject: [PATCH] Better handling and tracing of Index Errors between C and Cython --- python/obitools3/dms/capi/obierrno.pxd | 3 + .../dms/column/typed_column/bool.pyx | 45 ++++----- .../dms/column/typed_column/char.pyx | 34 +++---- .../dms/column/typed_column/float.pyx | 24 ++--- .../obitools3/dms/column/typed_column/int.pyx | 23 ++--- .../dms/column/typed_column/qual.pyx | 59 ++++------- .../obitools3/dms/column/typed_column/seq.pyx | 23 ++--- .../obitools3/dms/column/typed_column/str.pyx | 25 ++--- python/obitools3/utils.cfiles | 33 +++++++ python/obitools3/utils.pxd | 10 +- python/obitools3/utils.pyx | 99 +++++++++++++++++++ src/obierrno.h | 5 + 12 files changed, 236 insertions(+), 147 deletions(-) create mode 100644 python/obitools3/utils.cfiles diff --git a/python/obitools3/dms/capi/obierrno.pxd b/python/obitools3/dms/capi/obierrno.pxd index 7ba7f1e..a0bf858 100644 --- a/python/obitools3/dms/capi/obierrno.pxd +++ b/python/obitools3/dms/capi/obierrno.pxd @@ -3,3 +3,6 @@ cdef extern from "obierrno.h": int obi_errno + + extern int OBI_LINE_IDX_ERROR + extern int OBI_ELT_IDX_ERROR diff --git a/python/obitools3/dms/column/typed_column/bool.pyx b/python/obitools3/dms/column/typed_column/bool.pyx index 66c3659..3c0b487 100644 --- a/python/obitools3/dms/column/typed_column/bool.pyx +++ b/python/obitools3/dms/column/typed_column/bool.pyx @@ -5,15 +5,14 @@ from ..column cimport register_column_class from ...view.view cimport View -from obitools3.utils cimport tobytes +from obitools3.utils cimport tobytes, \ + obi_errno_to_exception from ...capi.obiview cimport obi_get_bool_with_elt_name_and_col_p_in_view, \ obi_get_bool_with_elt_idx_and_col_p_in_view, \ obi_set_bool_with_elt_name_and_col_p_in_view, \ obi_set_bool_with_elt_idx_and_col_p_in_view -from ...capi.obierrno cimport obi_errno - from ...capi.obitypes cimport OBI_BOOL, OBIBool_NA, obibool_t from cpython.bool cimport PyBool_FromLong @@ -27,7 +26,6 @@ cdef class Column_bool(Column): index_t nb_elements_per_line=1, object elements_names=None, object comments=b""): - return Column.new_column(view, column_name, OBI_BOOL, nb_elements_per_line=nb_elements_per_line, elements_names=elements_names, @@ -35,13 +33,10 @@ cdef class Column_bool(Column): cpdef object get_line(self, index_t line_nb): - cdef obibool_t value - cdef object result - global obi_errno - + cdef obibool_t value + cdef object result value = obi_get_bool_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem getting a value from a column") if value == OBIBool_NA : result = None else : @@ -53,22 +48,21 @@ cdef class Column_bool(Column): if value is None : value = OBIBool_NA if obi_set_bool_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, value) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") cdef class Column_multi_elts_bool(Column_multi_elts): cpdef object get_item(self, index_t line_nb, object elt_id) : - cdef obibool_t value - cdef object result - cdef bytes elt_name + cdef obibool_t value + cdef object result + cdef bytes elt_name if type(elt_id) == int : value = obi_get_bool_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id) else : elt_name = tobytes(elt_id) value = obi_get_bool_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name) - if obi_errno > 0 : - raise IndexError(line_nb, elt_id) + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem getting a value from a column") if value == OBIBool_NA : result = None else : @@ -76,17 +70,16 @@ cdef class Column_multi_elts_bool(Column_multi_elts): return result cpdef object get_line(self, index_t line_nb) : - cdef obibool_t value - cdef object value_in_result - cdef dict result - cdef index_t i - cdef bint all_NA + cdef obibool_t value + cdef object value_in_result + cdef dict result + cdef index_t i + cdef bint all_NA result = {} all_NA = True for i in range(self.nb_elements_per_line) : value = obi_get_bool_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, i) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=i, error_message="Problem getting a value from a column") if value == OBIBool_NA : value_in_result = None else : @@ -99,16 +92,16 @@ cdef class Column_multi_elts_bool(Column_multi_elts): return result cpdef set_item(self, index_t line_nb, object elt_id, object value) : - cdef bytes elt_name + cdef bytes elt_name if value is None : value = OBIBool_NA if type(elt_id) == int : if obi_set_bool_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id, value) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") else : elt_name = tobytes(elt_id) if obi_set_bool_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name, value) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") def register_class() : diff --git a/python/obitools3/dms/column/typed_column/char.pyx b/python/obitools3/dms/column/typed_column/char.pyx index 3ea6ef0..48b9ac0 100644 --- a/python/obitools3/dms/column/typed_column/char.pyx +++ b/python/obitools3/dms/column/typed_column/char.pyx @@ -5,15 +5,14 @@ from ..column cimport register_column_class from ...view.view cimport View -from obitools3.utils cimport tobytes +from obitools3.utils cimport tobytes, \ + obi_errno_to_exception from ...capi.obiview cimport obi_get_char_with_elt_name_and_col_p_in_view, \ obi_get_char_with_elt_idx_and_col_p_in_view, \ obi_set_char_with_elt_name_and_col_p_in_view, \ obi_set_char_with_elt_idx_and_col_p_in_view -from ...capi.obierrno cimport obi_errno - from ...capi.obitypes cimport OBI_CHAR, OBIChar_NA, obichar_t @@ -33,13 +32,10 @@ cdef class Column_char(Column): comments=comments) cpdef object get_line(self, index_t line_nb): - cdef obichar_t value - cdef object result - global obi_errno - + cdef obichar_t value + cdef object result value = obi_get_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem getting a value from a column") if value == OBIChar_NA : result = None else : @@ -47,28 +43,27 @@ cdef class Column_char(Column): return result cpdef set_line(self, index_t line_nb, object value): - cdef obichar_t value_b + cdef obichar_t value_b if value is None : value_b = OBIChar_NA else : value_b = tobytes(value)[0] if obi_set_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, value_b) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") cdef class Column_multi_elts_char(Column_multi_elts): cpdef object get_item(self, index_t line_nb, object elt_id) : - cdef obichar_t value - cdef object result - cdef bytes elt_name + cdef obichar_t value + cdef object result + cdef bytes elt_name if type(elt_id) == int : value = obi_get_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id) else : elt_name = tobytes(elt_id) value = obi_get_char_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name) - if obi_errno > 0 : - raise IndexError(line_nb, elt_id) + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem getting a value from a column") if value == OBIChar_NA : result = None else : @@ -85,8 +80,7 @@ cdef class Column_multi_elts_char(Column_multi_elts): all_NA = True for i in range(self.nb_elements_per_line) : value = obi_get_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, i) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=i, error_message="Problem getting a value from a column") if value == OBIChar_NA : value_in_result = None else : @@ -107,11 +101,11 @@ cdef class Column_multi_elts_char(Column_multi_elts): value_b = tobytes(value)[0] if type(elt_id) == int : if obi_set_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id, value_b) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") else : elt_name = tobytes(elt_id) if obi_set_char_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name, value_b) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") def register_class(): diff --git a/python/obitools3/dms/column/typed_column/float.pyx b/python/obitools3/dms/column/typed_column/float.pyx index 335d93d..14a2eca 100644 --- a/python/obitools3/dms/column/typed_column/float.pyx +++ b/python/obitools3/dms/column/typed_column/float.pyx @@ -5,15 +5,14 @@ from ..column cimport register_column_class from ...view.view cimport View -from obitools3.utils cimport tobytes +from obitools3.utils cimport tobytes, \ + obi_errno_to_exception from ...capi.obiview cimport obi_get_float_with_elt_name_and_col_p_in_view, \ obi_get_float_with_elt_idx_and_col_p_in_view, \ obi_set_float_with_elt_name_and_col_p_in_view, \ obi_set_float_with_elt_idx_and_col_p_in_view -from ...capi.obierrno cimport obi_errno - from ...capi.obitypes cimport OBI_FLOAT, OBIFloat_NA, obifloat_t @@ -35,12 +34,9 @@ cdef class Column_float(Column): cpdef object get_line(self, index_t line_nb): cdef obifloat_t value - cdef object result - global obi_errno - + cdef object result value = obi_get_float_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem getting a value from a column") if value == OBIFloat_NA : result = None else : @@ -52,7 +48,7 @@ cdef class Column_float(Column): if value is None : value = OBIFloat_NA if obi_set_float_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, value) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") cdef class Column_multi_elts_float(Column_multi_elts): @@ -66,8 +62,7 @@ cdef class Column_multi_elts_float(Column_multi_elts): else : elt_name = tobytes(elt_id) value = obi_get_float_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name) - if obi_errno > 0 : - raise IndexError(line_nb, elt_id) + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem getting a value from a column") if value == OBIFloat_NA : result = None else : @@ -84,8 +79,7 @@ cdef class Column_multi_elts_float(Column_multi_elts): all_NA = True for i in range(self.nb_elements_per_line) : value = obi_get_float_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, i) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=i, error_message="Problem getting a value from a column") if value == OBIFloat_NA : value_in_result = None else : @@ -103,11 +97,11 @@ cdef class Column_multi_elts_float(Column_multi_elts): value = OBIFloat_NA if type(elt_id) == int : if obi_set_float_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id, value) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") else : elt_name = tobytes(elt_id) if obi_set_float_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name, value) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") def register_class(): diff --git a/python/obitools3/dms/column/typed_column/int.pyx b/python/obitools3/dms/column/typed_column/int.pyx index 8444a0c..31bbb8f 100644 --- a/python/obitools3/dms/column/typed_column/int.pyx +++ b/python/obitools3/dms/column/typed_column/int.pyx @@ -5,14 +5,14 @@ from ..column cimport register_column_class from ...view.view cimport View -from obitools3.utils cimport tobytes +from obitools3.utils cimport tobytes, \ + obi_errno_to_exception from ...capi.obiview cimport obi_get_int_with_elt_name_and_col_p_in_view, \ obi_get_int_with_elt_idx_and_col_p_in_view, \ obi_set_int_with_elt_name_and_col_p_in_view, \ obi_set_int_with_elt_idx_and_col_p_in_view -from ...capi.obierrno cimport obi_errno from ...capi.obitypes cimport OBI_INT, OBIInt_NA, obiint_t from cpython.int cimport PyInt_FromLong @@ -35,12 +35,9 @@ cdef class Column_int(Column): cpdef object get_line(self, index_t line_nb): cdef obiint_t value - cdef object result - global obi_errno - + cdef object result value = obi_get_int_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem getting a value from a column") if value == OBIInt_NA : result = None else : @@ -52,7 +49,7 @@ cdef class Column_int(Column): if value is None : value = OBIInt_NA if obi_set_int_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, value) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") cdef class Column_multi_elts_int(Column_multi_elts): @@ -66,8 +63,7 @@ cdef class Column_multi_elts_int(Column_multi_elts): else : elt_name = tobytes(elt_id) value = obi_get_int_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name) - if obi_errno > 0 : - raise IndexError(line_nb, elt_id) + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem getting a value from a column") if value == OBIInt_NA : result = None else : @@ -84,8 +80,7 @@ cdef class Column_multi_elts_int(Column_multi_elts): all_NA = True for i in range(self.nb_elements_per_line) : value = obi_get_int_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, i) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=i, error_message="Problem getting a value from a column") if value == OBIInt_NA : value_in_result = None else : @@ -103,11 +98,11 @@ cdef class Column_multi_elts_int(Column_multi_elts): value = OBIInt_NA if type(elt_id) == int : if obi_set_int_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id, value) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") else : elt_name = tobytes(elt_id) if obi_set_int_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name, value) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") def register_class(): diff --git a/python/obitools3/dms/column/typed_column/qual.pyx b/python/obitools3/dms/column/typed_column/qual.pyx index 8947c98..89eae9d 100644 --- a/python/obitools3/dms/column/typed_column/qual.pyx +++ b/python/obitools3/dms/column/typed_column/qual.pyx @@ -5,7 +5,8 @@ from ..column cimport register_column_class from ...view.view cimport View -from obitools3.utils cimport tobytes, bytes2str +from obitools3.utils cimport tobytes, bytes2str, \ + obi_errno_to_exception from ...capi.obiview cimport obi_get_qual_char_with_elt_name_and_col_p_in_view, \ obi_get_qual_char_with_elt_idx_and_col_p_in_view, \ @@ -16,8 +17,6 @@ from ...capi.obiview cimport obi_get_qual_char_with_elt_name_and_col_p_in_view, obi_set_qual_int_with_elt_name_and_col_p_in_view, \ obi_set_qual_int_with_elt_idx_and_col_p_in_view -from ...capi.obierrno cimport obi_errno - from ...capi.obitypes cimport OBI_QUAL, OBIQual_char_NA, OBIQual_int_NA, const_char_p from libc.stdlib cimport free @@ -43,12 +42,9 @@ cdef class Column_qual(Column): cpdef object get_line(self, index_t line_nb): cdef const uint8_t* value cdef int value_length - cdef object result - global obi_errno - + cdef object result value = obi_get_qual_int_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, &value_length) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem getting a value from a column") if value == OBIQual_int_NA : result = None else : @@ -59,14 +55,11 @@ cdef class Column_qual(Column): cpdef object get_str_line(self, index_t line_nb): - cdef char* value - cdef object result - cdef int i - global obi_errno - + cdef char* value + cdef object result + cdef int i value = obi_get_qual_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem getting a value from a column") if value == OBIQual_char_NA : result = None else : # TODO discuss @@ -80,14 +73,14 @@ cdef class Column_qual(Column): cdef int value_length if value is None : if obi_set_qual_int_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, OBIQual_int_NA, 0) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") else : value_length = len(value) value_b = malloc(value_length * sizeof(uint8_t)) for i in range(value_length) : value_b[i] = value[i] if obi_set_qual_int_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, value_b, value_length) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") free(value_b) @@ -95,11 +88,11 @@ cdef class Column_qual(Column): cdef bytes value_b if value is None : if obi_set_qual_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, OBIQual_char_NA) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") else : value_b = tobytes(value) if obi_set_qual_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, value_b) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") cdef class Column_multi_elts_qual(Column_multi_elts): @@ -109,15 +102,12 @@ cdef class Column_multi_elts_qual(Column_multi_elts): cdef int value_length cdef object result cdef int i - global obi_errno # TODO add everywhere - if type(elt_id) == int : value = obi_get_qual_int_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id, &value_length) else : elt_name = tobytes(elt_id) value = obi_get_qual_int_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name, &value_length) - if obi_errno > 0 : - raise IndexError(line_nb, elt_id) + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem getting a value from a column") if value == OBIQual_int_NA : result = None else : @@ -130,15 +120,12 @@ cdef class Column_multi_elts_qual(Column_multi_elts): cpdef object get_str_item(self, index_t line_nb, object elt_id): cdef char* value cdef object result - global obi_errno - if type(elt_id) == int : value = obi_get_qual_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id) else : elt_name = tobytes(elt_id) value = obi_get_qual_char_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name) - if obi_errno > 0 : - raise IndexError(line_nb, elt_name) + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem getting a value from a column") if value == OBIQual_char_NA : result = None else : @@ -155,14 +142,11 @@ cdef class Column_multi_elts_qual(Column_multi_elts): cdef index_t i cdef int j cdef bint all_NA - global obi_errno - result = {} all_NA = True for i in range(self.nb_elements_per_line) : value = obi_get_qual_int_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, i, &value_length) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=i, error_message="Problem getting a value from a column") if value == OBIQual_int_NA : value_in_result = None else : @@ -183,14 +167,11 @@ cdef class Column_multi_elts_qual(Column_multi_elts): cdef dict result cdef index_t i cdef bint all_NA - global obi_errno - result = {} all_NA = True for i in range(self.nb_elements_per_line) : value = obi_get_qual_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, i) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=i, error_message="Problem getting a value from a column") if value == OBIQual_char_NA : value_in_result = None else : @@ -220,11 +201,11 @@ cdef class Column_multi_elts_qual(Column_multi_elts): if type(elt_id) == int : if obi_set_qual_int_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id, value_b, value_length) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") else : elt_name = tobytes(elt_id) if obi_set_qual_int_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name, value_b, value_length) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") if value is not None : free(value_b) @@ -241,11 +222,11 @@ cdef class Column_multi_elts_qual(Column_multi_elts): if type(elt_id) == int : if obi_set_qual_char_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id, value_b) < 0 : - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") else : elt_name = tobytes(elt_id) if obi_set_qual_char_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name, value_b) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") diff --git a/python/obitools3/dms/column/typed_column/seq.pyx b/python/obitools3/dms/column/typed_column/seq.pyx index 56ccbb0..94d3602 100644 --- a/python/obitools3/dms/column/typed_column/seq.pyx +++ b/python/obitools3/dms/column/typed_column/seq.pyx @@ -5,15 +5,14 @@ from ..column cimport register_column_class from ...view.view cimport View -from obitools3.utils cimport tobytes +from obitools3.utils cimport tobytes, \ + obi_errno_to_exception from ...capi.obiview cimport obi_get_seq_with_elt_name_and_col_p_in_view, \ obi_get_seq_with_elt_idx_and_col_p_in_view, \ obi_set_seq_with_elt_name_and_col_p_in_view, \ obi_set_seq_with_elt_idx_and_col_p_in_view -from ...capi.obierrno cimport obi_errno - from ...capi.obitypes cimport OBI_SEQ, OBISeq_NA from libc.stdlib cimport free @@ -37,10 +36,8 @@ cdef class Column_seq(Column): cpdef object get_line(self, index_t line_nb): cdef char* value cdef object result - global obi_errno value = obi_get_seq_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem getting a value from a column") if value == OBISeq_NA : result = None else : # TODO @@ -62,7 +59,7 @@ cdef class Column_seq(Column): value_b = value_bytes if obi_set_seq_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, value_b) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") cdef class Column_multi_elts_seq(Column_multi_elts): @@ -70,14 +67,12 @@ cdef class Column_multi_elts_seq(Column_multi_elts): cpdef object get_item(self, index_t line_nb, object elt_id) : cdef char* value cdef object result - global obi_errno if type(elt_id) == int : value = obi_get_seq_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id) else : elt_name = tobytes(elt_id) value = obi_get_seq_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name) - if obi_errno > 0 : - raise IndexError(line_nb, elt_id) + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem getting a value from a column") if value == OBISeq_NA : result = None else : @@ -94,13 +89,11 @@ cdef class Column_multi_elts_seq(Column_multi_elts): cdef dict result cdef index_t i cdef bint all_NA - global obi_errno result = {} all_NA = True for i in range(self.nb_elements_per_line) : value = obi_get_seq_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, i) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=i, error_message="Problem getting a value from a column") if value == OBISeq_NA : value_in_result = None else : @@ -130,12 +123,12 @@ cdef class Column_multi_elts_seq(Column_multi_elts): if type(elt_id) == int : if obi_set_seq_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id, value_b) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") else : elt_name = tobytes(elt_id) if obi_set_seq_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name, value_b) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") def register_class(): diff --git a/python/obitools3/dms/column/typed_column/str.pyx b/python/obitools3/dms/column/typed_column/str.pyx index 60ea93e..a876e9e 100644 --- a/python/obitools3/dms/column/typed_column/str.pyx +++ b/python/obitools3/dms/column/typed_column/str.pyx @@ -5,14 +5,14 @@ from ..column cimport register_column_class from ...view.view cimport View -from obitools3.utils cimport tobytes +from obitools3.utils cimport tobytes, \ + obi_errno_to_exception from ...capi.obiview cimport obi_get_str_with_elt_name_and_col_p_in_view, \ obi_get_str_with_elt_idx_and_col_p_in_view, \ obi_set_str_with_elt_name_and_col_p_in_view, \ obi_set_str_with_elt_idx_and_col_p_in_view -from ...capi.obierrno cimport obi_errno from ...capi.obitypes cimport OBI_STR, OBIStr_NA, const_char_p @@ -34,11 +34,8 @@ cdef class Column_str(Column): cpdef object get_line(self, index_t line_nb): cdef const_char_p value cdef object result - global obi_errno value = obi_get_str_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0) - if obi_errno > 0 : - raise IndexError(line_nb) - print(value == NULL) + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem getting a value from a column") if value == OBIStr_NA : result = None else : @@ -57,7 +54,7 @@ cdef class Column_str(Column): value_b = value_bytes if obi_set_str_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, 0, value_b) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=None, error_message="Problem setting a value in a column") cdef class Column_multi_elts_str(Column_multi_elts): @@ -65,15 +62,12 @@ cdef class Column_multi_elts_str(Column_multi_elts): cpdef object get_item(self, index_t line_nb, object elt_id) : cdef const_char_p value cdef object result - global obi_errno if type(elt_id) == int : value = obi_get_str_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id) else : elt_name = tobytes(elt_id) value = obi_get_str_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name) - print(value == NULL) - if obi_errno > 0 : - raise IndexError(line_nb, elt_id) + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem getting a value from a column") if value == OBIStr_NA : result = None else : @@ -87,14 +81,11 @@ cdef class Column_multi_elts_str(Column_multi_elts): cdef dict result cdef index_t i cdef bint all_NA - global obi_errno result = {} all_NA = True for i in range(self.nb_elements_per_line) : value = obi_get_str_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, i) - print(value == NULL) - if obi_errno > 0 : - raise IndexError(line_nb) + obi_errno_to_exception(line_nb=line_nb, elt_id=i, error_message="Problem getting a value from a column") if value == OBIStr_NA : value_in_result = None else : @@ -120,11 +111,11 @@ cdef class Column_multi_elts_str(Column_multi_elts): if type(elt_id) == int : if obi_set_str_with_elt_idx_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_id, value_b) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") else : elt_name = tobytes(elt_id) if obi_set_str_with_elt_name_and_col_p_in_view(self._view.pointer(), self.pointer(), line_nb, elt_name, value_b) < 0: - raise Exception("Problem setting a value in a column") + obi_errno_to_exception(line_nb=line_nb, elt_id=elt_id, error_message="Problem setting a value in a column") def register_class(): diff --git a/python/obitools3/utils.cfiles b/python/obitools3/utils.cfiles new file mode 100644 index 0000000..cbb30fc --- /dev/null +++ b/python/obitools3/utils.cfiles @@ -0,0 +1,33 @@ +../../src/bloom.c +../../src/char_str_indexer.c +../../src/crc64.c +../../src/dna_seq_indexer.c +../../src/encode.c +../../src/hashtable.c +../../src/linked_list.c +../../src/murmurhash2.c +../../src/obi_align.c +../../src/obiavl.c +../../src/obiblob_indexer.c +../../src/obiblob.c +../../src/obidms_taxonomy.c +../../src/obidms.c +../../src/obidmscolumn_blob.c +../../src/obidmscolumn_bool.c +../../src/obidmscolumn_char.c +../../src/obidmscolumn_float.c +../../src/obidmscolumn_idx.c +../../src/obidmscolumn_int.c +../../src/obidmscolumn_qual.c +../../src/obidmscolumn_seq.c +../../src/obidmscolumn_str.c +../../src/obidmscolumn.c +../../src/obidmscolumndir.c +../../src/obierrno.c +../../src/obilittlebigman.c +../../src/obitypes.c +../../src/obiview.c +../../src/sse_banded_LCS_alignment.c +../../src/uint8_indexer.c +../../src/upperband.c +../../src/utils.c diff --git a/python/obitools3/utils.pxd b/python/obitools3/utils.pxd index 725a9fe..f52eac9 100644 --- a/python/obitools3/utils.pxd +++ b/python/obitools3/utils.pxd @@ -1,7 +1,15 @@ #cython: language_level=3 +from obitools3.dms.capi.obitypes cimport obitype_t, index_t + +cdef obi_errno_to_exception(index_t line_nb=*, object elt_id=*, str error_message=*) cdef bytes str2bytes(str string) cdef str bytes2str(bytes string) cdef bytes tobytes(object string) -cdef str tostr(object string) \ No newline at end of file +cdef str tostr(object string) + +cdef obitype_t get_obitype_single_value(object value) +cdef obitype_t update_obitype(obitype_t obitype, object new_value) +cdef obitype_t get_obitype_iterable_value(object value) +cdef obitype_t get_obitype(object value) \ No newline at end of file diff --git a/python/obitools3/utils.pyx b/python/obitools3/utils.pyx index b7e4399..72162ce 100644 --- a/python/obitools3/utils.pyx +++ b/python/obitools3/utils.pyx @@ -1,5 +1,32 @@ #cython: language_level=3 +from obitools3.dms.capi.obitypes cimport is_a_DNA_seq, \ + OBI_VOID, \ + OBI_BOOL, \ + OBI_CHAR, \ + OBI_FLOAT, \ + OBI_INT, \ + OBI_QUAL, \ + OBI_SEQ, \ + OBI_STR, \ + index_t + +from obitools3.dms.capi.obierrno cimport obi_errno, \ + OBI_LINE_IDX_ERROR, \ + OBI_ELT_IDX_ERROR + + +cdef obi_errno_to_exception(index_t line_nb=-1, object elt_id=None, str error_message=None) : + global obi_errno + if obi_errno > 0 : + if obi_errno == OBI_LINE_IDX_ERROR : + raise IndexError(line_nb, None or error_message) + elif obi_errno == OBI_ELT_IDX_ERROR : + raise IndexError(elt_id, None or error_message) + else : + raise Exception(None or error_message) + + cdef bytes str2bytes(str string): """ Short cut to convert ascii encoded python string (str) to bytes @@ -52,3 +79,75 @@ cdef str tostr(object string): return string return bytes2str(string) + +cdef obitype_t get_obitype_single_value(object value) : + + cdef type value_type + cdef obitype_t value_obitype + + if value is None : + return OBI_VOID + + value_type = type(value) + value_obitype = OBI_VOID + + if value_type == int : + value_obitype = OBI_INT + elif value_type == float : + value_obitype = OBI_FLOAT + elif value_type == bool : + value_obitype = OBI_BOOL + elif value_type == str or value_type == bytes : + if is_a_DNA_seq(tobytes(value)) : + value_obitype = OBI_SEQ + elif len(value) == 1 : + value_obitype = OBI_CHAR + elif (len(value) > 1) : + value_obitype = OBI_STR + else : + value_obitype = OBI_VOID + + return value_obitype + + +cdef obitype_t update_obitype(obitype_t obitype, object new_value) : + + cdef type new_type + + new_type = type(new_value) + + if obitype == OBI_INT : + if new_type == float : + return OBI_FLOAT + # TODO BOOL vers INT/FLOAT + elif new_type == str or new_type == bytes : + if obitype == OBI_SEQ and is_a_DNA_seq(tobytes(new_value)) : + pass + else : + return OBI_STR + + return obitype + + +cdef obitype_t get_obitype_iterable_value(object value) : + + cdef obitype_t value_obitype + + value_obitype = OBI_VOID + + for k in value : + if value_obitype == OBI_VOID : + value_obitype = get_obitype_single_value(value[k]) + else : + value_obitype = update_obitype(value_obitype, value[k]) + + return value_obitype + + +cdef obitype_t get_obitype(object value) : + + if type(value) == dict or type(value) == list or type(value) == tuple : + return get_obitype_iterable_value(value) + + else : + return get_obitype_single_value(value) diff --git a/src/obierrno.h b/src/obierrno.h index e9fb6c0..d1b9717 100644 --- a/src/obierrno.h +++ b/src/obierrno.h @@ -118,6 +118,11 @@ extern int obi_errno; */ #define OBI_ALIGN_ERROR (29) /** Error while aligning sequences */ +#define OBI_LINE_IDX_ERROR (30) /** Error setting or getting a value at a forbidden line index (greater than the line count of the view or the column) + */ +#define OBI_ELT_IDX_ERROR (31) /** Error setting or getting a value at a non-existent element index or with a non-existent element name + */ + /**@}*/ #endif /* OBIERRNO_H_ */