Source code for argmatch.numbers
"""
Matchers for numbers.
"""
from __future__ import absolute_import
import fractions
import numbers
from argmatch._compat import IS_PY3
from argmatch.base import BaseMatcher
__all__ = [
"Number",
"Complex",
"Real",
"Float",
"Rational",
"Fraction",
"Integral",
"Integer",
"Int",
"Long",
]
class NumericMatcher(BaseMatcher):
"""Matches some number type.
This class shouldn't be used directly.
"""
#: Number class to match.
#: Must be overridden in subclasses.
CLASS = None
def __init__(self):
assert self.CLASS, "must specify number type to match"
def match(self, value):
return isinstance(value, self.CLASS)
def __repr__(self):
return "<%s>" % (self.__class__.__name__,)
[docs]
class Number(NumericMatcher):
"""Matches any number
(integer, float, complex, custom number types, etc.).
"""
CLASS = numbers.Number
[docs]
class Complex(NumericMatcher):
"""Matches any complex number.
This *includes* all real, rational, and integer numbers as well,
which in Python translates to `float`\ s, fractions, and `int`\ egers.
"""
CLASS = numbers.Complex
# TODO: consider adding a dedicated matcher for the ``complex`` type;
# right now, though, ``IsA(complex)`` and ``Complex() & ~Real()`` are probably
# acceptable workarounds
[docs]
class Real(NumericMatcher):
"""Matches any real number.
This includes all rational and integer numbers as well, which in Python
translates to fractions, and `int`\ egers.
"""
CLASS = numbers.Real
[docs]
class Float(NumericMatcher):
"""Matches a floating point number."""
CLASS = float
[docs]
class Rational(NumericMatcher):
"""Matches a rational number.
This includes all `int`\ eger numbers as well.
"""
CLASS = numbers.Rational
[docs]
class Fraction(NumericMatcher):
"""Matches a fraction object."""
CLASS = fractions.Fraction
[docs]
class Integral(NumericMatcher):
"""Matches any integer.
This ignores the length of integer's internal representation on Python 2.
"""
CLASS = int if IS_PY3 else (int, long)
[docs]
class Integer(NumericMatcher):
"""Matches a regular integer.
On Python 3, there is no distinction between regular and long integer,
making this matcher and :class:`Long` equivalent.
On Python 2, this matches the :class:`int` integers exclusively.
"""
CLASS = int
#: Alias for :class:`Integer`.
Int = Integer
[docs]
class Long(NumericMatcher):
"""Matches a long integer.
On Python 3, this is the same as regular integer, making this matcher
and :class:`Integer` equivalent.
On Python 2, this matches the :class:`long` integers exclusively.
"""
CLASS = int if IS_PY3 else long