<commit_before>from collections.abc import Container, Mapping
from copy import copy
from typing import Dict, Hashable, MutableMapping, Sequence, Set

from cerberus import errors
from cerberus.base import (
    normalize_schema,
    rules_set_registry,
    RulesSetRegistry,
    SchemaError,
    SchemaRegistry,
    TypeDefinition,
    UnconcernedValidator,
    normalize_rulesset,
)
from cerberus.platform import _GenericAlias
from cerberus.typing import SchemaDict


class SchemaValidator(UnconcernedValidator):
    """ This validator provides mechanics to validate schemas passed to a Cerberus
        validator. """

    types_mapping = UnconcernedValidator.types_mapping.copy()
    types_mapping.update(
        {
            "container_but_not_string": TypeDefinition(
                "container_but_not_string", (Container,), (str,)
            ),
            "generic_type_alias": TypeDefinition(
                "generic_type_alias", (_GenericAlias,), ()
            ),
        }
    )

    @property
    def known_rules_set_refs(self):
        """ The encountered references to rules set registry items. """
        return self._config.get('known_rules_set_refs', ())

    @known_rules_set_refs.setter
    def known_rules_set_refs(self, value):
        self._config['known_rules_set_refs'] = value

    @property
    def known_schema_refs(self):
        """ The encountered references to schema registry items. """
        return self._config.get('known_schema_refs', ())

    @known_schema_refs.setter
    def known_schema_refs(self, value):
        self._config['known_schema_refs'] = value

    @property
    def target_validator(self):
        """ The validator whose schema is being validated. """
        return self._config['target_validator']

    def _check_with_dependencies(self, field, value):
        if isinstance(value, str):
            return
        elif isinstance(value, Mapping):
            validator = self._get_child_validator(
                document_crumb=field,
                schema={'valuesrules': {'type': ('list',)}},
                allow_unknown=True,
            )
            if not validator(value, normalize=False):
                self._error(validator._errors)
        elif isinstance(value, Sequence):
            if not all(isinstance(x, Hashable) for x in value):
                path = self.document_path + (field,)
                self._error(path, 'All dependencies must be a hashable type.')

    def _check_with_items(self, field, value):
        self._check_with_schema(
            field, {i: rules_set for i, rules_set in enumerate(value)}
        )

    def _check_with_rulesset(self, field, value):
        # resolve schema registry reference
        if isinstance(value, str):
            if value in self.known_rules_set_refs:
                return
            else:
                self.known_rules_set_refs += (value,)
            definition = self.target_validator.rules_set_registry.get(value)
            if definition is None:
                self._error(field, "Rules set definition '{}' not found.".format(value))
                return
            else:
                value = definition

        _hash = (
            schema_hash({'turing': value}),
            schema_hash(self.target_validator.types_mapping),
        )
        if _hash in self.target_validator._valid_schemas:
            return

        validator = self._get_child_validator(
            document_crumb=field,
            allow_unknown=False,
            schema=self.target_validator.rules,
        )
        validator(value, normalize=False)
        if validator._errors:
            self._error(validator._errors)
        else:
            self.target_validator._valid_schemas.add(_hash)

    def _check_with_schema(self, field, value):
        if isinstance(value, str):
            if value in self.known_schema_refs:
                return

            self.known_schema_refs += (value,)
            definition = self.target_validator.schema_registry.get(value)
            if definition is None:
                path = self.document_path + (field,)<commit_msg>Stores visited references in sets when validating schemas<commit_after>from collections.abc import Container, Mapping
from copy import copy
from typing import Dict, Hashable, MutableMapping, Sequence, Set

from cerberus import errors
from cerberus.base import (
    normalize_schema,
    rules_set_registry,
    RulesSetRegistry,
    SchemaError,
    SchemaRegistry,
    TypeDefinition,
    UnconcernedValidator,
    normalize_rulesset,
)
from cerberus.platform import _GenericAlias
from cerberus.typing import SchemaDict


class SchemaValidator(UnconcernedValidator):
    """ This validator provides mechanics to validate schemas passed to a Cerberus
        validator. """

    types_mapping = UnconcernedValidator.types_mapping.copy()
    types_mapping.update(
        {
            "container_but_not_string": TypeDefinition(
                "container_but_not_string", (Container,), (str,)
            ),
            "generic_type_alias": TypeDefinition(
                "generic_type_alias", (_GenericAlias,), ()
            ),
        }
    )

    def __init__(self, *args, **kwargs):
        kwargs.setdefault("known_rules_set_refs", set())
        kwargs.setdefault("known_schema_refs", set())
        super().__init__(*args, **kwargs)

    @property
    def known_rules_set_refs(self):
        """ The encountered references to rules set registry items. """
        return self._config["known_rules_set_refs"]

    @property
    def known_schema_refs(self):
        """ The encountered references to schema registry items. """
        return self._config["known_schema_refs"]

    @property
    def target_validator(self):
        """ The validator whose schema is being validated. """
        return self._config['target_validator']

    def _check_with_dependencies(self, field, value):
        if isinstance(value, str):
            return
        elif isinstance(value, Mapping):
            validator = self._get_child_validator(
                document_crumb=field,
                schema={'valuesrules': {'type': ('list',)}},
                allow_unknown=True,
            )
            if not validator(value, normalize=False):
                self._error(validator._errors)
        elif isinstance(value, Sequence):
            if not all(isinstance(x, Hashable) for x in value):
                path = self.document_path + (field,)
                self._error(path, 'All dependencies must be a hashable type.')

    def _check_with_items(self, field, value):
        self._check_with_schema(
            field, {i: rules_set for i, rules_set in enumerate(value)}
        )

    def _check_with_rulesset(self, field, value):
        # resolve schema registry reference
        if isinstance(value, str):
            if value in self.known_rules_set_refs:
                return
            else:
                self.known_rules_set_refs.add(value)
            definition = self.target_validator.rules_set_registry.get(value)
            if definition is None:
                self._error(field, "Rules set definition '{}' not found.".format(value))
                return
            else:
                value = definition

        _hash = (
            schema_hash({'turing': value}),
            schema_hash(self.target_validator.types_mapping),
        )
        if _hash in self.target_validator._valid_schemas:
            return

        validator = self._get_child_validator(
            document_crumb=field,
            allow_unknown=False,
            schema=self.target_validator.rules,
        )
        validator(value, normalize=False)
        if validator._errors:
            self._error(validator._errors)
        else:
            self.target_validator._valid_schemas.add(_hash)

    def _check_with_schema(self, field, value):
        if isinstance(value, str):
            if value in self.known_schema_refs:
                return

            self.known_schema_refs.add(value)
            definition = self.target_validator.schema_registry.get(value)
            if definition is None:
                path = self.document_path + (field,)
{'fraction_non_alphanumeric': 0.08672847035862405, 'fraction_numerical': 0.0, 'mean_word_length': 2.3033843674456085, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5959198', 'n_tokens_mistral': 2244, 'n_tokens_neox': 2155, 'n_words': 506}