def METHOD_NAME(a, b, msg='assertion of equality failed!'):
    import scipy.sparse
    assert_base_types = (int, float, str, bytes, complex,
                         None.__class__, type, nm.number)
    if a is b: return
    def assert_dict(a, b):
        assert_(set(a.keys()) == set(b.keys()), msg)
        for i in a:
            METHOD_NAME(a[i], b[i], msg)
    def assert_list(a, b):
        assert_(len(a) == len(b), msg)
        for i, j in zip(a, b):
            METHOD_NAME(i, j)
    assert_(a.__class__ is b.__class__, msg)
    if isinstance(a, (int, float, str, assert_base_types, bytes, complex)):
        assert_(a == b, msg)
    elif isinstance(a, dict):
        assert_dict(a, b)
    elif isinstance(a, (list, tuple)):
        assert_list(a, b)
    elif isinstance(a, nm.ndarray):
        nm.testing.assert_array_equal(a,b)
    elif isinstance(a, (scipy.sparse.csr_matrix, scipy.sparse.csc_matrix)):
        nm.testing.assert_array_equal(a.data, b.data)
        nm.testing.assert_array_equal(a.indices, b.indices)
        nm.testing.assert_array_equal(a.indptr, b.indptr)
    elif isinstance(a, object):
        cls = a.__class__
        if hasattr(cls, '__slots__'):
            ad = dict((i,getattr(a,i)) for i in cls.__slots__)
            bd = dict((i,getattr(b,i)) for i in cls.__slots__)
        elif hasattr(a, '__dict__'):
            ad = a.__dict__
            bd = b.__dict__
        else:
            def members(obj):
                out = inspect.getmembers(obj, lambda x: not
                                         inspect.isroutine(x) )
                out = dict( (k,v) for k,v in out if not k.startswith('__'))
                return out
            ad = members(a)
            bd = members(b)
        assert_dict(ad, bd)