<commit_before>"""Providers module."""

import six

from .injections import _parse_args_injections
from .injections import _parse_kwargs_injections
from .injections import _get_injectable_args
from .injections import _get_injectable_kwargs

from .utils import ensure_is_provider
from .utils import is_attribute_injection
from .utils import is_method_injection
from .utils import GLOBAL_LOCK

from .errors import Error


class Provider(object):
    """Base provider class.

    :py:class:`Provider` is callable (implements ``__call__`` method). Every
    call to provider object returns provided result, according to the providing
    strategy of particular provider. This ``callable`` functionality is a
    regular part of providers API and it should be the same for all provider's
    subclasses.

    Implementation of particular providing strategy should be done in
    :py:meth:`Provider._provide` of :py:class:`Provider` subclass. Current
    method is called every time when not overridden provider is called.

    :py:class:`Provider` implements provider overriding logic that should be
    also common for all providers.

    .. code-block:: python

        provider1 = Factory(SomeClass)
        provider2 = Factory(ChildSomeClass)

        provider1.override(provider2)

        some_instance = provider1()
        assert isinstance(some_instance, ChildSomeClass)

    Also :py:class:`Provider` implements helper function for creating its
    delegates:

    .. code-block:: python

        provider = Factory(object)
        delegate = provider.delegate()

        delegated = delegate()

        assert provider is delegated

    All providers should extend this class.
    """

    __IS_PROVIDER__ = True
    __slots__ = ('overridden_by',)

    def __init__(self):
        """Initializer."""
        self.overridden_by = None
        """Tuple of overriding providers, if any.

        :type: tuple[:py:class:`Provider`] | None
        """

        super(Provider, self).__init__()

    def __call__(self, *args, **kwargs):
        """Return provided instance.

        Implementation of current method adds ``callable`` functionality for
        providers API and it should be common for all provider's subclasses.
        Also this method implements provider overriding logic that is also
        common for all providers. Implementation of particular providing
        strategy should be done in :py:meth:`Provider._provide` of
        :py:class:`Provider` subclass.
        """
        if self.overridden_by:
            return self.last_overriding(*args, **kwargs)
        return self._provide(*args, **kwargs)

    def _provide(self, *args, **kwargs):
        """Providing strategy implementation.

        Abstract protected method that implements providing strategy of
        particular provider. Current method is called every time when not
        overridden provider is called. Need to be overridden in subclasses.
        """
        raise NotImplementedError()

    @property
    def is_overridden(self):
        """Read-only property that is set to ``True`` if provider is overridden.

        :rtype: bool
        """
        return bool(self.overridden_by)

    @property
    def last_overriding(self):
        """Read-only reference to the last overriding provider, if any.

        :type: :py:class:`Provider` | None
        """
        return self.overridden_by[-1] if self.overridden_by else None

    def override(self, provider):
        """Override provider with another provider.

        :param provider: Overriding provider.
        :type provider: :py:class:`Provider`

        :raise: :py:exc:`dependency_injector.errors.Error`
        """
        if provider is self:
            raise Error('Provider {0} could not be overridden '
                        'with itself'.format(self))
        if not self.is_overridden:
            self.overridden_by = (ensure_is_provider(provider),)
        else:
            self.overridden_by += (ensure_is_provider(provider),)

    def reset_last_overriding(self):
        """Reset last overriding provider.

        :rtype: None
        """
        if not self.overridden_by:
            raise Error('Provider {0} is not overridden'.format(str(self)))<commit_msg>Update providers module API docs<commit_after>"""Providers module."""

import six

from .injections import _parse_args_injections
from .injections import _parse_kwargs_injections
from .injections import _get_injectable_args
from .injections import _get_injectable_kwargs

from .utils import ensure_is_provider
from .utils import is_attribute_injection
from .utils import is_method_injection
from .utils import GLOBAL_LOCK

from .errors import Error


class Provider(object):
    """Base provider class.

    :py:class:`Provider` is callable (implements ``__call__`` method). Every
    call to provider object returns provided result, according to the providing
    strategy of particular provider. This ``callable`` functionality is a
    regular part of providers API and it should be the same for all provider's
    subclasses.

    Implementation of particular providing strategy should be done in
    :py:meth:`Provider._provide` of :py:class:`Provider` subclass. Current
    method is called every time when not overridden provider is called.

    :py:class:`Provider` implements provider overriding logic that should be
    also common for all providers:

    .. code-block:: python

        provider1 = Factory(SomeClass)
        provider2 = Factory(ChildSomeClass)

        provider1.override(provider2)

        some_instance = provider1()
        assert isinstance(some_instance, ChildSomeClass)

    Also :py:class:`Provider` implements helper function for creating its
    delegates:

    .. code-block:: python

        provider = Factory(object)
        delegate = provider.delegate()

        delegated = delegate()

        assert provider is delegated

    All providers should extend this class.
    """

    __IS_PROVIDER__ = True
    __slots__ = ('overridden_by',)

    def __init__(self):
        """Initializer."""
        self.overridden_by = None
        """Tuple of overriding providers, if any.

        :type: tuple[:py:class:`Provider`] | None
        """

        super(Provider, self).__init__()

    def __call__(self, *args, **kwargs):
        """Return provided instance.

        Implementation of current method adds ``callable`` functionality for
        providers API and it should be common for all provider's subclasses.
        Also this method implements provider overriding logic that is also
        common for all providers. Implementation of particular providing
        strategy should be done in :py:meth:`Provider._provide` of
        :py:class:`Provider` subclass.
        """
        if self.overridden_by:
            return self.last_overriding(*args, **kwargs)
        return self._provide(*args, **kwargs)

    def _provide(self, *args, **kwargs):
        """Providing strategy implementation.

        Abstract protected method that implements providing strategy of
        particular provider. Current method is called every time when not
        overridden provider is called. Need to be overridden in subclasses.
        """
        raise NotImplementedError()

    @property
    def is_overridden(self):
        """Read-only property that is set to ``True`` if provider is overridden.

        :rtype: bool
        """
        return bool(self.overridden_by)

    @property
    def last_overriding(self):
        """Read-only reference to the last overriding provider, if any.

        :type: :py:class:`Provider` | None
        """
        return self.overridden_by[-1] if self.overridden_by else None

    def override(self, provider):
        """Override provider with another provider.

        :param provider: Overriding provider.
        :type provider: :py:class:`Provider`

        :raise: :py:exc:`dependency_injector.errors.Error`
        """
        if provider is self:
            raise Error('Provider {0} could not be overridden '
                        'with itself'.format(self))
        if not self.is_overridden:
            self.overridden_by = (ensure_is_provider(provider),)
        else:
            self.overridden_by += (ensure_is_provider(provider),)

    def reset_last_overriding(self):
        """Reset last overriding provider.

        :raise: :py:exc:`dependency_injector.errors.Error` if provider is not
                overridden.

        :rtype: None
        """
        if not self.overridden_by:
            raise Error('Provider {0} is not overridden'.format(str(self)))
{'fraction_non_alphanumeric': 0.08358486185279777, 'fraction_numerical': 0.0018574413745066172, 'mean_word_length': 2.8442659526996876, 'pattern_counts': {'":': 0, '<': 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': '7036373', 'n_tokens_mistral': 2292, 'n_tokens_neox': 2175, 'n_words': 762}