Skip to content

Commit

Permalink
lib.item: add methods for list/dict manipulation
Browse files Browse the repository at this point in the history
  • Loading branch information
Morg42 committed Feb 24, 2024
1 parent afdb4c2 commit e7e0b19
Showing 1 changed file with 115 additions and 0 deletions.
115 changes: 115 additions & 0 deletions lib/item/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,17 @@ def __init__(self, smarthome, parent, path, config, items_instance=None):
raise AttributeError
self.cast = globals()['cast_' + self._type]

#
# add type methods
#
ext_item_functions = {
'list': ['append', 'prepend', 'insert', 'pop', 'extend', 'clear', 'delete', 'remove'],
'dict': ['get', 'delete', 'clear', 'pop', 'popitem', 'update']
}
if self._type in ['list', 'dict']:
for func in ext_item_functions[self._type]:
setattr(self, func, getattr(self, f'_Item__{self._type}_{func}'))

#############################################################
# Item Attributes
#############################################################
Expand Down Expand Up @@ -1369,6 +1380,110 @@ def _build_trigger_condition_eval(self, trigger_condition):

return result

#
# drop-in functions for list/dict handling
#
# these mimic list/dict modification functions by wrapping around __call__
#
# on item type initialization, only the "matching" method can be inserted
# into the item instance as methods with their respective "original" names,
# i.e. Item.__list__append becomes Item.append
#
# To keep some compatibility, all methods support optional caller, source and
# dest arguments, which are directly passed to __call__
#
# these don't provide error handling as no sensible result would be possible.
# As in using "raw" lists/dicts, errors must be handles by the caller
# (logic, eval, console, ...)
#

# list functions

def __list_append(self, value, caller='Logic', source=None, dest=None):
self.__call__(value, caller, source, dest, index='append')

def __list_prepend(self, value, caller='Logic', source=None, dest=None):
self.__call__(value, caller, source, dest, index='prepend')

def __list_insert(self, index, value, caller='Logic', source=None, dest=None):
tmplist = copy.deepcopy(self._value)
tmplist.insert(index, value)
self.__call__(tmplist, caller, source, dest)

def __list_pop(self, index=None, caller='Logic', source=None, dest=None):
tmplist = copy.deepcopy(self._value)
if index is None:
ret = tmplist.pop()
else:
ret = tmplist.pop(index)
self.__call__(tmplist, caller, source, dest)
return ret

def __list_extend(self, value, caller='Logic', source=None, dest=None):
tmplist = copy.deepcopy(self._value)
tmplist.extend(value)
self.__call__(tmplist, caller, source, dest)

def __list_clear(self, caller='Logic', source=None, dest=None):
self.__call__([], caller, source, dest)

def __list_delete(self, value, caller='Logic', source=None, dest=None):
"""
mimic the del list[x:y] behaviour - supply "x:y" as value
needs to be called delete instead of del for syntax reasons
"""
splits = str(value).count(':')
tmplist = copy.deepcopy(self._value)
if splits == 0:
x = int(value)
del tmplist[x]
if splits == 1:
x, y = [int(i) for i in value.split(':')]
del tmplist[x:y]
elif splits == 2:
x, y, z = [int(i) for i in value.split(':')]
del tmplist[x:y:z]
self.__call__(tmplist, caller, source, dest)

def __list_remove(self, value, caller='Logic', source=None, dest=None):
tmplist = copy.deepcopy(self._value)
tmplist.remove(value)
self.__call__(tmplist, caller, source, dest)

# dict functions

def __dict_get(self, key, caller='Logic', source=None, dest=None, default=None):
return self.__call__(key=key, default=default, caller=caller, source=source, dest=dest)

def __dict_delete(self, key, caller='Logic', source=None, dest=None):
""" needs to be called delete instead of del for syntax reasons """
tmpdict = copy.deepcopy(self._value)
del tmpdict[key]
self.__call__(tmpdict, caller, source, dest)

def __dict_clear(self, caller='Logic', source=None, dest=None):
self.__call__({}, caller, source, dest)

def __dict_pop(self, key, caller='Logic', source=None, dest=None, default=None):
tmpdict = copy.deepcopy(self._value)
ret = tmpdict.pop(key, default)
self.__call__(tmpdict, caller, source, dest)
return ret

def __dict_popitem(self, caller='Logic', source=None, dest=None):
tmpdict = copy.deepcopy(self._value)
ret = tmpdict.popitem()
self.__call__(tmpdict, caller, source, dest)
return ret

def __dict_update(self, value, caller='Logic', source=None, dest=None):
tmpdict = copy.deepcopy(self._value)
tmpdict.update(value)
self.__call__(tmpdict, caller, source, dest)

#
#
#

def __call__(self, value=None, caller='Logic', source=None, dest=None, key=None, index=None, default=None):
# return value
Expand Down

0 comments on commit e7e0b19

Please sign in to comment.