# Path: diffoscope/exc.py
# class RequiredToolNotFound(Exception):
#     def __init__(self, command):
#         self.command = command
# 
#     def get_package(self):
#         try:
#             providers = EXTERNAL_TOOLS[self.command]
#         except KeyError:  # noqa
#             return None
# 
#         return providers.get(get_current_os(), None)
# 
# class OutputParsingError(Exception):
#     def __init__(self, command, object):
#         self.command = command
#         self.object_class = object.__class__
# 
# Path: diffoscope/tools.py
# def tool_required(command):
#     """
#     Decorator that checks if the specified tool is installed
#     """
#     if not hasattr(tool_required, 'all'):
#         tool_required.all = set()
#     tool_required.all.add(command)
#     def wrapper(original_function):
#         if find_executable(command):
#             @functools.wraps(original_function)
#             def tool_check(*args, **kwargs):
#                 with profile('command', command):
#                     return original_function(*args, **kwargs)
#         else:
#             @functools.wraps(original_function)
#             def tool_check(*args, **kwargs):
#                 from .exc import RequiredToolNotFound
#                 raise RequiredToolNotFound(command)
#         return tool_check
#     return wrapper


import os
import re
import abc
import magic
import logging
import subprocess
    import tlsh
from diffoscope.exc import RequiredToolNotFound, OutputParsingError
from diffoscope.tools import tool_required
from diffoscope.profiling import profile
from diffoscope.difference import Difference
        from .compare import compare_binary_files
        raise NotImplementedError()

    # Remove any temporary data associated with the file. The function
    # should be idempotent and work during the destructor.
    def cleanup(self):
        if hasattr(self, '_as_container'):
            del self._as_container

    def __del__(self):
        self.cleanup()

    # This might be different from path and is used to do file extension matching
    @property
    def name(self):
        return self._name

    @property
    def container(self):
        return self._container

    @property
    def as_container(self):
        if not hasattr(self.__class__, 'CONTAINER_CLASS'):
            if hasattr(self, '_other_file'):
                return self._other_file.__class__.CONTAINER_CLASS(self)
            return None
        if not hasattr(self, '_as_container'):
            logger.debug('instantiating %s for %s', self.__class__.CONTAINER_CLASS, self)
            try:
                self._as_container = self.__class__.CONTAINER_CLASS(self)

# Path: diffoscope/exc.py
# class RequiredToolNotFound(Exception):
#     def __init__(self, command):
#         self.command = command
# 
#     def get_package(self):
#         try:
#             providers = EXTERNAL_TOOLS[self.command]
#         except KeyError:  # noqa
#             return None
# 
#         return providers.get(get_current_os(), None)
# 
# class OutputParsingError(Exception):
#     def __init__(self, command, object):
#         self.command = command
#         self.object_class = object.__class__
# 
# Path: diffoscope/tools.py
# def tool_required(command):
#     """
#     Decorator that checks if the specified tool is installed
#     """
#     if not hasattr(tool_required, 'all'):
#         tool_required.all = set()
#     tool_required.all.add(command)
#     def wrapper(original_function):
#         if find_executable(command):
#             @functools.wraps(original_function)
#             def tool_check(*args, **kwargs):
#                 with profile('command', command):
#                     return original_function(*args, **kwargs)
#         else:
#             @functools.wraps(original_function)
#             def tool_check(*args, **kwargs):
#                 from .exc import RequiredToolNotFound
#                 raise RequiredToolNotFound(command)
#         return tool_check
#     return wrapper


# Path: diffoscope/comparators/utils/file.py
import os
import re
import abc
import magic
import logging
import subprocess
    import tlsh
from diffoscope.exc import RequiredToolNotFound, OutputParsingError
from diffoscope.tools import tool_required
from diffoscope.profiling import profile
from diffoscope.difference import Difference
        from .compare import compare_binary_files

        raise NotImplementedError()

    # Remove any temporary data associated with the file. The function
    # should be idempotent and work during the destructor.
    def cleanup(self):
        if hasattr(self, '_as_container'):
            del self._as_container

    def __del__(self):
        self.cleanup()

    # This might be different from path and is used to do file extension matching
    @property
    def name(self):
        return self._name

    @property
    def container(self):
        return self._container

    @property
    def as_container(self):
        if not hasattr(self.__class__, 'CONTAINER_CLASS'):
            if hasattr(self, '_other_file'):
                return self._other_file.__class__.CONTAINER_CLASS(self)
            return None
        if not hasattr(self, '_as_container'):
            logger.debug('instantiating %s for %s', self.__class__.CONTAINER_CLASS, self)
            try:
                self._as_container = self.__class__.CONTAINER_CLASS(self)

            except RequiredToolNotFound: