diff --git a/python/obitools3/dms/dms.pyx b/python/obitools3/dms/dms.pyx index 7658c13..b5dd5df 100644 --- a/python/obitools3/dms/dms.pyx +++ b/python/obitools3/dms/dms.pyx @@ -27,6 +27,8 @@ from obitools3.utils cimport bytes2str, \ str2bytes, \ tobytes, \ tostr + +from .object cimport OBIObjectClosedInstance from pathlib import Path @@ -74,18 +76,6 @@ cdef class DMS(OBIObject): if self._pointer == NULL : raise Exception("Failed opening or creating an OBIDMS") - - - def __dealloc__(self): - """ - Destructor of the DMS instance. - - The destructor automatically call the `close` method and - therefore free all the associated memory. - """ - - self.close() - self._pointer=NULL # name property getter @property @@ -103,9 +93,13 @@ cdef class DMS(OBIObject): the `close` method is automatically called by the object destructor. """ + cdef OBIDMS_p pointer = self._pointer - if self._pointer!=NULL: - if (obi_close_dms(self._pointer)) < 0 : + OBIObject.close(self) + self._pointer=NULL + + if pointer!=NULL: + if (obi_close_dms(pointer)) < 0 : raise Exception("Problem closing an OBIDMS") else: raise OBIObjectClosedInstance() diff --git a/python/obitools3/dms/object.pxd b/python/obitools3/dms/object.pxd index 50cbe6c..1ec2513 100644 --- a/python/obitools3/dms/object.pxd +++ b/python/obitools3/dms/object.pxd @@ -4,6 +4,7 @@ cdef class OBIObject: cdef dict _dependent_object cpdef register(self, OBIObject object) + cpdef unregister(self, OBIObject object) cpdef close(self) cdef class OBIObjectClosedInstance(Exception): diff --git a/python/obitools3/dms/object.pyx b/python/obitools3/dms/object.pyx index 43bd21c..f73fba7 100644 --- a/python/obitools3/dms/object.pyx +++ b/python/obitools3/dms/object.pyx @@ -5,12 +5,18 @@ cdef class OBIObject: cpdef register(self, OBIObject object): self._dependent_object[id(object)]=object - cpdef close(self): + cpdef unregister(self, OBIObject object): + del self._dependent_object[id(object)] + + def close(self): cdef OBIObject object + cdef list toclose = list(self._dependent_object.values()) - for object in self._dependent_object.values(): + for object in toclose: object.close() + assert len(dependent_object.values)==0 + def __init__(self): self._dependent_object={} diff --git a/python/obitools3/dms/view/view.pxd b/python/obitools3/dms/view/view.pxd index 6806e2a..8963744 100644 --- a/python/obitools3/dms/view/view.pxd +++ b/python/obitools3/dms/view/view.pxd @@ -3,13 +3,15 @@ from ..capi.obiview cimport Obiview_p from ..capi.obitypes cimport index_t, \ obitype_t - + +from ..object cimport OBIObject from ..dms cimport DMS + from ..column.column cimport Column -cdef class View: +cdef class View(OBIObject): cdef DMS _dms cdef Obiview_p _pointer diff --git a/python/obitools3/dms/view/view.pyx b/python/obitools3/dms/view/view.pyx index d1b6287..7715386 100644 --- a/python/obitools3/dms/view/view.pyx +++ b/python/obitools3/dms/view/view.pyx @@ -16,13 +16,17 @@ from .dms cimport __OBIDMS_VIEW_CLASS__ from obitools3.utils cimport tobytes, \ bytes2str - + +from ..object cimport OBIObjectClosedInstance + -cdef class View : +cdef class View(OBIObject) : def __init__(self,dms,int __internalCall__): + OBIObject.__init__(self) + if __internalCall__!=987654: raise RuntimeError('OBIView constructor cannot be called directly') @@ -55,6 +59,8 @@ cdef class View : % (str(self.name), bytes2str(view_name_b)) ) + + self._dms.register(view) return view @@ -85,6 +91,8 @@ cdef class View : message = "Error : Cannot create view %s" % bytes2str(view_name_b) raise RuntimeError(message) + dms.register(view) + return view @staticmethod @@ -101,16 +109,25 @@ cdef class View : if view._pointer == NULL : raise RuntimeError("Error : Cannot open view %s" % bytes2str(view_name_b)) + dms.register(view) + return view def close(self): - if (self._pointer != NULL): + cdef Obiview_p pointer = self._pointer + + if (pointer != NULL): + self._dms.unregister(self) + OBIObject.close(self) + + self._pointer = NULL + if obi_save_and_close_view(self._pointer) < 0 : raise Exception("Problem closing view %s" % bytes2str(self.name)) + else: + raise OBIObjectClosedInstance() - def __dealloc__(self): - self.close() def __repr__(self) : cdef str s = "{name:s}\n{comments:s}\n{line_count:d} lines\n".format(name = str(self.name),