def specize(x: Speccable) -> Spec: """ Although this is public and in spec.core, you'll probably never need to use it """ if isinstance(x, Spec): return x if isinstance(x, type): return is_instance(x) if isinstance(x, Set): return is_in(x) if callable(x): if hasattr(x, '__name__'): description = x.__name__ elif hasattr(x, '__code__'): description = x.__code__.co_name else: description = a_or_an(type(x).__name__) return SimpleSpec(description, x) raise ValueError("I don't know how to turn a {} into a spec: {}".format( type(x), x))
def Gt(value) -> Spec: return SimpleSpec("greater than {}".format(value), lambda x: x > value)
def IsNone() -> Spec: return SimpleSpec("None", lambda x: x is None)
def InRange(start, end_exclusive=None) -> Spec: return SimpleSpec( "between {} {}".format( start, "and {}".format(end_exclusive) if end_exclusive else None), lambda x: x >= start and (end_exclusive is None or x < end_exclusive))
def Odd() -> Spec: return SimpleSpec("an odd number", lambda x: isinstance(x, int) and bool(x & 1))
def Even() -> Spec: return SimpleSpec("an even number", lambda x: isinstance(x, int) and not bool(x & 1))
def Lte(value) -> Spec: return SimpleSpec("less than or equal to {}".format(value), lambda x: x <= value)
def Gte(value) -> Spec: return SimpleSpec("greater than or equal to {}".format(value), lambda x: x >= value)
def Lt(value) -> Spec: return SimpleSpec("less than {}".format(value), lambda x: x < value)