mirror of
https://github.com/yweber/lodel2.git
synced 2025-11-02 04:20:55 +01:00
Code cleaning
This commit is contained in:
parent
283fa4a3cc
commit
822ad1bea2
1 changed files with 142 additions and 135 deletions
|
|
@ -19,7 +19,7 @@ LodelContext.expose_modules(globals(), {
|
||||||
'DataNoneValid',
|
'DataNoneValid',
|
||||||
'FieldValidationError'
|
'FieldValidationError'
|
||||||
],
|
],
|
||||||
'lodel.mlnamedobject.mlnamedobject':['MlNamedObject'],
|
'lodel.mlnamedobject.mlnamedobject': ['MlNamedObject'],
|
||||||
'lodel.leapi.datahandlers.exceptions': [
|
'lodel.leapi.datahandlers.exceptions': [
|
||||||
'LodelDataHandlerConsistencyException',
|
'LodelDataHandlerConsistencyException',
|
||||||
'LodelDataHandlerException'
|
'LodelDataHandlerException'
|
||||||
|
|
@ -30,14 +30,14 @@ LodelContext.expose_modules(globals(), {
|
||||||
'lodel.logger': 'logger'})
|
'lodel.logger': 'logger'})
|
||||||
|
|
||||||
|
|
||||||
##@brief Base class for all data handlers
|
## @brief Base class for all data handlers
|
||||||
#@ingroup lodel2_datahandlers
|
# @ingroup lodel2_datahandlers
|
||||||
class DataHandler(MlNamedObject):
|
class DataHandler(MlNamedObject):
|
||||||
base_type = "type"
|
base_type = "type"
|
||||||
_HANDLERS_MODULES = ('datas_base', 'datas', 'references')
|
_HANDLERS_MODULES = ('datas_base', 'datas', 'references')
|
||||||
##@brief Stores the DataHandler childs classes indexed by name
|
## @brief Stores the DataHandler childs classes indexed by name
|
||||||
_base_handlers = None
|
_base_handlers = None
|
||||||
##@brief Stores custom datahandlers classes indexed by name
|
## @brief Stores custom datahandlers classes indexed by name
|
||||||
# @todo do it ! (like plugins, register handlers... blablabla)
|
# @todo do it ! (like plugins, register handlers... blablabla)
|
||||||
__custom_handlers = dict()
|
__custom_handlers = dict()
|
||||||
|
|
||||||
|
|
@ -46,15 +46,16 @@ class DataHandler(MlNamedObject):
|
||||||
options_spec = dict()
|
options_spec = dict()
|
||||||
options_values = dict()
|
options_values = dict()
|
||||||
|
|
||||||
##@brief List fields that will be exposed to the construct_data_method
|
## @brief List fields that will be exposed to the construct_data_method
|
||||||
_construct_datas_deps = []
|
_construct_datas_deps = []
|
||||||
|
|
||||||
directly_editable = True
|
directly_editable = True
|
||||||
##@brief constructor
|
|
||||||
|
## @brief constructor
|
||||||
|
#
|
||||||
# @param internal False | str : define whether or not a field is internal
|
# @param internal False | str : define whether or not a field is internal
|
||||||
# @param immutable bool : indicates if the fieldtype has to be defined in child classes of LeObject or if it is
|
# @param immutable bool : indicates if the fieldtype has to be defined in child classes of
|
||||||
# designed globally and immutable
|
# LeObject or if it is designed globally and immutable
|
||||||
# @param **args
|
|
||||||
# @throw NotImplementedError if it is instanciated directly
|
# @throw NotImplementedError if it is instanciated directly
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
if self.__class__ == DataHandler:
|
if self.__class__ == DataHandler:
|
||||||
|
|
@ -69,22 +70,24 @@ class DataHandler(MlNamedObject):
|
||||||
self.default, error = self.check_data_value(kwargs['default'])
|
self.default, error = self.check_data_value(kwargs['default'])
|
||||||
if error:
|
if error:
|
||||||
raise error
|
raise error
|
||||||
del(kwargs['default'])
|
del kwargs['default']
|
||||||
for argname, argval in kwargs.items():
|
for argname, argval in kwargs.items():
|
||||||
setattr(self, argname, argval)
|
setattr(self, argname, argval)
|
||||||
self.check_options()
|
self.check_options()
|
||||||
super().__init__(self.display_name, self.help_text)
|
super().__init__(self.display_name, self.help_text)
|
||||||
|
|
||||||
## @brief Sets properly casted and checked options for the datahandler
|
## @brief Sets properly casted and checked options for the datahandler
|
||||||
# @raises LodelDataHandlerNotAllowedOptionException when a passed option is not in the option specifications of the datahandler
|
# @raises LodelDataHandlerNotAllowedOptionException when a passed option is not in the option
|
||||||
|
# specifications of the datahandler
|
||||||
def check_options(self):
|
def check_options(self):
|
||||||
for option_name, option_datas in self.options_spec.items():
|
for option_name, option_datas in self.options_spec.items():
|
||||||
if option_name in self.options_values:
|
if option_name in self.options_values:
|
||||||
# There is a configured option, we check its value
|
# There is a configured option, we check its value
|
||||||
try:
|
try:
|
||||||
self.options_values[option_name] = option_datas[1].check_value(self.options_values[option_name])
|
self.options_values[option_name] = option_datas[1].check_value(
|
||||||
|
self.options_values[option_name])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass # TODO Deal with the case where the value used for an option has not been validated
|
pass # TODO Deal with the case where the value used for an option is invalid
|
||||||
else:
|
else:
|
||||||
# This option was not configured, we get the default value from the specs
|
# This option was not configured, we get the default value from the specs
|
||||||
self.options_values[option_name] = option_datas[0]
|
self.options_values[option_name] = option_datas[0]
|
||||||
|
|
@ -105,15 +108,15 @@ class DataHandler(MlNamedObject):
|
||||||
def is_primary_key(self):
|
def is_primary_key(self):
|
||||||
return self.primary_key
|
return self.primary_key
|
||||||
|
|
||||||
##@brief checks if a fieldtype is internal
|
## @brief checks if a fieldtype is internal
|
||||||
# @return bool
|
# @return bool
|
||||||
def is_internal(self):
|
def is_internal(self):
|
||||||
return self.internal is not False
|
return self.internal is not False
|
||||||
|
|
||||||
##brief check if a value can be nullable
|
## @brief check if a value can be nullable
|
||||||
#@param value *
|
# @param value *
|
||||||
#@throw DataNoneValid if value is None and nullable. LodelExceptions if not nullable
|
# @throw DataNoneValid if value is None and nullable. LodelExceptions if not nullable
|
||||||
#@return value (if not None)
|
# @return value (if not None)
|
||||||
# @return value
|
# @return value
|
||||||
def _check_data_value(self, value):
|
def _check_data_value(self, value):
|
||||||
if value is None:
|
if value is None:
|
||||||
|
|
@ -122,9 +125,9 @@ class DataHandler(MlNamedObject):
|
||||||
raise DataNoneValid("None with a nullable. This exeption is allowed")
|
raise DataNoneValid("None with a nullable. This exeption is allowed")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
##@brief calls the data_field (defined in derived class) _check_data_value() method
|
## @brief calls the data_field (defined in derived class) _check_data_value() method
|
||||||
#@param value *
|
# @param value *
|
||||||
#@return tuple (value|None, None|error) value can be cast if NoneError
|
# @return tuple (value|None, None|error) value can be cast if NoneError
|
||||||
def check_data_value(self, value):
|
def check_data_value(self, value):
|
||||||
try:
|
try:
|
||||||
value = self._check_data_value(value)
|
value = self._check_data_value(value)
|
||||||
|
|
@ -134,7 +137,7 @@ class DataHandler(MlNamedObject):
|
||||||
return None, expt
|
return None, expt
|
||||||
return value, None
|
return value, None
|
||||||
|
|
||||||
##@brief checks if this class can override the given data handler
|
## @brief checks if this class can override the given data handler
|
||||||
# @param data_handler DataHandler
|
# @param data_handler DataHandler
|
||||||
# @return bool
|
# @return bool
|
||||||
def can_override(self, data_handler):
|
def can_override(self, data_handler):
|
||||||
|
|
@ -142,17 +145,17 @@ class DataHandler(MlNamedObject):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
##@brief Build field value
|
## @brief Build field value
|
||||||
#@ingroup lodel2_dh_checks
|
# @ingroup lodel2_dh_checks
|
||||||
#@warning DO NOT REIMPLEMENT THIS METHOD IN A CUSTOM DATAHANDLER (see
|
# @warning DO NOT REIMPLEMENT THIS METHOD IN A CUSTOM DATAHANDLER (see
|
||||||
#@ref _construct_data() and @ref lodel2_dh_check_impl )
|
# @ref _construct_data() and @ref lodel2_dh_check_impl )
|
||||||
#@param emcomponent EmComponent : An EmComponent child class instance
|
# @param emcomponent EmComponent : An EmComponent child class instance
|
||||||
#@param fname str : The field name
|
# @param fname str : The field name
|
||||||
#@param datas dict : dict storing fields values (from the component)
|
# @param datas dict : dict storing fields values (from the component)
|
||||||
#@param cur_value : the value from the current field (identified by fieldname)
|
# @param cur_value : the value from the current field (identified by fieldname)
|
||||||
#@return the value
|
# @return the value
|
||||||
#@throw RunTimeError if data construction fails
|
# @throw RunTimeError if data construction fails
|
||||||
#@todo raise something else
|
# @todo raise something else
|
||||||
def construct_data(self, emcomponent, fname, datas, cur_value):
|
def construct_data(self, emcomponent, fname, datas, cur_value):
|
||||||
emcomponent_fields = emcomponent.fields()
|
emcomponent_fields = emcomponent.fields()
|
||||||
data_handler = None
|
data_handler = None
|
||||||
|
|
@ -167,41 +170,41 @@ class DataHandler(MlNamedObject):
|
||||||
new_val = None
|
new_val = None
|
||||||
return self._construct_data(emcomponent, fname, datas, new_val)
|
return self._construct_data(emcomponent, fname, datas, new_val)
|
||||||
|
|
||||||
##@brief Designed to be reimplemented by child classes
|
## @brief Designed to be reimplemented by child classes
|
||||||
#@param emcomponent EmComponent : An EmComponent child class instance
|
# @param emcomponent EmComponent : An EmComponent child class instance
|
||||||
#@param fname str : The field name
|
# @param fname str : The field name
|
||||||
#@param datas dict : dict storing fields values (from the component)
|
# @param datas dict : dict storing fields values (from the component)
|
||||||
#@param cur_value : the value from the current field (identified by fieldname)
|
# @param cur_value : the value from the current field (identified by fieldname)
|
||||||
#@return the value
|
# @return the value
|
||||||
#@see construct_data() lodel2_dh_check_impl
|
# @see construct_data() lodel2_dh_check_impl
|
||||||
def _construct_data(self, empcomponent, fname, datas, cur_value):
|
def _construct_data(self, empcomponent, fname, datas, cur_value):
|
||||||
return cur_value
|
return cur_value
|
||||||
|
|
||||||
##@brief Check datas consistency
|
## @brief Check datas consistency
|
||||||
#@ingroup lodel2_dh_checks
|
# @ingroup lodel2_dh_checks
|
||||||
#@warning DO NOT REIMPLEMENT THIS METHOD IN A CUSTOM DATAHANDLER (see
|
# @warning DO NOT REIMPLEMENT THIS METHOD IN A CUSTOM DATAHANDLER (see
|
||||||
#@ref _construct_data() and @ref lodel2_dh_check_impl )
|
# @ref _construct_data() and @ref lodel2_dh_check_impl )
|
||||||
#@warning the datas argument looks like a dict but is not a dict
|
# @warning the datas argument looks like a dict but is not a dict
|
||||||
#see @ref base_classes.DatasConstructor "DatasConstructor" and
|
# see @ref base_classes.DatasConstructor "DatasConstructor" and
|
||||||
#@ref lodel2_dh_datas_construction "Datas construction section"
|
# @ref lodel2_dh_datas_construction "Datas construction section"
|
||||||
#@param emcomponent EmComponent : An EmComponent child class instance
|
# @param emcomponent EmComponent : An EmComponent child class instance
|
||||||
#@param fname : the field name
|
# @param fname : the field name
|
||||||
#@param datas dict : dict storing fields values
|
# @param datas dict : dict storing fields values
|
||||||
#@return an Exception instance if fails else True
|
# @return an Exception instance if fails else True
|
||||||
#@todo A implémenter
|
# @todo A implémenter
|
||||||
def check_data_consistency(self, emcomponent, fname, datas):
|
def check_data_consistency(self, emcomponent, fname, datas):
|
||||||
return self._check_data_consistency(emcomponent, fname, datas)
|
return self._check_data_consistency(emcomponent, fname, datas)
|
||||||
|
|
||||||
##@brief Designed to be reimplemented by child classes
|
## @brief Designed to be reimplemented by child classes
|
||||||
#@param emcomponent EmComponent : An EmComponent child class instance
|
# @param emcomponent EmComponent : An EmComponent child class instance
|
||||||
#@param fname : the field name
|
# @param fname : the field name
|
||||||
#@param datas dict : dict storing fields values
|
# @param datas dict : dict storing fields values
|
||||||
#@return an Exception instance if fails else True
|
# @return an Exception instance if fails else True
|
||||||
#@see check_data_consistency() lodel2_dh_check_impl
|
# @see check_data_consistency() lodel2_dh_check_impl
|
||||||
def _check_data_consistency(self, emcomponent, fname, datas):
|
def _check_data_consistency(self, emcomponent, fname, datas):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
##@brief make consistency after a query
|
## @brief make consistency after a query
|
||||||
# @param emcomponent EmComponent : An EmComponent child class instance
|
# @param emcomponent EmComponent : An EmComponent child class instance
|
||||||
# @param fname : the field name
|
# @param fname : the field name
|
||||||
# @param datas dict : dict storing fields values
|
# @param datas dict : dict storing fields values
|
||||||
|
|
@ -210,7 +213,7 @@ class DataHandler(MlNamedObject):
|
||||||
def make_consistency(self, emcomponent, fname, datas):
|
def make_consistency(self, emcomponent, fname, datas):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
##@brief This method is use by plugins to register new data handlers
|
## @brief This method is use by plugins to register new data handlers
|
||||||
@classmethod
|
@classmethod
|
||||||
def register_new_handler(cls, name, data_handler):
|
def register_new_handler(cls, name, data_handler):
|
||||||
if not inspect.isclass(data_handler):
|
if not inspect.isclass(data_handler):
|
||||||
|
|
@ -219,7 +222,7 @@ class DataHandler(MlNamedObject):
|
||||||
raise ValueError("A data handler HAS TO be a child class of DataHandler")
|
raise ValueError("A data handler HAS TO be a child class of DataHandler")
|
||||||
cls.__custom_handlers[name] = data_handler
|
cls.__custom_handlers[name] = data_handler
|
||||||
|
|
||||||
##@brief Load all datahandlers
|
## @brief Load all datahandlers
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_base_handlers(cls):
|
def load_base_handlers(cls):
|
||||||
if cls._base_handlers is None:
|
if cls._base_handlers is None:
|
||||||
|
|
@ -232,10 +235,11 @@ class DataHandler(MlNamedObject):
|
||||||
cls._base_handlers[name.lower()] = obj
|
cls._base_handlers[name.lower()] = obj
|
||||||
return copy.copy(cls._base_handlers)
|
return copy.copy(cls._base_handlers)
|
||||||
|
|
||||||
##@brief given a field type name, returns the associated python class
|
## @brief given a field type name, returns the associated python class
|
||||||
# @param fieldtype_name str : A field type name (not case sensitive)
|
# @param fieldtype_name str : A field type name (not case sensitive)
|
||||||
# @return DataField child class
|
# @return DataField child class
|
||||||
# @note To access custom data handlers it can be cool to prefix the handler name by plugin name for example ? (to ensure name unicity)
|
# @note To access custom data handlers it can be cool to prefix the handler name by plugin
|
||||||
|
# name for example ? (to ensure name unicity)
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_name(cls, name):
|
def from_name(cls, name):
|
||||||
cls.load_base_handlers()
|
cls.load_base_handlers()
|
||||||
|
|
@ -245,7 +249,7 @@ class DataHandler(MlNamedObject):
|
||||||
raise NameError("No data handlers named '%s'" % (name,))
|
raise NameError("No data handlers named '%s'" % (name,))
|
||||||
return all_handlers[name]
|
return all_handlers[name]
|
||||||
|
|
||||||
##@brief Return the module name to import in order to use the datahandler
|
## @brief Return the module name to import in order to use the datahandler
|
||||||
# @param data_handler_name str : Data handler name
|
# @param data_handler_name str : Data handler name
|
||||||
# @return a str
|
# @return a str
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
@ -253,62 +257,64 @@ class DataHandler(MlNamedObject):
|
||||||
name = name.lower()
|
name = name.lower()
|
||||||
handler_class = cls.from_name(name)
|
handler_class = cls.from_name(name)
|
||||||
return '{module_name}.{class_name}'.format(
|
return '{module_name}.{class_name}'.format(
|
||||||
module_name=handler_class.__module__,
|
module_name=handler_class.__module__,
|
||||||
class_name=handler_class.__name__
|
class_name=handler_class.__name__
|
||||||
)
|
)
|
||||||
|
|
||||||
##@brief __hash__ implementation for fieldtypes
|
## @brief __hash__ implementation for fieldtypes
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
hash_dats = [self.__class__.__module__]
|
hash_dats = [self.__class__.__module__]
|
||||||
for kdic in sorted([k for k in self.__dict__.keys() if not k.startswith('_')]):
|
for kdic in sorted([k for k in self.__dict__.keys() if not k.startswith('_')]):
|
||||||
hash_dats.append((kdic, getattr(self, kdic)))
|
hash_dats.append((kdic, getattr(self, kdic)))
|
||||||
return hash(tuple(hash_dats))
|
return hash(tuple(hash_dats))
|
||||||
|
|
||||||
##@brief Base class for datas data handler (by opposition with references)
|
## @brief Base class for datas data handler (by opposition with references)
|
||||||
#@ingroup lodel2_datahandlers
|
# @ingroup lodel2_datahandlers
|
||||||
class DataField(DataHandler):
|
class DataField(DataHandler):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
##@brief Abstract class for all references
|
|
||||||
#@ingroup lodel2_datahandlers
|
## @brief Abstract class for all references
|
||||||
|
# @ingroup lodel2_datahandlers
|
||||||
#
|
#
|
||||||
# References are fields that stores a reference to another
|
# References are fields that stores a reference to another
|
||||||
# editorial object
|
# editorial object
|
||||||
#@todo Construct data implementation : transform the data into a LeObject
|
# @todo Construct data implementation : transform the data into a LeObject instance
|
||||||
#instance
|
|
||||||
|
|
||||||
class Reference(DataHandler):
|
class Reference(DataHandler):
|
||||||
base_type = "ref"
|
base_type = "ref"
|
||||||
|
|
||||||
##@brief Instanciation
|
## @brief Instanciation
|
||||||
# @param allowed_classes list | None : list of allowed em classes if None no restriction
|
# @param allowed_classes list | None : list of allowed em classes if None no restriction
|
||||||
# @param back_reference tuple | None : tuple containing (LeObject child class, fieldname)
|
# @param back_reference tuple | None : tuple containing (LeObject child class, fieldname)
|
||||||
# @param internal bool : if False, the field is not internal
|
# @param internal bool : if False, the field is not internal
|
||||||
# @param **kwargs : other arguments
|
# @param **kwargs : other arguments
|
||||||
def __init__(self, allowed_classes=None, back_reference=None, internal=False, **kwargs):
|
def __init__(self, allowed_classes=None, back_reference=None, internal=False, **kwargs):
|
||||||
self.__allowed_classes = set() if allowed_classes is None else set(allowed_classes)
|
self.__allowed_classes = set() if allowed_classes is None else set(allowed_classes)
|
||||||
self.allowed_classes = list() if allowed_classes is None else allowed_classes # For now usefull to jinja 2
|
# For now usefull to jinja 2
|
||||||
|
self.allowed_classes = list() if allowed_classes is None else allowed_classes
|
||||||
if back_reference is not None:
|
if back_reference is not None:
|
||||||
if len(back_reference) != 2:
|
if len(back_reference) != 2:
|
||||||
raise ValueError("A tuple (classname, fieldname) expected but got '%s'" % back_reference)
|
raise ValueError("A tuple (classname, fieldname) expected but got '%s'" % back_reference)
|
||||||
#if not issubclass(lodel.leapi.leobject.LeObject, back_reference[0]) or not isinstance(back_reference[1], str):
|
# if not issubclass(lodel.leapi.leobject.LeObject, back_reference[0])
|
||||||
# raise TypeError("Back reference was expected to be a tuple(<class LeObject>, str) but got : (%s, %s)" % (back_reference[0], back_reference[1]))
|
# or not isinstance(back_reference[1], str):
|
||||||
|
# raise TypeError("Back reference was expected to be a tuple(<class LeObject>, str)
|
||||||
|
# but got : (%s, %s)" % (back_reference[0], back_reference[1]))
|
||||||
self.__back_reference = back_reference
|
self.__back_reference = back_reference
|
||||||
super().__init__(internal=internal, **kwargs)
|
super().__init__(internal=internal, **kwargs)
|
||||||
|
|
||||||
##@brief Method designed to return an empty value for this kind of
|
## @brief Method designed to return an empty value for this kind of
|
||||||
#multipleref
|
# multipleref
|
||||||
@classmethod
|
@classmethod
|
||||||
def empty(cls):
|
def empty(cls):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
##@brief Property that takes value of a copy of the back_reference tuple
|
## @brief Property that takes value of a copy of the back_reference tuple
|
||||||
@property
|
@property
|
||||||
def back_reference(self):
|
def back_reference(self):
|
||||||
return copy.copy(self.__back_reference)
|
return copy.copy(self.__back_reference)
|
||||||
|
|
||||||
##@brief Property that takes value of datahandler of the backreference or
|
## @brief Property that takes value of datahandler of the backreference or
|
||||||
#None
|
# None
|
||||||
@property
|
@property
|
||||||
def back_ref_datahandler(self):
|
def back_ref_datahandler(self):
|
||||||
if self.__back_reference is None:
|
if self.__back_reference is None:
|
||||||
|
|
@ -319,15 +325,15 @@ class Reference(DataHandler):
|
||||||
def linked_classes(self):
|
def linked_classes(self):
|
||||||
return copy.copy(self.__allowed_classes)
|
return copy.copy(self.__allowed_classes)
|
||||||
|
|
||||||
##@brief Set the back reference for this field.
|
## @brief Set the back reference for this field.
|
||||||
def _set_back_reference(self, back_reference):
|
def _set_back_reference(self, back_reference):
|
||||||
self.__back_reference = back_reference
|
self.__back_reference = back_reference
|
||||||
|
|
||||||
##@brief Check and cast value in appropriate type
|
## @brief Check and cast value in appropriate type
|
||||||
#@param value *
|
# @param value *
|
||||||
#@throw FieldValidationError if value is an appropriate type
|
# @throw FieldValidationError if value is an appropriate type
|
||||||
#@return value
|
# @return value
|
||||||
#@todo implement the check when we have LeObject uid check value
|
# @todo implement the check when we have LeObject uid check value
|
||||||
def _check_data_value(self, value):
|
def _check_data_value(self, value):
|
||||||
from lodel.leapi.leobject import LeObject
|
from lodel.leapi.leobject import LeObject
|
||||||
value = super()._check_data_value(value)
|
value = super()._check_data_value(value)
|
||||||
|
|
@ -342,13 +348,13 @@ class Reference(DataHandler):
|
||||||
raise FieldValidationError("Reference datahandler can not check this value %s if any allowed_class is allowed." % value)
|
raise FieldValidationError("Reference datahandler can not check this value %s if any allowed_class is allowed." % value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
##@brief Check datas consistency
|
## @brief Check datas consistency
|
||||||
#@param emcomponent EmComponent : An EmComponent child class instance
|
# @param emcomponent EmComponent : An EmComponent child class instance
|
||||||
#@param fname : the field name
|
# @param fname : the field name
|
||||||
#@param datas dict : dict storing fields values
|
# @param datas dict : dict storing fields values
|
||||||
#@return an Exception instance if fails else True
|
# @return an Exception instance if fails else True
|
||||||
#@todo check for performance issue and check logics
|
# @todo check for performance issue and check logics
|
||||||
#@warning composed uid capabilities broken here
|
# @warning composed uid capabilities broken here
|
||||||
def check_data_consistency(self, emcomponent, fname, datas):
|
def check_data_consistency(self, emcomponent, fname, datas):
|
||||||
rep = super().check_data_consistency(emcomponent, fname, datas)
|
rep = super().check_data_consistency(emcomponent, fname, datas)
|
||||||
if isinstance(rep, Exception):
|
if isinstance(rep, Exception):
|
||||||
|
|
@ -364,21 +370,21 @@ class Reference(DataHandler):
|
||||||
if not target_class.is_exist(value):
|
if not target_class.is_exist(value):
|
||||||
logger.warning('Object referenced does not exist')
|
logger.warning('Object referenced does not exist')
|
||||||
return False
|
return False
|
||||||
#target_uidfield = target_class.uid_fieldname()[0] #multi uid broken here
|
# target_uidfield = target_class.uid_fieldname()[0] #multi uid broken here
|
||||||
#obj = target_class.get([(target_uidfield, '=', value)])
|
# obj = target_class.get([(target_uidfield, '=', value)])
|
||||||
#if len(obj) == 0:
|
# if len(obj) == 0:
|
||||||
# logger.warning('Object referenced does not exist')
|
# logger.warning('Object referenced does not exist')
|
||||||
# return False
|
# return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
##@brief Utility method designed to fetch referenced objects
|
## @brief Utility method designed to fetch referenced objects
|
||||||
#@param value mixed : the field value
|
# @param value mixed : the field value
|
||||||
#@throw NotImplementedError
|
# @throw NotImplementedError
|
||||||
def get_referenced(self, value):
|
def get_referenced(self, value):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
##@brief This class represent a data_handler for single reference to another object
|
## @brief This class represent a data_handler for single reference to another object
|
||||||
#
|
#
|
||||||
# The fields using this data handlers are like "foreign key" on another object
|
# The fields using this data handlers are like "foreign key" on another object
|
||||||
class SingleRef(Reference):
|
class SingleRef(Reference):
|
||||||
|
|
@ -387,18 +393,18 @@ class SingleRef(Reference):
|
||||||
super().__init__(allowed_classes=allowed_classes, **kwargs)
|
super().__init__(allowed_classes=allowed_classes, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
##@brief Check and cast value in appropriate type
|
## @brief Check and cast value in appropriate type
|
||||||
#@param value: *
|
# @param value: *
|
||||||
#@throw FieldValidationError if value is unappropriate or can not be cast
|
# @throw FieldValidationError if value is unappropriate or can not be cast
|
||||||
#@return value
|
# @return value
|
||||||
def _check_data_value(self, value):
|
def _check_data_value(self, value):
|
||||||
value = super()._check_data_value(value)
|
value = super()._check_data_value(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
##@brief Utility method designed to fetch referenced objects
|
## @brief Utility method designed to fetch referenced objects
|
||||||
#@param value mixed : the field value
|
# @param value mixed : the field value
|
||||||
#@return A LeObject child class instance
|
# @return A LeObject child class instance
|
||||||
#@throw LodelDataHandlerConsistencyException if no referenced object found
|
# @throw LodelDataHandlerConsistencyException if no referenced object found
|
||||||
def get_referenced(self, value):
|
def get_referenced(self, value):
|
||||||
for leo_cls in self.linked_classes:
|
for leo_cls in self.linked_classes:
|
||||||
res = leo_cls.get_from_uid(value)
|
res = leo_cls.get_from_uid(value)
|
||||||
|
|
@ -408,30 +414,30 @@ class SingleRef(Reference):
|
||||||
referenced object with uid %s" % value)
|
referenced object with uid %s" % value)
|
||||||
|
|
||||||
|
|
||||||
##@brief This class represent a data_handler for multiple references to another object
|
## @brief This class represent a data_handler for multiple references to another object
|
||||||
#@ingroup lodel2_datahandlers
|
# @ingroup lodel2_datahandlers
|
||||||
#
|
#
|
||||||
# The fields using this data handlers are like SingleRef but can store multiple references in one field
|
# The fields using this data handlers are like SingleRef but can store multiple references in one field
|
||||||
# @note for the moment split on ',' chars
|
# @note for the moment split on ',' chars
|
||||||
class MultipleRef(Reference):
|
class MultipleRef(Reference):
|
||||||
|
|
||||||
##
|
## @brief Constructor
|
||||||
# @param max_item int | None : indicate the maximum number of item referenced by this field, None mean no limit
|
# @param max_item int | None : indicate the maximum number of item referenced by this field, None mean no limit
|
||||||
def __init__(self, max_item=None, **kwargs):
|
def __init__(self, max_item=None, **kwargs):
|
||||||
self.max_item = max_item
|
self.max_item = max_item
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
##@brief Method designed to return an empty value for this kind of
|
## @brief Method designed to return an empty value for this kind of
|
||||||
#multipleref
|
# multipleref
|
||||||
@classmethod
|
@classmethod
|
||||||
def empty(cls):
|
def empty(cls):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
##@brief Check and cast value in appropriate type
|
## @brief Check and cast value in appropriate type
|
||||||
#@param value *
|
# @param value *
|
||||||
#@throw FieldValidationError if value is unappropriate or can not be cast
|
# @throw FieldValidationError if value is unappropriate or can not be cast
|
||||||
#@return value
|
# @return value
|
||||||
#@TODO Writing test error for errors when stored multiple references in one field
|
# @TODO Writing test error for errors when stored multiple references in one field
|
||||||
def _check_data_value(self, value):
|
def _check_data_value(self, value):
|
||||||
value = DataHandler._check_data_value(self, value)
|
value = DataHandler._check_data_value(self, value)
|
||||||
if not hasattr(value, '__iter__'):
|
if not hasattr(value, '__iter__'):
|
||||||
|
|
@ -451,11 +457,11 @@ class MultipleRef(Reference):
|
||||||
raise FieldValidationError("MultipleRef have for invalid values [%s] :" % (",".join(error_list)))
|
raise FieldValidationError("MultipleRef have for invalid values [%s] :" % (",".join(error_list)))
|
||||||
return new_val
|
return new_val
|
||||||
|
|
||||||
##@brief Utility method designed to fetch referenced objects
|
## @brief Utility method designed to fetch referenced objects
|
||||||
#@param values mixed : the field values
|
# @param values mixed : the field values
|
||||||
#@return A list of LeObject child class instance
|
# @return A list of LeObject child class instance
|
||||||
#@throw LodelDataHandlerConsistencyException if some referenced objects
|
# @throw LodelDataHandlerConsistencyException if some referenced objects
|
||||||
#were not found
|
# were not found
|
||||||
def get_referenced(self, values):
|
def get_referenced(self, values):
|
||||||
if values is None or len(values) == 0:
|
if values is None or len(values) == 0:
|
||||||
return list()
|
return list()
|
||||||
|
|
@ -463,18 +469,19 @@ class MultipleRef(Reference):
|
||||||
values = set(values)
|
values = set(values)
|
||||||
res = list()
|
res = list()
|
||||||
for leo_cls in self.linked_classes:
|
for leo_cls in self.linked_classes:
|
||||||
uidname = leo_cls.uid_fieldname()[0] #MULTIPLE UID BROKEN HERE
|
uidname = leo_cls.uid_fieldname()[0] # MULTIPLE UID BROKEN HERE
|
||||||
tmp_res = leo_cls.get(('%s in (%s)' % (uidname, ','.join(
|
tmp_res = leo_cls.get(('%s in (%s)' % (uidname, ','.join(
|
||||||
[str(l) for l in left]))))
|
[str(l) for l in left]))))
|
||||||
left ^= set(( leo.uid() for leo in tmp_res))
|
left ^= set((leo.uid() for leo in tmp_res))
|
||||||
res += tmp_res
|
res += tmp_res
|
||||||
if len(left) == 0:
|
if len(left) == 0:
|
||||||
return res
|
return res
|
||||||
raise LodelDataHandlerConsistencyException("Unable to find \
|
raise LodelDataHandlerConsistencyException("Unable to find \
|
||||||
some referenced objects. Following uids were not found : %s" % ','.join(left))
|
some referenced objects. Following uids were not found : %s" % ','.join(left))
|
||||||
|
|
||||||
|
|
||||||
## @brief Class designed to handle datas access will fieldtypes are constructing datas
|
## @brief Class designed to handle datas access will fieldtypes are constructing datas
|
||||||
#@ingroup lodel2_datahandlers
|
# @ingroup lodel2_datahandlers
|
||||||
#
|
#
|
||||||
# This class is designed to allow automatic scheduling of construct_data calls.
|
# This class is designed to allow automatic scheduling of construct_data calls.
|
||||||
#
|
#
|
||||||
|
|
@ -488,15 +495,15 @@ class DatasConstructor(object):
|
||||||
# @param datas dict : dict with field name as key and field values as value
|
# @param datas dict : dict with field name as key and field values as value
|
||||||
# @param fields_handler dict : dict with field name as key and data handler instance as value
|
# @param fields_handler dict : dict with field name as key and data handler instance as value
|
||||||
def __init__(self, leobject, datas, fields_handler):
|
def __init__(self, leobject, datas, fields_handler):
|
||||||
## Stores concerned class
|
# Stores concerned class
|
||||||
self._leobject = leobject
|
self._leobject = leobject
|
||||||
## Stores datas and constructed datas
|
# Stores datas and constructed datas
|
||||||
self._datas = copy.copy(datas)
|
self._datas = copy.copy(datas)
|
||||||
## Stores fieldtypes
|
# Stores fieldtypes
|
||||||
self._fields_handler = fields_handler
|
self._fields_handler = fields_handler
|
||||||
## Stores list of fieldname for constructed datas
|
# Stores list of fieldname for constructed datas
|
||||||
self._constructed = []
|
self._constructed = []
|
||||||
## Stores construct calls list
|
# Stores construct calls list
|
||||||
self._construct_calls = []
|
self._construct_calls = []
|
||||||
|
|
||||||
## @brief Implements the dict.keys() method on instance
|
## @brief Implements the dict.keys() method on instance
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue