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
This commit is contained in:
Celine Mercier
2017-07-27 19:35:28 +02:00
parent 3d7aa52c90
commit 1a0f18a11a
2 changed files with 53 additions and 25 deletions

View File

@ -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):

View File

@ -20,7 +20,8 @@ from ..capi.obidms cimport OBIDMS_p
from obitools3.utils cimport tobytes, \
str2bytes, \
bytes2str
bytes2str, \
tostr
from ..object cimport OBIObjectClosedInstance
@ -47,7 +48,8 @@ cdef class View(OBIWrapper) :
return <Obiview_p>(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((<Obiview_p>pointer).infos.view_type)
view = OBIWrapper.new(view_class, pointer)
view = OBIWrapper.new_wrapper(view_class, pointer)
view._dms = dms
dms.register(view)
@ -297,19 +299,35 @@ 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):
@ -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)