# Path: src/tidypy/extenders/base.py
# class DoesNotExistError(ExtenderError):
#     """
#     An exception indicating that the specified Extender does not exist in the
#     current environment.
#     """
# 
# Path: src/tidypy/extenders/filesys.py
# class FilesysExtender(Extender):
#     @classmethod
#     def can_handle(cls, location):
#         return True
# 
#     @classmethod
#     def retrieve(cls, location, project_path):
#         path = Path(location)
#         if not path.is_absolute():
#             path = Path(project_path).joinpath(path)
#         if not path.exists():
#             raise DoesNotExistError()
# 
#         with path.open('r', encoding='utf-8') as config_file:
#             content = config_file.read()
# 
#         return cls.parse(
#             content,
#             is_pyproject=path.parts[-1] == 'pyproject.toml',
#         )
# 
# Path: src/tidypy/util.py
# def merge_dict(dict1, dict2, merge_lists=False):
#     """
#     Recursively merges the contents of two dictionaries into a new dictionary.
# 
#     When both input dictionaries share a key, the value from ``dict2`` is
#     kept.
# 
#     :param dict1: the first dictionary
#     :type dict1: dict
#     :param dict2: the second dictionary
#     :type dict2: dict
#     :param merge_lists:
#         when this function encounters a key that contains lists in both input
#         dictionaries, this parameter dictates whether or not those lists should
#         be merged. If not specified, defaults to ``False``.
#     :type merge_lists: bool
#     :returns: dict
#     """
# 
#     merged = dict(dict1)
# 
#     for key, value in dict2.items():
#         if isinstance(merged.get(key), dict):
#             merged[key] = merge_dict(merged[key], value)
#         elif merge_lists and isinstance(merged.get(key), list):
#             merged[key] = merge_list(merged[key], value)
#         else:
#             merged[key] = value
# 
#     return merged
# 
# def output_error(msg):
#     """
#     Prints the specified string to ``stderr``.
# 
#     :param msg: the message to print
#     :type msg: str
#     """
# 
#     click.echo(click.style(msg, fg='red'), err=True)


import multiprocessing
import os
import shutil
import sys
import toml
import pkg_resources
from hashlib import sha512
from .extenders import DoesNotExistError
from .extenders.filesys import FilesysExtender
from .util import merge_dict, output_error
    for cls in get_extenders().values():
        if cls.can_handle(location):
            extender = cls
            break

    config = extender.retrieve(location, project_path)
    if 'extends' in config:
        del config['extends']

    if use_cache:
        put_config_cache(location, config)

    return config


def process_extensions(config, project_path, use_cache=True):
    extends = config['extends']
    if not extends:
        return config
    if isinstance(extends, str):
        extends = [extends]

    base = {}
    for location in extends:
        try:
            ext_config = retrieve_extension(
                location,
                project_path,
                use_cache=use_cache,
            )

# Path: src/tidypy/extenders/base.py
# class DoesNotExistError(ExtenderError):
#     """
#     An exception indicating that the specified Extender does not exist in the
#     current environment.
#     """
# 
# Path: src/tidypy/extenders/filesys.py
# class FilesysExtender(Extender):
#     @classmethod
#     def can_handle(cls, location):
#         return True
# 
#     @classmethod
#     def retrieve(cls, location, project_path):
#         path = Path(location)
#         if not path.is_absolute():
#             path = Path(project_path).joinpath(path)
#         if not path.exists():
#             raise DoesNotExistError()
# 
#         with path.open('r', encoding='utf-8') as config_file:
#             content = config_file.read()
# 
#         return cls.parse(
#             content,
#             is_pyproject=path.parts[-1] == 'pyproject.toml',
#         )
# 
# Path: src/tidypy/util.py
# def merge_dict(dict1, dict2, merge_lists=False):
#     """
#     Recursively merges the contents of two dictionaries into a new dictionary.
# 
#     When both input dictionaries share a key, the value from ``dict2`` is
#     kept.
# 
#     :param dict1: the first dictionary
#     :type dict1: dict
#     :param dict2: the second dictionary
#     :type dict2: dict
#     :param merge_lists:
#         when this function encounters a key that contains lists in both input
#         dictionaries, this parameter dictates whether or not those lists should
#         be merged. If not specified, defaults to ``False``.
#     :type merge_lists: bool
#     :returns: dict
#     """
# 
#     merged = dict(dict1)
# 
#     for key, value in dict2.items():
#         if isinstance(merged.get(key), dict):
#             merged[key] = merge_dict(merged[key], value)
#         elif merge_lists and isinstance(merged.get(key), list):
#             merged[key] = merge_list(merged[key], value)
#         else:
#             merged[key] = value
# 
#     return merged
# 
# def output_error(msg):
#     """
#     Prints the specified string to ``stderr``.
# 
#     :param msg: the message to print
#     :type msg: str
#     """
# 
#     click.echo(click.style(msg, fg='red'), err=True)


# Path: src/tidypy/config.py
import multiprocessing
import os
import shutil
import sys
import toml
import pkg_resources
from hashlib import sha512
from .extenders import DoesNotExistError
from .extenders.filesys import FilesysExtender
from .util import merge_dict, output_error

    for cls in get_extenders().values():
        if cls.can_handle(location):
            extender = cls
            break

    config = extender.retrieve(location, project_path)
    if 'extends' in config:
        del config['extends']

    if use_cache:
        put_config_cache(location, config)

    return config


def process_extensions(config, project_path, use_cache=True):
    extends = config['extends']
    if not extends:
        return config
    if isinstance(extends, str):
        extends = [extends]

    base = {}
    for location in extends:
        try:
            ext_config = retrieve_extension(
                location,
                project_path,
                use_cache=use_cache,
            )

        except DoesNotExistError: