def _convert()

in azure/Kqlmagic/parser.py [0:0]


    def _convert(cls, name:str, obj:Dict[str,Any], key:str, value:Any)->Any:
        if value is None:
            if obj.get("allow_none"):
                return None
            else:
                raise ValueError(f"option '{key}' doesn't allow None value.")
        _type = None
        try:
            _type = obj.get("type")
            if _type == "int":
                if float(value) != int(value):
                    raise ValueError
                return int(value)
            elif _type == "uint":
                if float(value) != int(value) or int(value) < 0:
                    raise ValueError
                return int(value)                 
            elif _type == "float":
                return float(value)
            elif _type == "bool":
                if type(value) == str:
                    if value.lower() == 'true':
                        return True
                    elif value.lower() == 'false':
                        return False
                    else:
                        raise ValueError
                elif bool(value) != int(value):
                    raise ValueError
                return bool(value)
            elif _type == "dict":
                return dict(value)
            elif _type == "list":
                if type(value) == str:
                    value = [value]                     
                return list(value)
            elif _type == "enum":
                enum_values = obj.get("values", [])
                if enum_values.index(value) >= 0:
                    return value
                else:
                    raise ValueError
            elif _type == "iso8601_duration":
                # There are four ways to express a time interval:
                # Start and end, such as "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"
                # Start and duration, such as "2007-03-01T13:00:00Z/P1Y2M10DT2H30M"
                # Duration and end, such as "P1Y2M10DT2H30M/2008-05-11T15:30:00Z"
                # Duration only, such as "P1Y2M10DT2H30M", with additional context information

                value_list = [value] if type(value) != list else list(value)[:2]
                if len(value_list) == 0:
                    raise ValueError

                elif len(value_list) == 1:
                    value = value_list[0]
                    if isinstance(value, timedelta):
                        isodate = Dependencies.get_module("isodate", message="timedelta convertion to iso8601 duration format is not supported without isodate module, use instead a datetime range format, or already converted string") # will throw if does not exist
                        value = isodate.duration_isoformat(value)
                    elif type(value) != str:
                        raise ValueError
                    return value

                else:
                    start_value = value_list[0]
                    end_value = value_list[1]
                    if isinstance(start_value, timedelta):
                        isodate = Dependencies.get_module("isodate", dont_throw=True)
                        if isodate:
                           start_value = isodate.duration_isoformat(start_value) 
                        else:
                            end_datetime = end_value if isinstance(end_value, datetime) else dateutil.parser.isoparse(end_value)
                            start_value = end_datetime - start_value
                    elif isinstance(end_value, timedelta):
                        isodate = Dependencies.get_module("isodate", dont_throw=True)
                        if isodate:
                           end_value = isodate.duration_isoformat(end_value)
                        else:
                            start_datetime = end_value if isinstance(start_value, datetime) else dateutil.parser.isoparse(start_value)
                            end_value = end_value + start_datetime
                    value_list = [v.strftime('%Y-%m-%dT%H:%M:%S%ZZ') if isinstance(v, datetime) else str(v) for v in [start_value, end_value]]
                    return "/".join(value_list)

            else:
                return str(value)

        except Exception as e:
            option_type = "property" if name == "query properties" else "option"
            due_message = f"{e}" or f"invalid '{_type}' of value '{value}'"
            raise ValueError(f"failed to set {option_type} '{key}' in {name}, due to {due_message}")