oplus/epm/field_descriptor.py
def deserialize(self, value, index):
        """
        index is used for extensible fields error messages (if given)
        """
        # -- serialize if not raw type
        # transform to string if external file
        if isinstance(value, ExternalFile):
            value = value.pointer

        # transform to string if record
        if isinstance(value, Record):
            try:
                value = value[0]
            except IndexError:
                raise ValueError("can't set given record because it does not have a name field")
        
        # -- prepare if string
        if isinstance(value, str):
            # change multiple spaces to mono spaces
            value = re.sub(spaces_and_newlines_pattern, lambda x: " ", value.strip())
            
            # see if still not empty
            if value == "":
                return None

            # make ASCII compatible
            value = unidecode.unidecode(value)

            # make lower case if not retaincase
            if "retaincase" not in self.tags:
                value = value.lower()

            # check not too big
            if len(value) >= 100:
                raise FieldValidationError(
                    f"Field has more than 100 characters which is the limit. "
                    f"{self.get_error_location_message(value, index=index)}"
                )

        # transform to external file if relevant
        if self.is_file_name:
            value = ExternalFile.deserialize(value)

        # -- deserialize

        # numeric types
        if self.detailed_type in ("integer", "real"):
            # manage none
            if value is None:
                return None

            # special values: auto-calculate, auto-size, use-weather-file
            if value in ("autocalculate", "autosize", "useweatherfile"):
                return value
            
            if self.detailed_type == "integer":
                try:
                    return int(value)
                except:
                    raise FieldValidationError(
                        f"Couldn't parse to integer. {self.get_error_location_message(value, index=index)}"
                    )

            try:
                return float(value)
            except:
                raise FieldValidationError(
                    f"Couldn't parse to float. {self.get_error_location_message(value, index=index)}"
                )

        # simple string types
        if self.detailed_type in ("alpha", "choice", "node", "external-list"):
            # manage none
            if value is None:
                return None

            # ensure it was str
            if not isinstance_str(value):
                raise FieldValidationError(
                    f"Value must be a string. {self.get_error_location_message(value, index=index)}"
                )
            return value

        # manage hooks (eplus reference)
        if self.detailed_type == "reference":
            # manage None
            if value is None:
                return NONE_RECORD_HOOK

            # reference class name appears in v9.0.1
            references = self.tags.get("reference", [])
            # table_name, index, value, references, class_references
            return RecordHook(references, index, value)

        # manage links (eplus object-list)
        if self.detailed_type == "object-list":
            # manage None
            if value is None:
                return NONE_LINK

            return Link(self.tags["object-list"], value, index)

        raise RuntimeError("should not be here")
def deserialize(self, value, index):
        """
        index is used for extensible fields error messages (if given)
        """
        # -- serialize if not raw type
        # transform to string if external file
        if isinstance(value, ExternalFile):
            value = value.pointer

        # transform to string if record
        if isinstance(value, Record):
            try:
                value = value[0]
            except IndexError:
                raise ValueError("can't set given record because it does not have a name field")
        
        # -- prepare if string
        if isinstance(value, str):
            # change multiple spaces to mono spaces
            value = re.sub(spaces_and_newlines_pattern, lambda x: " ", value.strip())
            
            # see if still not empty
            if value == "":
                return None

            # make ASCII compatible
            value = unidecode.unidecode(value)

            # make lower case if not retaincase
            if "retaincase" not in self.tags:
                value = value.lower()

            # check not too big
            if len(value) >= 100:
                raise FieldValidationError(
                    f"Field has more than 100 characters which is the limit. "
                    f"{self.get_error_location_message(value, index=index)}"
                )

        # transform to external file if relevant
        if self.is_file_name:
            value = ExternalFile.deserialize(value)

        # -- deserialize

        # numeric types
        if self.detailed_type in ("integer", "real"):
            # manage none
            if value is None:
                return None

            # special values: auto-calculate, auto-size, use-weather-file
            if value in ("autocalculate", "autosize", "useweatherfile"):
                return value
            
            if self.detailed_type == "integer":
                try:
                    return int(value)
                except:
                    raise FieldValidationError(
                        f"Couldn't parse to integer. {self.get_error_location_message(value, index=index)}"
                    )

            try:
                return float(value)
            except:
                raise FieldValidationError(
                    f"Couldn't parse to float. {self.get_error_location_message(value, index=index)}"
                )

        # simple string types
        if self.detailed_type in ("alpha", "choice", "node", "external-list"):
            # manage none
            if value is None:
                return None

            # ensure it was str
            if not isinstance_str(value):
                raise FieldValidationError(
                    f"Value must be a string. {self.get_error_location_message(value, index=index)}"
                )
            return value

        # manage hooks (eplus reference)
        if self.detailed_type == "reference":
            # manage None
            if value is None:
                return NONE_RECORD_HOOK

            # reference class name appears in v9.0.1
            references = self.tags.get("reference", [])
            # table_name, index, value, references, class_references
            return RecordHook(references, index, value)

        # manage links (eplus object-list)
        if self.detailed_type == "object-list":
            # manage None
            if value is None:
                return NONE_LINK

            return Link(self.tags["object-list"], value, index)

        raise RuntimeError("should not be here")
index is used for extensible fields error messages (if given)