diff --git a/python/obitools3/dms/column/bool.pyx b/python/obitools3/dms/column/bool.pyx index 20d3328..5556ff0 100644 --- a/python/obitools3/dms/column/bool.pyx +++ b/python/obitools3/dms/column/bool.pyx @@ -190,19 +190,26 @@ cdef class OBIDMS_column_line_bool(OBIDMS_column_line) : -cdef class OBIDMS_column_bool(OBIDMS_column): +cdef class Column_bool(Column): @staticmethod - cdef OBIDMS_column _new(OBIView view, - bytes column_name, - index_t nb_elements_per_line=1, - object elements_names=None, - bytes comments=b""): + def new(OBIView view, + object column_name, + index_t nb_elements_per_line=1, + object elements_names=None, + object comments=b""): + cdef bytes column_name_b = tobytes(column_name) + cdef bytes comments_b cdef bytes elements_names_b cdef char* elements_names_p cdef OBIDMS_column new_column + if comments is not None: + comments_b = tobytes(comments) + else: + comments_b = b'' + if elements_names is not None: elements_names_b = b''.join([tobytes(x) for x in elements_names]) elements_names_p = elements_names_b @@ -210,7 +217,7 @@ cdef class OBIDMS_column_bool(OBIDMS_column): elements_names_p = NULL if (obi_view_add_column(view = view._pointer, - column_name = column_name, + column_name = column_name_b, version_number = -1, alias = NULL, data_type = OBI_BOOL, @@ -220,7 +227,7 @@ cdef class OBIDMS_column_bool(OBIDMS_column): indexer_name = NULL, associated_column_name = NULL, associated_column_version = -1, - comments = comments, + comments = comments_b, create = True)<0): raise RuntimeError("Cannot create column %s in view %s" % (bytes2str(column_name), bytes2str(view.name))) @@ -229,24 +236,11 @@ cdef class OBIDMS_column_bool(OBIDMS_column): new_column = self._columns[column_name] return new_column - - @staticmethod - def new(OBIView view, - object column_name, - index_t nb_elements_per_line=1, - object elements_names=None, - object comments=b""): - - return OBIDMS_column_bool._new(view, - tobytes(column_name), - nb_elements_per_line, - elements_names, - tobytes(comments)) - - cpdef add_to_view(self, - OBIView view, - object column_name=None, - object comments=b""): + + def add_to_view(self, + OBIView view, + object column_name=None, + object comments=b""): cdef OBIDMS_column_p column_p = self._column_pp[0] cdef bytes alias @@ -256,19 +250,25 @@ cdef class OBIDMS_column_bool(OBIDMS_column): else: alias = tobytes(column_name) - obi_view_add_column(view = view._ponter, - column_name = column_p.header.name, - version_number = column_p.header.version, - alias = alias, - data_type = OBI_BOOL, - nb_lines = column_p.header.lines_used, - nb_elements_per_line = column_p.header.nb_elements_per_line, - elements_names = column_p.header.elements_names, - indexer_name = NULL, - associated_column_name = NULL, - associated_column_version = NULL, - comments = tobytes(comments), - create = False) + if (obi_view_add_column(view = view._ponter, + column_name = column_p.header.name, + version_number = column_p.header.version, + alias = alias, + data_type = OBI_BOOL, + nb_lines = column_p.header.lines_used, + nb_elements_per_line = column_p.header.nb_elements_per_line, + elements_names = column_p.header.elements_names, + indexer_name = NULL, + associated_column_name = NULL, + associated_column_version = NULL, + comments = tobytes(comments), + create = False) < 0): + raise RuntimeError("Cannot insert column %s (%s@%d) into view %s" % + ( bytes2str(alias), + bytes2str(column_p.header.name), + column_p.header.version, + bytes2str(view.name) + )) cpdef object get_line(self, index_t line_nb): cdef obibool_t value @@ -291,4 +291,4 @@ cdef class OBIDMS_column_bool(OBIDMS_column): raise Exception("Problem setting a value in a column") -register_column_class(OBI_BOOL,OBIDMS_column_bool) \ No newline at end of file +register_column_class(OBI_BOOL,Column_bool,bool) \ No newline at end of file diff --git a/python/obitools3/dms/dms.pxd b/python/obitools3/dms/dms.pxd index cc11ef2..07ec4b1 100644 --- a/python/obitools3/dms/dms.pxd +++ b/python/obitools3/dms/dms.pxd @@ -4,11 +4,13 @@ from .capi.obidms cimport OBIDMS_p from .capi.obitypes cimport obiversion_t, \ obitype_t, \ index_t + +from .object cimport OBIObject cdef dict __OBIDMS_COLUMN_CLASS__ cdef dict __OBIDMS_VIEW_CLASS__ -cdef class DMS: +cdef class DMS(OBIObject): cdef OBIDMS_p _pointer diff --git a/python/obitools3/dms/dms.pyx b/python/obitools3/dms/dms.pyx index e0de92e..7658c13 100644 --- a/python/obitools3/dms/dms.pyx +++ b/python/obitools3/dms/dms.pyx @@ -33,7 +33,7 @@ from pathlib import Path __OBIDMS_COLUMN_CLASS__ = {} __OBIDMS_VIEW_CLASS__= {} -cdef class DMS : +cdef class DMS(OBIObject): @staticmethod cdef type get_column_class(obitype_t obitype): @@ -64,6 +64,8 @@ cdef class DMS : @type dms_name: a `str` or a `bytes` instance ''' + OBIObject.__init__(self) + # Declarations cdef bytes dms_name_b = tobytes(dms_name) @@ -95,16 +97,19 @@ cdef class DMS : """ return self._pointer.dms_name - cpdef close(self) : + def close(self) : """ Closes the DNS instance and free the associated memory the `close` method is automatically called by the object destructor. """ - if (obi_close_dms(self._pointer)) < 0 : - raise Exception("Problem closing an OBIDMS") - + if self._pointer!=NULL: + if (obi_close_dms(self._pointer)) < 0 : + raise Exception("Problem closing an OBIDMS") + else: + raise OBIObjectClosedInstance() + def keys(self): cdef const_char_p path = obi_dms_get_full_path(self._pointer, b"VIEWS" diff --git a/python/obitools3/dms/object.pxd b/python/obitools3/dms/object.pxd new file mode 100644 index 0000000..50cbe6c --- /dev/null +++ b/python/obitools3/dms/object.pxd @@ -0,0 +1,10 @@ +#cython: language_level=3 + +cdef class OBIObject: + cdef dict _dependent_object + + cpdef register(self, OBIObject object) + cpdef close(self) + +cdef class OBIObjectClosedInstance(Exception): + pass \ No newline at end of file diff --git a/python/obitools3/dms/object.pyx b/python/obitools3/dms/object.pyx new file mode 100644 index 0000000..43bd21c --- /dev/null +++ b/python/obitools3/dms/object.pyx @@ -0,0 +1,28 @@ +#cython: language_level=3 + +cdef class OBIObject: + + cpdef register(self, OBIObject object): + self._dependent_object[id(object)]=object + + cpdef close(self): + cdef OBIObject object + + for object in self._dependent_object.values(): + object.close() + + def __init__(self): + self._dependent_object={} + + def __dealloc__(self): + """ + Destructor of the DMS instance. + + The destructor automatically call the `close` method and + therefore free all the associated memory. + """ + + self.close() + +cdef class OBIObjectClosedInstance(Exception): + pass