<commit_before># -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2018.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Building blocks for Qiskit validated classes.

This module provides the ``BaseSchema`` and ``BaseModel`` classes as the main
building blocks for defining objects (Models) that conform to a specification
(Schema) and are validated at instantiation, along with providing facilities
for being serialized and deserialized.

Implementors are recommended to subclass the two classes, and "binding" them
together by using ``bind_schema``::

    class PersonSchema(BaseSchema):
        name = String(required=True)

    @bind_schema(PersonSchema)
    class Person(BaseModel):
        pass
"""

import warnings

from functools import wraps
from types import SimpleNamespace, MethodType

from marshmallow import ValidationError
from marshmallow import Schema, post_dump, post_load
from marshmallow import fields as _fields
from marshmallow.utils import is_collection, INCLUDE

from .exceptions import ModelValidationError


class ModelTypeValidator(_fields.Field):
    """A field able to validate the correct type of a value."""

    valid_types = (object, )

    def _expected_types(self):
        return self.valid_types

    def check_type(self, value, attr, data, **_):
        """Validates a value against the correct type of the field.

        It calls ``_expected_types`` to get a list of valid types.

        Subclasses can do one of the following:

        1. Override the ``valid_types`` property with a tuple with the expected
           types for this field.

        2. Override the ``_expected_types`` method to return a tuple of
           expected types for the field.

        3. Change ``check_type`` completely to customize validation.

        Note:
            This method or the overrides must return the ``value`` parameter
            untouched.
        """
        expected_types = self._expected_types()
        if not isinstance(value, expected_types):
            raise self._not_expected_type(
                value, expected_types, fields=[self], field_names=attr, data=data)
        return value

    @staticmethod
    def _not_expected_type(value, type_, **kwargs):
        if is_collection(type_) and len(type_) == 1:
            type_ = type_[0]

        if is_collection(type_):
            body = 'is none of the expected types {}'.format(type_)
        else:
            body = 'is not the expected type {}'.format(type_)

        message = 'Value \'{}\' {}: {}'.format(value, type(value), body)
        return ValidationError(message, **kwargs)

    def make_error_serialize(self, key, **kwargs):
        """Helper method to return a ValidationError from _serialize.

        This method wraps the result of ``make_error()``, adding contextual
        information in order to provide more informative information to users.

        Args:
            key (str): error key index.
            **kwargs: additional arguments to ``make_error()``.

        Returns:
            ValidationError: an exception with the field name.
        """
        bare_error = self.make_error(key, **kwargs)
        return ValidationError({self.name: bare_error.messages},
                               field_name=self.name)


class BaseSchema(Schema):
    """Base class for Schemas for validated Qiskit classes.

    Provides convenience functionality for the Qiskit common use case:

    * deserialization into class instances instead of dicts.
    * handling of unknown attributes not defined in the schema.

    Attributes:
         model_cls (type): class used to instantiate the instance. The
         constructor is passed all named parameters from deserialization.
    """

    class Meta:
        """Add extra fields to the schema."""
        unknown = INCLUDE

    model_cls = SimpleNamespace

    @post_dump(pass_original=True, pass_many=True)
    def dump_additional_data(self, valid_data, original_data, **kwargs):
        """Include unknown fields after dumping.

        Unknown fields are added with no processing at all.

        Args:
            valid_data (dict or list): data collected and returned by ``dump()``.
            original_data (object or list): object passed to ``dump()`` in the
                first place.
            **kwargs: extra arguments from the decorators.

        Returns:
            dict: the same ``valid_data`` extended with the unknown attributes.

        Inspired by https://github.com/marshmallow-code/marshmallow/pull/595.
        """
        if kwargs.get('many'):
            for i, _ in enumerate(valid_data):
                additional_keys = set(original_data[i].__dict__) - set(valid_data[i])
                for key in additional_keys:
                    valid_data[i][key] = getattr(original_data[i], key)
        else:
            additional_keys = set(original_data.__dict__) - set(valid_data)
            for key in additional_keys:
                valid_data[key] = getattr(original_data, key)

        return valid_data

    @post_load
    def make_model(self, data, **_):<commit_msg>don't serialize private attributes (#3451)<commit_after># -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2018.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Building blocks for Qiskit validated classes.

This module provides the ``BaseSchema`` and ``BaseModel`` classes as the main
building blocks for defining objects (Models) that conform to a specification
(Schema) and are validated at instantiation, along with providing facilities
for being serialized and deserialized.

Implementors are recommended to subclass the two classes, and "binding" them
together by using ``bind_schema``::

    class PersonSchema(BaseSchema):
        name = String(required=True)

    @bind_schema(PersonSchema)
    class Person(BaseModel):
        pass
"""

import warnings

from functools import wraps
from types import SimpleNamespace, MethodType

from marshmallow import ValidationError
from marshmallow import Schema, post_dump, post_load
from marshmallow import fields as _fields
from marshmallow.utils import is_collection, INCLUDE

from .exceptions import ModelValidationError


class ModelTypeValidator(_fields.Field):
    """A field able to validate the correct type of a value."""

    valid_types = (object, )

    def _expected_types(self):
        return self.valid_types

    def check_type(self, value, attr, data, **_):
        """Validates a value against the correct type of the field.

        It calls ``_expected_types`` to get a list of valid types.

        Subclasses can do one of the following:

        1. Override the ``valid_types`` property with a tuple with the expected
           types for this field.

        2. Override the ``_expected_types`` method to return a tuple of
           expected types for the field.

        3. Change ``check_type`` completely to customize validation.

        Note:
            This method or the overrides must return the ``value`` parameter
            untouched.
        """
        expected_types = self._expected_types()
        if not isinstance(value, expected_types):
            raise self._not_expected_type(
                value, expected_types, fields=[self], field_names=attr, data=data)
        return value

    @staticmethod
    def _not_expected_type(value, type_, **kwargs):
        if is_collection(type_) and len(type_) == 1:
            type_ = type_[0]

        if is_collection(type_):
            body = 'is none of the expected types {}'.format(type_)
        else:
            body = 'is not the expected type {}'.format(type_)

        message = 'Value \'{}\' {}: {}'.format(value, type(value), body)
        return ValidationError(message, **kwargs)

    def make_error_serialize(self, key, **kwargs):
        """Helper method to return a ValidationError from _serialize.

        This method wraps the result of ``make_error()``, adding contextual
        information in order to provide more informative information to users.

        Args:
            key (str): error key index.
            **kwargs: additional arguments to ``make_error()``.

        Returns:
            ValidationError: an exception with the field name.
        """
        bare_error = self.make_error(key, **kwargs)
        return ValidationError({self.name: bare_error.messages},
                               field_name=self.name)


class BaseSchema(Schema):
    """Base class for Schemas for validated Qiskit classes.

    Provides convenience functionality for the Qiskit common use case:

    * deserialization into class instances instead of dicts.
    * handling of unknown attributes not defined in the schema.

    Attributes:
         model_cls (type): class used to instantiate the instance. The
         constructor is passed all named parameters from deserialization.
    """

    class Meta:
        """Add extra fields to the schema."""
        unknown = INCLUDE

    model_cls = SimpleNamespace

    @post_dump(pass_original=True, pass_many=True)
    def dump_additional_data(self, valid_data, original_data, **kwargs):
        """Include unknown fields after dumping.

        Unknown fields are added with no processing at all.

        Args:
            valid_data (dict or list): data collected and returned by ``dump()``.
            original_data (object or list): object passed to ``dump()`` in the
                first place.
            **kwargs: extra arguments from the decorators.

        Returns:
            dict: the same ``valid_data`` extended with the unknown attributes.

        Inspired by https://github.com/marshmallow-code/marshmallow/pull/595.
        """
        if kwargs.get('many'):
            for i, _ in enumerate(valid_data):
                additional_keys = set(original_data[i].__dict__) - set(valid_data[i])
                for key in additional_keys:
                    if key.startswith('_'):
                        continue
                    valid_data[i][key] = getattr(original_data[i], key)
        else:
            additional_keys = set(original_data.__dict__) - set(valid_data)
            for key in additional_keys:
                if key.startswith('_'):
                    continue
                valid_data[key] = getattr(original_data, key)

        return valid_data

    @post_load
    def make_model(self, data, **_):
{'fraction_non_alphanumeric': 0.08192166352962266, 'fraction_numerical': 0.004122972125123241, 'mean_word_length': 2.6861579121242154, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, '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': '3276185', 'n_tokens_mistral': 2956, 'n_tokens_neox': 2790, 'n_words': 1110}