def are_equal(*sequences, easy_types=(sequence_tools.CuteRange,)):
    '''
    Are the given sequences equal?
    
    This tries to make a cheap comparison between the sequences if possible,
    but if not, it goes over the sequences in parallel item-by-item and checks
    whether the items are all equal. A cheap comparison is attempted only if
    the sequences are all of the same type, and that type is in `easy_types`.
    (It's important to restrict `easy_types` only to types where equality
    between the sequences is the same as equality between every item in the
    sequences.)
    '''
    from python_toolbox import logic_tools
    sequence_types = set(map(type, sequences))
    
    # Trying cheap comparison:
    if len(sequence_types) == 1 and issubclass(
                                get_single_if_any(sequence_types), easy_types):
        return logic_tools.all_equal(sequences)
    
    # If cheap comparison didn't work, trying item-by-item comparison:
    zipped = itertools.zip_longest(*sequences,
                                   fillvalue=_EMPTY_SENTINEL)
    for values in zipped:
        # No need to explicitly check for `_EMPTY_SENTINEL`, it would just make
        # the following condition `False`, because it's impossible for all
        # values to be the sentinel.
        if not logic_tools.all_equal(values):
            return False
    else:
        return True
示例#2
0
def test_exhaustive_true():
    '''Test `all_equal` in cases where `exhaustive=True` is relevant.'''
    class FunkyFloat(float):
        def __eq__(self, other):
            return (abs(self - other) <= 2)

    funky_floats = [FunkyFloat(1), FunkyFloat(2), FunkyFloat(3), FunkyFloat(4)]

    assert all_equal(funky_floats)
    assert not all_equal(funky_floats, exhaustive=True)
示例#3
0
def test_exhaustive():
    """Test `all_equal` in cases where `exhaustive=True` is relevant."""

    class FunkyFloat(float):
        def __eq__(self, other):
            return abs(self - other) <= 2

    funky_floats = [FunkyFloat(1), FunkyFloat(2), FunkyFloat(3), FunkyFloat(4)]

    assert all_equal(funky_floats)
    assert not all_equal(funky_floats, exhaustive=True)
def cute_equal(*items):
    # For testing purposes, we need `nan == nan`, so we use `cute_equal`.
    if all(isinstance(item, numbers.Number) for item in items):
        if all(map(math.isnan, items)): return True
        else: return logic_tools.all_equal(items)
    else:
        assert all(isinstance(item, tuple) for item in items)
        return all(cute_equal(*sub_items) for sub_items in zip(*items))
def cute_equal(*items):
    # For testing purposes, we need `nan == nan`, so we use `cute_equal`.
    if all(isinstance(item, numbers.Number) for item in items):
        if all(map(math.isnan, items)): return True
        else: return logic_tools.all_equal(items)
    else:
        assert all(isinstance(item, tuple) for item in items)
        return all(cute_equal(*sub_items) for sub_items in zip(*items))
def test_illegal_cases():
    illegal_cases = ((4, 0), (infinity, 0), (-infinity, 0))
    for illegal_case in illegal_cases:
        with cute_testing.RaiseAssertor() as raise_assertor_0:
            cute_divmod(*illegal_case)
        with cute_testing.RaiseAssertor() as raise_assertor_1:
            divmod(*illegal_case)
        with cute_testing.RaiseAssertor() as raise_assertor_2:
            cute_floor_div(*illegal_case)
        assert logic_tools.all_equal((
            type(raise_assertor_0.exception),
            type(raise_assertor_1.exception),
            type(raise_assertor_2.exception),
        ))
        assert logic_tools.all_equal((
            raise_assertor_0.exception.args,
            raise_assertor_1.exception.args,
            raise_assertor_2.exception.args,
        ))
def test_illegal_cases():
    illegal_cases = (
        (4, 0), (infinity, 0), (-infinity, 0)
    )
    for illegal_case in illegal_cases:
        with cute_testing.RaiseAssertor() as raise_assertor_0:
            cute_divmod(*illegal_case)
        with cute_testing.RaiseAssertor() as raise_assertor_1:
            divmod(*illegal_case)
        with cute_testing.RaiseAssertor() as raise_assertor_2:
            cute_floor_div(*illegal_case)
        assert logic_tools.all_equal((
            type(raise_assertor_0.exception),
            type(raise_assertor_1.exception),
            type(raise_assertor_2.exception),
        ))
        assert logic_tools.all_equal((
            raise_assertor_0.exception.args,
            raise_assertor_1.exception.args,
            raise_assertor_2.exception.args,
        ))
def zip_non_equal(iterables, lazy_tuple=False):
    '''
    Zip the iterables, but only yield the tuples where the items aren't equal.
    '''
    from python_toolbox import logic_tools
    iterator = (items for items in zip(*iterables)
                if not logic_tools.all_equal(items))

    if lazy_tuple:
        from python_toolbox import nifty_collections
        return nifty_collections.LazyTuple(iterator)
    else:
        return iterator
示例#9
0
def call_and_check_if_profiled(f):
    '''Call the function `f` and return whether it profiled itself.'''

    with OutputCapturer() as output_capturer:
        f()

    output = output_capturer.output

    segments_found = [(segment in output) for segment in segments]

    if not logic_tools.all_equal(segments_found):
        raise Exception("Some segments were found, but some weren't; can't "
                        "know if this was a profiled call or not. Possibly "
                        "some of our segments are wrong.")

    return segments_found[0]
示例#10
0
def call_and_check_if_profiled(f):
    '''Call the function `f` and return whether it profiled itself.'''
    
    with OutputCapturer() as output_capturer:
        f()
    
    output = output_capturer.output
        
    segments_found = [(segment in output) for segment in segments]
    
    if not logic_tools.all_equal(segments_found):
        raise Exception("Some segments were found, but some weren't; can't "
                        "know if this was a profiled call or not. Possibly "
                        "some of our segments are wrong.")
    
    return segments_found[0]
    
    
    
示例#11
0
def assert_same_signature(*callables):
    """Assert that all the `callables` have the same function signature."""
    arg_specs = [cute_inspect.getargspec(callable_) for callable_ in callables]
    if not logic_tools.all_equal(arg_specs, exhaustive=True):
        raise Failure("Not all the callables have the same signature.")
示例#12
0
def _check(exhaustive):
    '''Check the basic working of `all_equal` with given `exhaustive` flag.'''
    assert all_equal([1, 1, 1, 1], exhaustive)
    assert all_equal([1, 1, 1.0, 1], exhaustive)
    assert all_equal(((1 + 0j), 1, 1.0, 1), exhaustive)
    assert all_equal([], exhaustive)
    assert all_equal(iter([1, 1, 1.0, 1]), exhaustive)
    assert all_equal({'meow'}, exhaustive)
    assert all_equal(['frr', 'frr', 'frr', 'frr'], exhaustive)

    assert not all_equal([1, 1, 2, 1], exhaustive)
    assert not all_equal([1, 1, 1.001, 1], exhaustive)
    assert not all_equal(((1 + 0j), 3, 1.0, 1), exhaustive)
    assert not all_equal(range(7), exhaustive)
    assert not all_equal(iter([1, 17, 1.0, 1]), exhaustive)
    assert not all_equal({'meow', 'grr'}, exhaustive)
    assert not all_equal(['frr', 'frr', {}, 'frr', 'frr'], exhaustive)
    assert not all_equal(itertools.count())  # Not using given `exhaustive`
示例#13
0
def assert_same_signature(*callables):
    '''Assert that all the `callables` have the same function signature.'''
    arg_specs = [cute_inspect.getargspec(callable_) for callable_ in callables]
    if not logic_tools.all_equal(arg_specs, exhaustive=True):
        raise Failure('Not all the callables have the same signature.')
示例#14
0
def _check(exhaustive):
    '''Check the basic working of `all_equal` with given `exhaustive` flag.'''
    assert all_equal([1, 1, 1, 1], exhaustive)
    assert all_equal([1, 1, 1.0, 1], exhaustive)
    assert all_equal(((1 + 0j), 1, 1.0, 1), exhaustive)
    assert all_equal([], exhaustive)
    assert all_equal(iter([1, 1, 1.0, 1]), exhaustive)
    assert all_equal({'meow'}, exhaustive)
    assert all_equal(['frr', 'frr', 'frr', 'frr'], exhaustive)
    
    assert not all_equal([1, 1, 2, 1], exhaustive)
    assert not all_equal([1, 1, 1.001, 1], exhaustive)
    assert not all_equal(((1 + 0j), 3, 1.0, 1), exhaustive)
    assert not all_equal(range(7), exhaustive)
    assert not all_equal(iter([1, 17, 1.0, 1]), exhaustive)
    assert not all_equal({'meow', 'grr'}, exhaustive)
    assert not all_equal(['frr', 'frr', {}, 'frr', 'frr'], exhaustive)
    assert not all_equal(itertools.count()) # Not using given `exhaustive`
示例#15
0
def _check(exhaustive):
    """Check the basic working of `all_equal` with given `exhaustive` flag."""
    assert all_equal([1, 1, 1, 1], exhaustive)
    assert all_equal([1, 1, 1.0, 1], exhaustive)
    assert all_equal(((1 + 0j), 1, 1.0, 1), exhaustive)
    assert all_equal([], exhaustive)
    assert all_equal(iter([1, 1, 1.0, 1]), exhaustive)
    assert all_equal({"meow"}, exhaustive)
    assert all_equal(["frr", "frr", "frr", "frr"], exhaustive)

    assert not all_equal([1, 1, 2, 1], exhaustive)
    assert not all_equal([1, 1, 1.001, 1], exhaustive)
    assert not all_equal(((1 + 0j), 3, 1.0, 1), exhaustive)
    assert not all_equal(range(7), exhaustive)
    assert not all_equal(iter([1, 17, 1.0, 1]), exhaustive)
    assert not all_equal({"meow", "grr"}, exhaustive)
    assert not all_equal(["frr", "frr", {}, "frr", "frr"], exhaustive)
    assert not all_equal(itertools.count())  # Not using given `exhaustive`