def md5(file_or_path, hash_obj=None):
    hash_obj = hash_obj or hashlib.md5()

    if isinstance(file_or_path, (list, tuple)):
        for _file_or_path in file_or_path:
            md5(_file_or_path, hash_obj)
    elif isinstance(file_or_path, six.string_types):
        _path_str = file_or_path  # type: str
        if os.path.isdir(_path_str):
            for _sub_path_str in (os.path.join(root, file) for root, _, files in os.walk(_path_str) for file in files):
                with open(_sub_path_str, 'rb') as file:
                    _md5_file(file, hash_obj)
        else:
            with open(_path_str, 'rb') as file:
                _md5_file(file, hash_obj)
    elif six.PY3 and isinstance(file_or_path, pathlib.Path):
        _path_obj = file_or_path  # type: pathlib.Path
        if _path_obj.is_dir():
            for _sub_path_obj in _path_obj.glob('**/*'):
                with _sub_path_obj.open('rb') as file:
                    _md5_file(file, hash_obj)
        else:
            with _path_obj.open('rb') as file:
                _md5_file(file, hash_obj)
    else:
        _md5_file(file_or_path, hash_obj)

    return hash_obj
Check that other alert iis the same.
dataset/ETHPy150Open sodastsai/taskr/taskr/contrib/filetools.py/md5--crossover with--dataset/ETHPy150Open klen/graphite-beacon/graphite_beacon/alerts.py/BaseAlert.__eq__