"""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]]