123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- """Immutable datetime and date vars."""
- from __future__ import annotations
- import dataclasses
- from datetime import date, datetime
- from typing import Any, TypeVar
- from reflex.utils.exceptions import VarTypeError
- from reflex.vars.number import BooleanVar
- from .base import (
- CustomVarOperationReturn,
- LiteralVar,
- Var,
- VarData,
- var_operation,
- var_operation_return,
- )
- DATETIME_T = TypeVar("DATETIME_T", datetime, date)
- datetime_types = datetime | date
- def raise_var_type_error():
- """Raise a VarTypeError.
- Raises:
- VarTypeError: Cannot compare a datetime object with a non-datetime object.
- """
- raise VarTypeError("Cannot compare a datetime object with a non-datetime object.")
- class DateTimeVar(Var[DATETIME_T], python_types=(datetime, date)):
- """A variable that holds a datetime or date object."""
- def __lt__(self, other: datetime_types | DateTimeVar) -> BooleanVar:
- """Less than comparison.
- Args:
- other: The other datetime to compare.
- Returns:
- The result of the comparison.
- """
- if not isinstance(other, DATETIME_TYPES):
- raise_var_type_error()
- return date_lt_operation(self, other)
- def __le__(self, other: datetime_types | DateTimeVar) -> BooleanVar:
- """Less than or equal comparison.
- Args:
- other: The other datetime to compare.
- Returns:
- The result of the comparison.
- """
- if not isinstance(other, DATETIME_TYPES):
- raise_var_type_error()
- return date_le_operation(self, other)
- def __gt__(self, other: datetime_types | DateTimeVar) -> BooleanVar:
- """Greater than comparison.
- Args:
- other: The other datetime to compare.
- Returns:
- The result of the comparison.
- """
- if not isinstance(other, DATETIME_TYPES):
- raise_var_type_error()
- return date_gt_operation(self, other)
- def __ge__(self, other: datetime_types | DateTimeVar) -> BooleanVar:
- """Greater than or equal comparison.
- Args:
- other: The other datetime to compare.
- Returns:
- The result of the comparison.
- """
- if not isinstance(other, DATETIME_TYPES):
- raise_var_type_error()
- return date_ge_operation(self, other)
- @var_operation
- def date_gt_operation(lhs: DateTimeVar | Any, rhs: DateTimeVar | Any):
- """Greater than comparison.
- Args:
- lhs: The left-hand side of the operation.
- rhs: The right-hand side of the operation.
- Returns:
- The result of the operation.
- """
- return date_compare_operation(rhs, lhs, strict=True)
- @var_operation
- def date_lt_operation(lhs: DateTimeVar | Any, rhs: DateTimeVar | Any):
- """Less than comparison.
- Args:
- lhs: The left-hand side of the operation.
- rhs: The right-hand side of the operation.
- Returns:
- The result of the operation.
- """
- return date_compare_operation(lhs, rhs, strict=True)
- @var_operation
- def date_le_operation(lhs: DateTimeVar | Any, rhs: DateTimeVar | Any):
- """Less than or equal comparison.
- Args:
- lhs: The left-hand side of the operation.
- rhs: The right-hand side of the operation.
- Returns:
- The result of the operation.
- """
- return date_compare_operation(lhs, rhs)
- @var_operation
- def date_ge_operation(lhs: DateTimeVar | Any, rhs: DateTimeVar | Any):
- """Greater than or equal comparison.
- Args:
- lhs: The left-hand side of the operation.
- rhs: The right-hand side of the operation.
- Returns:
- The result of the operation.
- """
- return date_compare_operation(rhs, lhs)
- def date_compare_operation(
- lhs: DateTimeVar[DATETIME_T] | Any,
- rhs: DateTimeVar[DATETIME_T] | Any,
- strict: bool = False,
- ) -> CustomVarOperationReturn[bool]:
- """Check if the value is less than the other value.
- Args:
- lhs: The left-hand side of the operation.
- rhs: The right-hand side of the operation.
- strict: Whether to use strict comparison.
- Returns:
- The result of the operation.
- """
- return var_operation_return(
- f"({lhs} {'<' if strict else '<='} {rhs})",
- bool,
- )
- @dataclasses.dataclass(
- eq=False,
- frozen=True,
- slots=True,
- )
- class LiteralDatetimeVar(LiteralVar, DateTimeVar):
- """Base class for immutable datetime and date vars."""
- _var_value: datetime | date = dataclasses.field(default=datetime.now())
- @classmethod
- def create(cls, value: datetime | date, _var_data: VarData | None = None):
- """Create a new instance of the class.
- Args:
- value: The value to set.
- Returns:
- LiteralDatetimeVar: The new instance of the class.
- """
- js_expr = f'"{value!s}"'
- return cls(
- _js_expr=js_expr,
- _var_type=type(value),
- _var_value=value,
- _var_data=_var_data,
- )
- DATETIME_TYPES = (datetime, date, DateTimeVar)
|