"""Dependency injector static providers. Powered by Cython. """ from dependency_injector.errors import Error from .base cimport Provider from .utils cimport ( ensure_is_provider, represent_provider, CLASS_TYPES, ) cdef class Object(Provider): """Object provider returns provided instance "as is". .. py:attribute:: provides Value that have to be provided. :type: object """ def __init__(self, provides): """Initializer. :param provides: Value that have to be provided. :type provides: object """ self.__provides = provides super(Object, self).__init__() def __str__(self): """Return string representation of provider. :rtype: str """ return represent_provider(provider=self, provides=self.__provides) def __repr__(self): """Return string representation of provider. :rtype: str """ return self.__str__() cpdef object _provide(self, tuple args, dict kwargs): """Return provided instance. :param args: Tuple of context positional arguments. :type args: tuple[object] :param kwargs: Dictionary of context keyword arguments. :type kwargs: dict[str, object] :rtype: object """ return self.__provides cdef class Delegate(Object): """Delegate provider returns provider "as is". .. py:attribute:: provides Value that have to be provided. :type: object """ def __init__(self, provides): """Initializer. :param provides: Value that have to be provided. :type provides: object """ super(Delegate, self).__init__(ensure_is_provider(provides)) cdef class ExternalDependency(Provider): """:py:class:`ExternalDependency` provider describes dependency interface. This provider is used for description of dependency interface. That might be useful when dependency could be provided in the client's code only, but it's interface is known. Such situations could happen when required dependency has non-determenistic list of dependencies itself. .. code-block:: python database_provider = ExternalDependency(sqlite3.dbapi2.Connection) database_provider.override(Factory(sqlite3.connect, ':memory:')) database = database_provider() .. py:attribute:: instance_of Class of required dependency. :type: type """ def __init__(self, type instance_of): """Initializer.""" if not isinstance(instance_of, CLASS_TYPES): raise Error('ExternalDependency provider expects to get class, ' + 'got {0} instead'.format(str(instance_of))) self.__instance_of = instance_of super(ExternalDependency, self).__init__() def __call__(self, *args, **kwargs): """Return provided instance. :param args: Tuple of context positional arguments. :type args: tuple[object] :param kwargs: Dictionary of context keyword arguments. :type kwargs: dict[str, object] :raise: :py:exc:`dependency_injector.errors.Error` :rtype: object """ cdef object instance if self.__overridden_len == 0: raise Error('Dependency is not defined') instance = self._call_last_overriding(args, kwargs) if not isinstance(instance, self.instance_of): raise Error('{0} is not an '.format(instance) + 'instance of {0}'.format(self.instance_of)) return instance def __str__(self): """Return string representation of provider. :rtype: str """ return represent_provider(provider=self, provides=self.__instance_of) def __repr__(self): """Return string representation of provider. :rtype: str """ return self.__str__() @property def instance_of(self): """Return class of required dependency.""" return self.__instance_of def provided_by(self, provider): """Set external dependency provider. :param provider: Provider that provides required dependency. :type provider: :py:class:`Provider` :rtype: None """ return self.override(provider)