Skip to content

BoundaryType

Bases: AbstractType

Source code in library_analyzer/processing/api/model/_types.py
@dataclass
class BoundaryType(AbstractType):
    NEGATIVE_INFINITY: ClassVar = "NegativeInfinity"
    INFINITY: ClassVar = "Infinity"

    base_type: str
    min: Union[float, int, str]
    max: Union[float, int, str]
    min_inclusive: bool
    max_inclusive: bool

    full_match: str = ""

    @classmethod
    def _is_inclusive(cls, bracket: str) -> bool:
        if bracket in ("(", ")"):
            return False
        if bracket in ("[", "]"):
            return True
        raise Exception(f"{bracket} is not one of []()")

    @classmethod
    def from_json(cls, json: Any) -> Optional[BoundaryType]:
        if json["kind"] == cls.__name__:
            return BoundaryType(
                json["base_type"],
                json["min"],
                json["max"],
                json["min_inclusive"],
                json["max_inclusive"],
            )
        return None

    @classmethod
    def from_string(cls, string: str) -> Optional[BoundaryType]:
        # language=PythonRegExp
        pattern = r"""(?P<base_type>float|int)?[ ]  # optional base type of either float or int
                    (in|of)[ ](the[ ])?(range|interval)[ ](of[ ])?  # 'in' or 'of', optional 'the', 'range' or 'interval', optional 'of'
                    `?(?P<min_bracket>[\[(])(?P<min>[-+]?\d+(.\d*)?|negative_infinity),[ ]  # left side of the range
                    (?P<max>[-+]?\d+(.\d*)?|infinity)(?P<max_bracket>[\])])`?"""  # right side of the range
        match = re.search(pattern, string, re.VERBOSE)

        if match is not None:
            base_type = match.group("base_type")
            if base_type is None:
                base_type = "float"

            min_value: Union[str, int, float] = match.group("min")
            if min_value != "negative_infinity":
                if base_type == "int":
                    min_value = int(min_value)
                else:
                    min_value = float(min_value)
            else:
                min_value = BoundaryType.NEGATIVE_INFINITY

            max_value: Union[str, int, float] = match.group("max")
            if max_value != "infinity":
                if base_type == "int":
                    max_value = int(max_value)
                else:
                    max_value = float(max_value)
            else:
                max_value = BoundaryType.INFINITY

            min_bracket = match.group("min_bracket")
            max_bracket = match.group("max_bracket")
            min_inclusive = BoundaryType._is_inclusive(min_bracket)
            max_inclusive = BoundaryType._is_inclusive(max_bracket)

            return BoundaryType(
                base_type=base_type,
                min=min_value,
                max=max_value,
                min_inclusive=min_inclusive,
                max_inclusive=max_inclusive,
                full_match=match.group(0),
            )

        return None

    def __eq__(self, __o: object) -> bool:
        if isinstance(__o, BoundaryType):
            eq = (
                self.base_type == __o.base_type
                and self.min == __o.min
                and self.min_inclusive == __o.min_inclusive
                and self.max == __o.max
            )
            if eq:
                if self.max == BoundaryType.INFINITY:
                    return True
                return self.max_inclusive == __o.max_inclusive
        return False

    def __hash__(self) -> int:
        return hash(
            (
                self.base_type,
                self.min,
                self.min_inclusive,
                self.max,
                self.max_inclusive,
                self.full_match,
            )
        )

    def to_json(self) -> dict[str, Any]:
        return {
            "kind": self.__class__.__name__,
            "base_type": self.base_type,
            "min": self.min,
            "max": self.max,
            "min_inclusive": self.min_inclusive,
            "max_inclusive": self.max_inclusive,
        }

INFINITY: ClassVar = 'Infinity' class-attribute

NEGATIVE_INFINITY: ClassVar = 'NegativeInfinity' class-attribute

base_type: str class-attribute

full_match: str = '' class-attribute

max: Union[float, int, str] class-attribute

max_inclusive: bool class-attribute

min: Union[float, int, str] class-attribute

min_inclusive: bool class-attribute

__eq__(__o)

Source code in library_analyzer/processing/api/model/_types.py
def __eq__(self, __o: object) -> bool:
    if isinstance(__o, BoundaryType):
        eq = (
            self.base_type == __o.base_type
            and self.min == __o.min
            and self.min_inclusive == __o.min_inclusive
            and self.max == __o.max
        )
        if eq:
            if self.max == BoundaryType.INFINITY:
                return True
            return self.max_inclusive == __o.max_inclusive
    return False

__hash__()

Source code in library_analyzer/processing/api/model/_types.py
def __hash__(self) -> int:
    return hash(
        (
            self.base_type,
            self.min,
            self.min_inclusive,
            self.max,
            self.max_inclusive,
            self.full_match,
        )
    )

from_json(json) classmethod

Source code in library_analyzer/processing/api/model/_types.py
@classmethod
def from_json(cls, json: Any) -> Optional[BoundaryType]:
    if json["kind"] == cls.__name__:
        return BoundaryType(
            json["base_type"],
            json["min"],
            json["max"],
            json["min_inclusive"],
            json["max_inclusive"],
        )
    return None

from_string(string) classmethod

Source code in library_analyzer/processing/api/model/_types.py
@classmethod
def from_string(cls, string: str) -> Optional[BoundaryType]:
    # language=PythonRegExp
    pattern = r"""(?P<base_type>float|int)?[ ]  # optional base type of either float or int
                (in|of)[ ](the[ ])?(range|interval)[ ](of[ ])?  # 'in' or 'of', optional 'the', 'range' or 'interval', optional 'of'
                `?(?P<min_bracket>[\[(])(?P<min>[-+]?\d+(.\d*)?|negative_infinity),[ ]  # left side of the range
                (?P<max>[-+]?\d+(.\d*)?|infinity)(?P<max_bracket>[\])])`?"""  # right side of the range
    match = re.search(pattern, string, re.VERBOSE)

    if match is not None:
        base_type = match.group("base_type")
        if base_type is None:
            base_type = "float"

        min_value: Union[str, int, float] = match.group("min")
        if min_value != "negative_infinity":
            if base_type == "int":
                min_value = int(min_value)
            else:
                min_value = float(min_value)
        else:
            min_value = BoundaryType.NEGATIVE_INFINITY

        max_value: Union[str, int, float] = match.group("max")
        if max_value != "infinity":
            if base_type == "int":
                max_value = int(max_value)
            else:
                max_value = float(max_value)
        else:
            max_value = BoundaryType.INFINITY

        min_bracket = match.group("min_bracket")
        max_bracket = match.group("max_bracket")
        min_inclusive = BoundaryType._is_inclusive(min_bracket)
        max_inclusive = BoundaryType._is_inclusive(max_bracket)

        return BoundaryType(
            base_type=base_type,
            min=min_value,
            max=max_value,
            min_inclusive=min_inclusive,
            max_inclusive=max_inclusive,
            full_match=match.group(0),
        )

    return None

to_json()

Source code in library_analyzer/processing/api/model/_types.py
def to_json(self) -> dict[str, Any]:
    return {
        "kind": self.__class__.__name__,
        "base_type": self.base_type,
        "min": self.min,
        "max": self.max,
        "min_inclusive": self.min_inclusive,
        "max_inclusive": self.max_inclusive,
    }