Source code for xotl.tools.infinity

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ---------------------------------------------------------------------
# Copyright (c) Merchise Autrement [~º/~] and Contributors
# All rights reserved.
#
# This is free software; you can do what the LICENCE file allows you to.
#

"""The Infinity value.

Not all values are comparable with `Infinity`:obj: by default.  The ABC
`InfinityComparable`:class: holds the registry of such values.  Any `number
<numbers.Number>`:class: is comparable with `Infinity`:obj:.

`Dates <datetime.date>`:class:, `datetimes <datetime.datetime>`:class: and
`time deltas <datetime.timedelta>`:class: are also registered by default.

.. warning:: In Python 2, dates, datetimes and time deltas must be the right
             operand, as in ``Infinity > today``.  Doing ``today < Infinity``
             fails in Python 2.

"""

import abc
import datetime
from numbers import Number
from functools import total_ordering


[docs]class InfinityComparable(metaclass=abc.ABCMeta): """Any type that can be sensibly compared to infinity. All types in the `number <numbers.Number>`:class: tower are *always* comparable. Classes `datetime.date`:class:, `datetime.datetime`:class:, and `datetime.timedelta`:class: are automatically registered. """ @classmethod def __subclasshook__(self, cls): if isinstance(cls, type) and issubclass(cls, Number): return True else: return NotImplemented
InfinityComparable.register(datetime.date) InfinityComparable.register(datetime.datetime) InfinityComparable.register(datetime.timedelta) @total_ordering class InfinityType: _positive = None _negative = None def __getnewargs__(self): return (self.sign,) def __new__(cls, sign): if sign < 0: res = cls._negative if not res: cls._negative = res = object.__new__(cls) else: res = cls._positive if not res: cls._positive = res = object.__new__(cls) return res def __init__(self, sign): self.sign = -1 if sign < 0 else 1 def __lt__(self, other): if isinstance(other, InfinityComparable): return self.sign < 0 # True iff -Infinity elif isinstance(other, InfinityType): return self.sign < other.sign else: return NotImplemented def __eq__(self, other): if isinstance(other, InfinityType): return self.sign == other.sign else: return NotImplemented def __neg__(self): return type(self)(-self.sign) def __str__(self): return "∞" if self.sign > 0 else "-∞" def __repr__(self): return "Infinity" if self.sign > 0 else "-Infinity" def __hash__(self): return id(self) Infinity = InfinityType(+1)