No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

field_data_handler.py 3.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. # -*- coding: utf-8 -*-
  2. import importlib
  3. class FieldDataHandler(object):
  4. help_text = 'Generic Field Data Handler'
  5. ## @brief List fields that will be exposed to the construct_data_method
  6. _construct_datas_deps = []
  7. ## @brief constructor
  8. # @param internal False | str : define whether or not a field is internal
  9. # @param immutable bool : indicates if the fieldtype has to be defined in child classes of LeObject or if it is designed globally and immutable
  10. # @param **args
  11. # @throw NotImplementedError if it is instanciated directly
  12. def __init__(self, internal=False, immutable=False, **args):
  13. if self.__class__ == GenericFieldType:
  14. raise NotImplementedError("Abstract class")
  15. self.internal = internal # Check this value ?
  16. self.immutable = bool(immutable)
  17. for argname, argval in args.items():
  18. setattr(self, argname, argval)
  19. ## Fieldtype name
  20. @staticmethod
  21. def name(cls):
  22. return cls.__module__.split('.')[-1]
  23. ## @brief checks if a fieldtype is internal
  24. # @return bool
  25. def is_internal(self):
  26. return self.internal is not False
  27. ## @brief calls the data_field defined _check_data_value() method
  28. # @return tuple (value, error|None)
  29. def check_data_value(self, value):
  30. return self._check_data_value(value)
  31. def _check_data_value(self, value):
  32. return (value, None)
  33. ## @brief Build field value
  34. # @param emcomponent EmComponent : An EmComponent child class instance
  35. # @param fname str : The field name
  36. # @param datas dict : dict storing fields values (from the component)
  37. # @param cur_value : the value from the current field (identified by fieldname)
  38. def construct_data(self, emcomponent, fname, datas, cur_value):
  39. emcomponent_fields = emcomponent.fields()
  40. fname_data_handler = None
  41. if fname in emcomponent_fields:
  42. fname_data_handler = FieldDataHandler.from_name(emcomponent_fields[fname])
  43. if fname in datas.keys():
  44. return cur_value
  45. elif fname_data_handler is not None and hasattr(fname_data_handler, 'default'):
  46. return fname_data_handler.default
  47. elif fname_data_handler is not None and fname_data_handler.nullable:
  48. return None
  49. raise RuntimeError("Unable to construct data for field %s", fname)
  50. ## @brief Check datas consistency
  51. # @param emcomponent EmComponent : An EmComponent child class instance
  52. # @param fname : the field name
  53. # @param datas dict : dict storing fields values
  54. # @return an Exception instance if fails else True
  55. # @todo A implémenter
  56. def check_data_consistency(self, emcomponent, fname, datas):
  57. return True
  58. ## @brief given a field type name, returns the associated python class
  59. # @param fieldtype_name str : A field type name
  60. # @return DataField child class
  61. @staticmethod
  62. def from_name(fieldtype_name):
  63. mod = importlib.import_module(FieldDataHandler.module_name(fieldtype_name))
  64. return mod.EmDataField
  65. ## @brief get a module name given a fieldtype name
  66. # @param fieldtype_name str : a field type name
  67. # @return a string representing a python module name
  68. @staticmethod
  69. def module_name(self, fieldtype_name):
  70. return 'leapi.datahandlers.data_fields.%s' % fieldtype_name
  71. ## @brief __hash__ implementation for fieldtypes
  72. def __hash__(self):
  73. hash_dats = [self.__class__.__module__]
  74. for kdic in sorted([k for k in self.__dict__.keys() if not k.startswith('_')]):
  75. hash_dats.append((kdic, getattr(self, kdic)))
  76. return hash(tuple(hash_dats))