conservancy_beancount/conservancy_beancount/ranges.py

50 lines
1.4 KiB
Python

"""ranges.py - Higher-typed range classes"""
# Copyright © 2020 Brett Smith
# License: AGPLv3-or-later WITH Beancount-Plugin-Additional-Permission-1.0
#
# Full copyright and licensing details can be found at toplevel file
# LICENSE.txt in the repository.
import datetime
from decimal import Decimal
from typing import (
Generic,
TypeVar,
Union,
)
RangeT = TypeVar(
'RangeT',
# This is a relatively arbitrary set of types. Feel free to add to it if
# you need; the types just need to support enough comparisons to implement
# _GenericRange.__contains__.
datetime.date,
datetime.datetime,
datetime.time,
Union[int, Decimal],
)
class _GenericRange(Generic[RangeT]):
"""range for higher-level types
This class knows how to check membership for higher-level types just like
Python's built-in range. It does not know how to iterate or step.
"""
def __init__(self, start: RangeT, stop: RangeT) -> None:
self.start: RangeT = start
self.stop: RangeT = stop
def __repr__(self) -> str:
return "{clsname}({self.start!r}, {self.stop!r})".format(
clsname=type(self).__name__,
self=self,
)
def __contains__(self, item: RangeT) -> bool:
return self.start <= item < self.stop
DateRange = _GenericRange[datetime.date]
DecimalCompatRange = _GenericRange[Union[int, Decimal]]