# Path: doctor/errors.py
# class DoctorError(ValueError):
#     """Base error class for Doctor."""
#     def __init__(self, message, errors: dict = None):
#         self.errors = errors
#         super().__init__(message)
# 
# class SchemaError(DoctorError):
#     """Raised for errors in a schema."""
#     pass
# 
# class SchemaLoadingError(DoctorError):
#     """Raised when loading a resource and it is invalid."""
#     pass
# 
# class SchemaValidationError(DoctorError):
#     """Raised for errors when validating things against a schema."""
# 
#     def __init__(self, message, errors=None):
#         super(SchemaValidationError, self).__init__(message)
#         self.errors = errors
# 
# Path: doctor/parsers.py
# def parse_json(value: str, sig_params: List[inspect.Parameter] = None) -> dict:
#     """Parse a value as JSON.
# 
#     This is just a wrapper around json.loads which re-raises any errors as a
#     ParseError instead.
# 
#     :param str value: JSON string.
#     :param dict sig_params: The logic function's signature parameters.
#     :returns: the parsed JSON value
#     """
#     try:
#         loaded = json.loads(value)
#     except Exception as e:
#         message = 'Error parsing JSON: %r error: %s' % (value, e)
#         logging.debug(message, exc_info=e)
#         raise ParseError(message)
# 
#     if sig_params is not None:
#         return map_param_names(loaded, sig_params)
#     return loaded


import logging
import os
import jsonschema
import yaml
from jsonschema.compat import urldefrag
from .errors import (
    DoctorError, SchemaError, SchemaLoadingError, SchemaValidationError)
from .parsers import parse_json
        :raises SchemaError:
        """
        try:
            # This logic is basically the RefResolver's resolve function, but
            # updated to support fragments of dynamic documents. The jsonschema
            # module supports passing documents when resolving fragments, but
            # it doesn't expose that capability in the resolve function.
            url = self._urljoin_cache(self.resolution_scope, ref)
            if document is None:
                # No document passed, so just resolve it as we normally would.
                resolved = self._remote_cache(url)
            else:
                # Document passed, so assume it's a fragment.
                _, fragment = urldefrag(url)
                resolved = self.resolve_fragment(document, fragment)
        except jsonschema.RefResolutionError as e:
            # Failed to find a ref. Make the error a bit prettier so we can
            # figure out where it came from.
            message = e.args[0]
            if self._scopes_stack:
                message = '{} (from {})'.format(
                    message, self._format_stack(self._scopes_stack))
            raise SchemaError(message)

        if isinstance(resolved, dict) and '$ref' in resolved:
            # Try to resolve the reference, so we can get the actual value we
            # want, instead of a useless dict with a $ref in it.
            if url in self._scopes_stack:
                # We've already tried to look up this URL, so this must
                # be a circular reference in the schema.

# Path: doctor/errors.py
# class DoctorError(ValueError):
#     """Base error class for Doctor."""
#     def __init__(self, message, errors: dict = None):
#         self.errors = errors
#         super().__init__(message)
# 
# class SchemaError(DoctorError):
#     """Raised for errors in a schema."""
#     pass
# 
# class SchemaLoadingError(DoctorError):
#     """Raised when loading a resource and it is invalid."""
#     pass
# 
# class SchemaValidationError(DoctorError):
#     """Raised for errors when validating things against a schema."""
# 
#     def __init__(self, message, errors=None):
#         super(SchemaValidationError, self).__init__(message)
#         self.errors = errors
# 
# Path: doctor/parsers.py
# def parse_json(value: str, sig_params: List[inspect.Parameter] = None) -> dict:
#     """Parse a value as JSON.
# 
#     This is just a wrapper around json.loads which re-raises any errors as a
#     ParseError instead.
# 
#     :param str value: JSON string.
#     :param dict sig_params: The logic function's signature parameters.
#     :returns: the parsed JSON value
#     """
#     try:
#         loaded = json.loads(value)
#     except Exception as e:
#         message = 'Error parsing JSON: %r error: %s' % (value, e)
#         logging.debug(message, exc_info=e)
#         raise ParseError(message)
# 
#     if sig_params is not None:
#         return map_param_names(loaded, sig_params)
#     return loaded


# Path: doctor/schema.py
import logging
import os
import jsonschema
import yaml
from jsonschema.compat import urldefrag
from .errors import (
    DoctorError, SchemaError, SchemaLoadingError, SchemaValidationError)
from .parsers import parse_json

        :raises SchemaError:
        """
        try:
            # This logic is basically the RefResolver's resolve function, but
            # updated to support fragments of dynamic documents. The jsonschema
            # module supports passing documents when resolving fragments, but
            # it doesn't expose that capability in the resolve function.
            url = self._urljoin_cache(self.resolution_scope, ref)
            if document is None:
                # No document passed, so just resolve it as we normally would.
                resolved = self._remote_cache(url)
            else:
                # Document passed, so assume it's a fragment.
                _, fragment = urldefrag(url)
                resolved = self.resolve_fragment(document, fragment)
        except jsonschema.RefResolutionError as e:
            # Failed to find a ref. Make the error a bit prettier so we can
            # figure out where it came from.
            message = e.args[0]
            if self._scopes_stack:
                message = '{} (from {})'.format(
                    message, self._format_stack(self._scopes_stack))
            raise SchemaError(message)

        if isinstance(resolved, dict) and '$ref' in resolved:
            # Try to resolve the reference, so we can get the actual value we
            # want, instead of a useless dict with a $ref in it.
            if url in self._scopes_stack:
                # We've already tried to look up this URL, so this must
                # be a circular reference in the schema.

                raise SchemaError(