From 1a0f18a11a87a742755e570c9919863f1b104463 Mon Sep 17 00:00:00 2001 From: Celine Mercier Date: Thu, 27 Jul 2017 19:35:28 +0200 Subject: [PATCH] Cython API: added a __setitem__ method to the View class that can detect if the item is a Line and create the corresponding columns if needed + minor changes --- python/obitools3/dms/view/view.pxd | 3 -- python/obitools3/dms/view/view.pyx | 75 +++++++++++++++++++++--------- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/python/obitools3/dms/view/view.pxd b/python/obitools3/dms/view/view.pxd index 90b3799..a2caa97 100644 --- a/python/obitools3/dms/view/view.pxd +++ b/python/obitools3/dms/view/view.pxd @@ -37,9 +37,6 @@ cdef class View(OBIWrapper): cpdef Line_selection new_selection(self, list lines=*) - @staticmethod - cdef type get_view_class(bytes view_type) - cdef class Line_selection(list): diff --git a/python/obitools3/dms/view/view.pyx b/python/obitools3/dms/view/view.pyx index ecfd3a5..d7fa764 100644 --- a/python/obitools3/dms/view/view.pyx +++ b/python/obitools3/dms/view/view.pyx @@ -20,7 +20,8 @@ from ..capi.obidms cimport OBIDMS_p from obitools3.utils cimport tobytes, \ str2bytes, \ - bytes2str + bytes2str, \ + tostr from ..object cimport OBIObjectClosedInstance @@ -39,7 +40,7 @@ from ..capi.obitypes cimport is_a_DNA_seq, \ import importlib import inspect import pkgutil - + cdef class View(OBIWrapper) : @@ -47,7 +48,8 @@ cdef class View(OBIWrapper) : return (self._pointer) @staticmethod - cdef type get_view_class(bytes view_type): + # TODO try cdef again + def get_view_class(bytes view_type): global __VIEW_CLASS__ return __VIEW_CLASS__.get(view_type, View) @@ -79,7 +81,7 @@ cdef class View(OBIWrapper) : message = "Error : Cannot create view %s" % bytes2str(view_name_b) raise RuntimeError(message) - view = OBIWrapper.new(View, pointer) + view = OBIWrapper.new_wrapper(View, pointer) view._dms = dms dms.register(view) @@ -116,7 +118,7 @@ cdef class View(OBIWrapper) : bytes2str(view_name_b)) ) - view = OBIWrapper.new(type(self), pointer) + view = OBIWrapper.new_wrapper(type(self), pointer) view._dms = self._dms self._dms.register(view) @@ -139,7 +141,7 @@ cdef class View(OBIWrapper) : raise RuntimeError("Error : Cannot open view %s" % bytes2str(view_name_b)) view_class = View.get_view_class((pointer).infos.view_type) - view = OBIWrapper.new(view_class, pointer) + view = OBIWrapper.new_wrapper(view_class, pointer) view._dms = dms dms.register(view) @@ -297,21 +299,37 @@ cdef class View(OBIWrapper) : # Declarations cdef index_t line_nb - cdef Line line # Yield each line for line_nb in range(self.line_count) : - line = self[line_nb] - yield line + yield Line(self, line_nb) - def __getitem__(self, object item) : - if type(item) == int : - return Line(self, item) - else : # TODO assume str or bytes for optimization? - return self.get_column(item) # TODO hyper lent dans la pratique + def __getitem__(self, object ref) : + if type(ref) == int : + return Line(self, ref) + else : # TODO assume str or bytes for optimization (discuss) + return self.get_column(ref) # TODO hyper lent dans la pratique + def __setitem__(self, index_t idx, object item) : + cdef Column col + line = self[idx] + for k in item : + # If setting from another View Line and the column doesn't exist, create it based on the informations from the other View + if isinstance(item, Line) and tostr(k) not in self: + col = item.view[k] + Column.new_column(self, + col.original_name, + col.data_type_int, + nb_elements_per_line = col.nb_elements_per_line, + elements_names = col.elements_names, + comments = col.comments, + alias=k + ) + line[k] = item[k] + + def __contains__(self, str column_name): return (column_name in self.keys()) @@ -374,16 +392,18 @@ cdef class Line : def __getitem__(self, str column_name) : - return (self._view)[column_name][self._index] + return (self._view).get_column(column_name)[self._index] - def __setitem__(self, str column_name, object value): # TODO discuss + def __setitem__(self, object column_name_, object value): # TODO discuss # TODO detect multiple elements (dict type)? put somewhere else? but more risky (in get) # TODO OBI_QUAL ? cdef type value_type cdef obitype_t value_obitype cdef bytes value_b - + + column_name = tostr(column_name_) # TODO + if column_name not in self._view : if value == None : raise Exception("Trying to create a column from a None value (can't guess type)") @@ -410,17 +430,18 @@ cdef class Line : Column.new_column(self._view, column_name, value_obitype) - (self._view)[column_name][self._index] = value + (self._view).get_column(column_name).set_line(self._index, value) def __iter__(self): for column_name in (self._view).keys() : - yield self[column_name] + yield column_name + def keys(self): + return self._view.keys() def __contains__(self, str column_name): - return (column_name in self._view.keys()) - + return (column_name in self.keys()) def __repr__(self): cdef dict line @@ -430,6 +451,16 @@ cdef class Line : line[column_name] = self[column_name] return str(line) + # View property getter + @property + def view(self): + return self._view + + # index property getter + @property + def index(self): + return self._index + # cpdef dict get_view_infos(self, str view_name) : # @@ -547,7 +578,7 @@ cdef class Line_selection(list): bytes2str(view_name_b)) ) - view = OBIWrapper.new(type(self._view), pointer) + view = OBIWrapper.new_wrapper(type(self._view), pointer) view._dms = self._view._dms view._dms.register(view)