# Path: src/tidypy/util.py
# def read_file(filepath):
#     """
#     Retrieves the contents of the specified file.
# 
#     This function performs simple caching so that the same file isn't read more
#     than once per process.
# 
#     :param filepath: the file to read
#     :type filepath: str
#     :returns: str
#     """
# 
#     with _FILE_CACHE_LOCK:
#         if filepath not in _FILE_CACHE:
#             _FILE_CACHE[filepath] = _read_file(filepath)
#     return _FILE_CACHE[filepath]
# 
# def compile_masks(masks):
#     """
#     Compiles a list of regular expressions.
# 
#     :param masks: the regular expressions to compile
#     :type masks: list(str) or str
#     :returns: list(regular expression object)
#     """
# 
#     if not masks:
#         masks = []
#     elif not isinstance(masks, (list, tuple)):
#         masks = [masks]
# 
#     return [
#         re.compile(mask)
#         for mask in masks
#     ]
# 
# def matches_masks(target, masks):
#     """
#     Determines whether or not the target string matches any of the regular
#     expressions specified.
# 
#     :param target: the string to check
#     :type target: str
#     :param masks: the regular expressions to check against
#     :type masks: list(regular expression object)
#     :returns: bool
#     """
# 
#     for mask in masks:
#         if mask.search(target):
#             return True
#     return False


from pathlib import Path
from .util import read_file, compile_masks, matches_masks
        :type filepath: str or pathlib.Path
        :rtype: str
        """

        return str(Path(filepath).relative_to(self.base_path))

    def _find(self, path):
        for subpath in path.iterdir():
            if subpath.is_dir():
                if not self.is_excluded_dir(subpath):
                    self._found[str(subpath)] = []
                    self._find(subpath)

            elif subpath.is_file():
                if not self.is_excluded(subpath):
                    if str(path) not in self._found:
                        self._found[str(path)] = []
                    self._found[str(path)].append(str(subpath))

    def is_excluded(self, path):
        """
        Determines whether or not the specified file is excluded by the
        project's configuration.

        :param path: the path to check
        :type path: pathlib.Path
        :rtype: bool
        """

        relpath = path.relative_to(self.base_path).as_posix()

# Path: src/tidypy/util.py
# def read_file(filepath):
#     """
#     Retrieves the contents of the specified file.
# 
#     This function performs simple caching so that the same file isn't read more
#     than once per process.
# 
#     :param filepath: the file to read
#     :type filepath: str
#     :returns: str
#     """
# 
#     with _FILE_CACHE_LOCK:
#         if filepath not in _FILE_CACHE:
#             _FILE_CACHE[filepath] = _read_file(filepath)
#     return _FILE_CACHE[filepath]
# 
# def compile_masks(masks):
#     """
#     Compiles a list of regular expressions.
# 
#     :param masks: the regular expressions to compile
#     :type masks: list(str) or str
#     :returns: list(regular expression object)
#     """
# 
#     if not masks:
#         masks = []
#     elif not isinstance(masks, (list, tuple)):
#         masks = [masks]
# 
#     return [
#         re.compile(mask)
#         for mask in masks
#     ]
# 
# def matches_masks(target, masks):
#     """
#     Determines whether or not the target string matches any of the regular
#     expressions specified.
# 
#     :param target: the string to check
#     :type target: str
#     :param masks: the regular expressions to check against
#     :type masks: list(regular expression object)
#     :returns: bool
#     """
# 
#     for mask in masks:
#         if mask.search(target):
#             return True
#     return False


# Path: src/tidypy/finder.py
from pathlib import Path
from .util import read_file, compile_masks, matches_masks

        :type filepath: str or pathlib.Path
        :rtype: str
        """

        return str(Path(filepath).relative_to(self.base_path))

    def _find(self, path):
        for subpath in path.iterdir():
            if subpath.is_dir():
                if not self.is_excluded_dir(subpath):
                    self._found[str(subpath)] = []
                    self._find(subpath)

            elif subpath.is_file():
                if not self.is_excluded(subpath):
                    if str(path) not in self._found:
                        self._found[str(path)] = []
                    self._found[str(path)].append(str(subpath))

    def is_excluded(self, path):
        """
        Determines whether or not the specified file is excluded by the
        project's configuration.

        :param path: the path to check
        :type path: pathlib.Path
        :rtype: bool
        """

        relpath = path.relative_to(self.base_path).as_posix()

        return matches_masks(relpath, self.excludes)