mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 18:07:44 +03:00 
			
		
		
		
	Get 1st stable version
This commit is contained in:
		
							parent
							
								
									459ff5fcf5
								
							
						
					
					
						commit
						b2008b2dc3
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -89,10 +89,17 @@ cdef class CoroutineDelegate(Delegate):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Configuration providers
 | 
					# Configuration providers
 | 
				
			||||||
 | 
					cdef class ConfigurationOption(Provider):
 | 
				
			||||||
 | 
					    cdef str __name
 | 
				
			||||||
 | 
					    cdef object __root_ref
 | 
				
			||||||
 | 
					    cdef dict __children
 | 
				
			||||||
 | 
					    cdef object __cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cdef class Configuration(Object):
 | 
					cdef class Configuration(Object):
 | 
				
			||||||
    cdef str __name
 | 
					    cdef str __name
 | 
				
			||||||
    cdef dict __children
 | 
					    cdef dict __children
 | 
				
			||||||
    cdef list __linked
 | 
					    cdef object __weakref__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Factory providers
 | 
					# Factory providers
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ import re
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import types
 | 
					import types
 | 
				
			||||||
import threading
 | 
					import threading
 | 
				
			||||||
 | 
					import weakref
 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    import asyncio
 | 
					    import asyncio
 | 
				
			||||||
| 
						 | 
					@ -1045,158 +1046,79 @@ cdef class CoroutineDelegate(Delegate):
 | 
				
			||||||
        super(CoroutineDelegate, self).__init__(coroutine)
 | 
					        super(CoroutineDelegate, self).__init__(coroutine)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cdef class Configuration(Object):
 | 
					cdef class ConfigurationOption(Provider):
 | 
				
			||||||
    """Configuration provider provides configuration options to the other providers.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. code-block:: python
 | 
					    UNDEFINED = object()
 | 
				
			||||||
 | 
					 | 
				
			||||||
        config = Configuration('config')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        print(config.section1.option1())  # None
 | 
					 | 
				
			||||||
        print(config.section1.option2())  # None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        config.from_dict(
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                'section1': {
 | 
					 | 
				
			||||||
                    'option1': 1,
 | 
					 | 
				
			||||||
                    'option2': 2,
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        print(config.section1.option1())  # 1
 | 
					 | 
				
			||||||
        print(config.section1.option2())  # 2
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    DEFAULT_NAME = 'config'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, name=None, default=None):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param name: Name of configuration unit.
 | 
					 | 
				
			||||||
        :type name: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param default: Default values of configuration unit.
 | 
					 | 
				
			||||||
        :type default: dict
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        super(Configuration, self).__init__(default)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if name is None:
 | 
					 | 
				
			||||||
            name = self.DEFAULT_NAME
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, name, root):
 | 
				
			||||||
        self.__name = name
 | 
					        self.__name = name
 | 
				
			||||||
        self.__children = self._create_children(default)
 | 
					        self.__root_ref = weakref.ref(root)
 | 
				
			||||||
        self.__linked = list()
 | 
					        self.__children = {}
 | 
				
			||||||
 | 
					        self.__cache = self.UNDEFINED
 | 
				
			||||||
 | 
					        super().__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __deepcopy__(self, memo):
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
        """Create and return full copy of provider."""
 | 
					        cdef ConfigurationOption copied
 | 
				
			||||||
        cdef Configuration copied
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        copied = memo.get(id(self))
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
        if copied is not None:
 | 
					        if copied is not None:
 | 
				
			||||||
            return copied
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        copied = self.__class__(self.__name)
 | 
					        copied_root = memo[id(self.__root_ref())]
 | 
				
			||||||
        copied.__provides = deepcopy(self.__provides, memo)
 | 
					 | 
				
			||||||
        copied.__children = deepcopy(self.__children, memo)
 | 
					 | 
				
			||||||
        copied.__linked = deepcopy(self.__linked, memo)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._copy_overridings(copied, memo)
 | 
					        copied = self.__class__(self.__name, copied_root)
 | 
				
			||||||
 | 
					        copied.__children = deepcopy(self.__children, memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return copied
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        """Return string representation of provider.
 | 
					        return represent_provider(provider=self, provides=self.get_name())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: str
 | 
					    def __getattr__(self, item):
 | 
				
			||||||
        """
 | 
					        if item.startswith('__') and item.endswith('__'):
 | 
				
			||||||
        return represent_provider(provider=self, provides=self.__name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __getattr__(self, str name):
 | 
					 | 
				
			||||||
        """Return child configuration provider."""
 | 
					 | 
				
			||||||
        if name.startswith('__') and name.endswith('__'):
 | 
					 | 
				
			||||||
            raise AttributeError(
 | 
					            raise AttributeError(
 | 
				
			||||||
                '\'{cls}\' object has no attribute '
 | 
					                '\'{cls}\' object has no attribute '
 | 
				
			||||||
                '\'{attribute_name}\''.format(cls=self.__class__.__name__,
 | 
					                '\'{attribute_name}\''.format(cls=self.__class__.__name__,
 | 
				
			||||||
                                              attribute_name=name))
 | 
					                                              attribute_name=item))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        child_provider = self.__children.get(name)
 | 
					        child = self.__children.get(item)
 | 
				
			||||||
 | 
					        if child is None:
 | 
				
			||||||
 | 
					            child_name = '.'.join((self.__name, item))
 | 
				
			||||||
 | 
					            child = ConfigurationOption(child_name, self.__root_ref())
 | 
				
			||||||
 | 
					            self.__children[item] = child
 | 
				
			||||||
 | 
					        return child
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if child_provider is None:
 | 
					    cpdef object _provide(self, tuple args, dict kwargs):
 | 
				
			||||||
            child_name = self._get_child_full_name(name)
 | 
					        """Return new instance."""
 | 
				
			||||||
            child_provider = self.__class__(child_name)
 | 
					        if self.__cache is not self.UNDEFINED:
 | 
				
			||||||
 | 
					            return self.__cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            value = self.__call__()
 | 
					        root = self.__root_ref()
 | 
				
			||||||
            if isinstance(value, dict):
 | 
					        value = root.get(self.__name)
 | 
				
			||||||
                child_value = value.get(name)
 | 
					        self.__cache = value
 | 
				
			||||||
                child_provider.override(child_value)
 | 
					        return value
 | 
				
			||||||
 | 
					 | 
				
			||||||
            self.__children[name] = child_provider
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return child_provider
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_name(self):
 | 
					    def get_name(self):
 | 
				
			||||||
        """Name of configuration unit."""
 | 
					        root = self.__root_ref()
 | 
				
			||||||
        return self.__name
 | 
					        name = '.'.join((root.get_name(), self.__name))
 | 
				
			||||||
 | 
					        return name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def override(self, provider):
 | 
					    def override(self, value):
 | 
				
			||||||
        """Override provider with another provider.
 | 
					        if isinstance(value, Provider):
 | 
				
			||||||
 | 
					            raise Error('Configuration option can only be overridden by a value')
 | 
				
			||||||
        :param provider: Overriding provider.
 | 
					        root = self.__root_ref()
 | 
				
			||||||
        :type provider: :py:class:`Provider`
 | 
					        return root.set(self.__name, value)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :return: Overriding context.
 | 
					 | 
				
			||||||
        :rtype: :py:class:`OverridingContext`
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        overriding_context = super(Configuration, self).override(provider)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for linked in self.__linked:
 | 
					 | 
				
			||||||
            linked.override(provider)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if isinstance(provider, Configuration):
 | 
					 | 
				
			||||||
            provider.link_provider(self)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        value = self.__call__()
 | 
					 | 
				
			||||||
        if not isinstance(value, dict):
 | 
					 | 
				
			||||||
            return overriding_context
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for name in value.keys():
 | 
					 | 
				
			||||||
            child_provider = self.__children.get(name)
 | 
					 | 
				
			||||||
            if child_provider is None:
 | 
					 | 
				
			||||||
                continue
 | 
					 | 
				
			||||||
            child_provider.override(value.get(name))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return overriding_context
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reset_last_overriding(self):
 | 
					    def reset_last_overriding(self):
 | 
				
			||||||
        """Reset last overriding provider.
 | 
					        raise Error('Configuration option does not support this method')
 | 
				
			||||||
 | 
					 | 
				
			||||||
        :raise: :py:exc:`dependency_injector.errors.Error` if provider is not
 | 
					 | 
				
			||||||
                overridden.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        for child in self.__children.values():
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                child.reset_last_overriding()
 | 
					 | 
				
			||||||
            except Error:
 | 
					 | 
				
			||||||
                pass
 | 
					 | 
				
			||||||
        super(Configuration, self).reset_last_overriding()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reset_override(self):
 | 
					    def reset_override(self):
 | 
				
			||||||
        """Reset all overriding providers.
 | 
					        raise Error('Configuration option does not support this method')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					    def reset_cache(self):
 | 
				
			||||||
        """
 | 
					        self.__cache = self.UNDEFINED
 | 
				
			||||||
        for child in self.__children.values():
 | 
					        for child in self.__children.values():
 | 
				
			||||||
            child.reset_override()
 | 
					            child.reset_cache()
 | 
				
			||||||
        super(Configuration, self).reset_override()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def link_provider(self, provider):
 | 
					 | 
				
			||||||
        """Configuration link two configuration providers."""
 | 
					 | 
				
			||||||
        self.__linked.append(<Configuration?>provider)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update(self, value):
 | 
					    def update(self, value):
 | 
				
			||||||
        """Set configuration options.
 | 
					        """Set configuration options.
 | 
				
			||||||
| 
						 | 
					@ -1290,27 +1212,192 @@ cdef class Configuration(Object):
 | 
				
			||||||
        value = os.getenv(name, default)
 | 
					        value = os.getenv(name, default)
 | 
				
			||||||
        self.override(value)
 | 
					        self.override(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _create_children(self, value):
 | 
					 | 
				
			||||||
        children = dict()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not isinstance(value, dict):
 | 
					cdef class Configuration(Object):
 | 
				
			||||||
            return children
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for child_name, child_value in value.items():
 | 
					    DEFAULT_NAME = 'config'
 | 
				
			||||||
            child_full_name = self._get_child_full_name(child_name)
 | 
					 | 
				
			||||||
            child_provider = self.__class__(child_full_name, child_value)
 | 
					 | 
				
			||||||
            children[child_name] = child_provider
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return children
 | 
					    def __init__(self, name=DEFAULT_NAME, default=None):
 | 
				
			||||||
 | 
					        self.__name = name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _get_child_full_name(self, child_name):
 | 
					        value = {}
 | 
				
			||||||
        child_full_name = ''
 | 
					        if default is not None:
 | 
				
			||||||
 | 
					            assert isinstance(default, dict), default
 | 
				
			||||||
 | 
					            value = default.copy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.__name:
 | 
					        self.__children = {}
 | 
				
			||||||
            child_full_name += self.__name + '.'
 | 
					 | 
				
			||||||
        child_full_name += child_name
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return child_full_name
 | 
					        super().__init__(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        cdef Configuration copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied = self.__class__(self.__name, self.__provides)
 | 
				
			||||||
 | 
					        memo[id(self)] = copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied.__children = deepcopy(self.__children, memo)
 | 
				
			||||||
 | 
					        self._copy_overridings(copied, memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        return represent_provider(provider=self, provides=self.__name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __getattr__(self, item):
 | 
				
			||||||
 | 
					        if item.startswith('__') and item.endswith('__'):
 | 
				
			||||||
 | 
					            raise AttributeError(
 | 
				
			||||||
 | 
					                '\'{cls}\' object has no attribute '
 | 
				
			||||||
 | 
					                '\'{attribute_name}\''.format(cls=self.__class__.__name__,
 | 
				
			||||||
 | 
					                                              attribute_name=item))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        child = self.__children.get(item)
 | 
				
			||||||
 | 
					        if child is None:
 | 
				
			||||||
 | 
					            child = ConfigurationOption(item, self)
 | 
				
			||||||
 | 
					            self.__children[item] = child
 | 
				
			||||||
 | 
					        return child
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_name(self):
 | 
				
			||||||
 | 
					        return self.__name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get(self, selector):
 | 
				
			||||||
 | 
					        keys = selector.split('.')
 | 
				
			||||||
 | 
					        value = self.__call__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while len(keys) > 0:
 | 
				
			||||||
 | 
					            key = keys.pop(0)
 | 
				
			||||||
 | 
					            value = value.get(key)
 | 
				
			||||||
 | 
					            if value is None:
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set(self, selector, value):
 | 
				
			||||||
 | 
					        keys = selector.split('.')
 | 
				
			||||||
 | 
					        original_value = current_value = self.__call__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while len(keys) > 0:
 | 
				
			||||||
 | 
					            key = keys.pop(0)
 | 
				
			||||||
 | 
					            if len(keys) == 0:
 | 
				
			||||||
 | 
					                current_value[key] = value
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					            temp_value = current_value.get(key, {})
 | 
				
			||||||
 | 
					            current_value[key] = temp_value
 | 
				
			||||||
 | 
					            current_value = temp_value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return self.override(original_value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def override(self, provider):
 | 
				
			||||||
 | 
					        context = super().override(provider)
 | 
				
			||||||
 | 
					        self.reset_cache()
 | 
				
			||||||
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_last_overriding(self):
 | 
				
			||||||
 | 
					        super().reset_last_overriding()
 | 
				
			||||||
 | 
					        self.reset_cache()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_override(self):
 | 
				
			||||||
 | 
					        super().reset_override()
 | 
				
			||||||
 | 
					        self.reset_cache()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_cache(self):
 | 
				
			||||||
 | 
					        for child in self.__children.values():
 | 
				
			||||||
 | 
					            child.reset_cache()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def update(self, value):
 | 
				
			||||||
 | 
					        """Set configuration options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .. deprecated:: 3.11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Use :py:meth:`Configuration.override` instead.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param value: Value of configuration option.
 | 
				
			||||||
 | 
					        :type value: object | dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.override(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_ini(self, filepath):
 | 
				
			||||||
 | 
					        """Load configuration from the ini file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Loaded configuration is merged recursively over existing configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param filepath: Path to the configuration file.
 | 
				
			||||||
 | 
					        :type filepath: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        parser = _parse_ini_file(filepath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        config = {}
 | 
				
			||||||
 | 
					        for section in parser.sections():
 | 
				
			||||||
 | 
					            config[section] = dict(parser.items(section))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        current_config = self.__call__()
 | 
				
			||||||
 | 
					        if not current_config:
 | 
				
			||||||
 | 
					            current_config = {}
 | 
				
			||||||
 | 
					        self.override(merge_dicts(current_config, config))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_yaml(self, filepath):
 | 
				
			||||||
 | 
					        """Load configuration from the yaml file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Loaded configuration is merged recursively over existing configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param filepath: Path to the configuration file.
 | 
				
			||||||
 | 
					        :type filepath: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if yaml is None:
 | 
				
			||||||
 | 
					            raise Error(
 | 
				
			||||||
 | 
					                'Unable to load yaml configuration - PyYAML is not installed. '
 | 
				
			||||||
 | 
					                'Install PyYAML or install Dependency Injector with yaml extras: '
 | 
				
			||||||
 | 
					                '"pip install dependency-injector[yaml]"'
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            with open(filepath) as opened_file:
 | 
				
			||||||
 | 
					                config = yaml.load(opened_file, yaml.Loader)
 | 
				
			||||||
 | 
					        except IOError:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        current_config = self.__call__()
 | 
				
			||||||
 | 
					        if not current_config:
 | 
				
			||||||
 | 
					            current_config = {}
 | 
				
			||||||
 | 
					        self.override(merge_dicts(current_config, config))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_dict(self, options):
 | 
				
			||||||
 | 
					        """Load configuration from the dictionary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Loaded configuration is merged recursively over existing configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param options: Configuration options.
 | 
				
			||||||
 | 
					        :type options: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        current_config = self.__call__()
 | 
				
			||||||
 | 
					        if not current_config:
 | 
				
			||||||
 | 
					            current_config = {}
 | 
				
			||||||
 | 
					        self.override(merge_dicts(current_config, options))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_env(self, name, default=None):
 | 
				
			||||||
 | 
					        """Load configuration value from the environment variable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param name: Name of the environment variable.
 | 
				
			||||||
 | 
					        :type name: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param default: Default value that is used if environment variable does not exist.
 | 
				
			||||||
 | 
					        :type default: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        value = os.getenv(name, default)
 | 
				
			||||||
 | 
					        self.override(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cdef class Factory(Provider):
 | 
					cdef class Factory(Provider):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										367
									
								
								src/dependency_injector/providers2.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								src/dependency_injector/providers2.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,367 @@
 | 
				
			||||||
 | 
					import weakref
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ConfigurationOption(providers.Provider):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    UNDEFINED = object()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, name, root):
 | 
				
			||||||
 | 
					        self._name = name
 | 
				
			||||||
 | 
					        self._root_ref = weakref.ref(root)
 | 
				
			||||||
 | 
					        self._children = {}
 | 
				
			||||||
 | 
					        self._cache = self.UNDEFINED
 | 
				
			||||||
 | 
					        super().__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        root = self._root_ref()
 | 
				
			||||||
 | 
					        root_copy = providers.deepcopy(root, memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied = self.__class__(self._name, root_copy)
 | 
				
			||||||
 | 
					        copied._children = providers.deepcopy(self._children, memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __getattr__(self, item):
 | 
				
			||||||
 | 
					        child = self._children.get(item)
 | 
				
			||||||
 | 
					        if child is None:
 | 
				
			||||||
 | 
					            child_name = '.'.join((self._name, item))
 | 
				
			||||||
 | 
					            child = ConfigurationOption(child_name, self._root_ref())
 | 
				
			||||||
 | 
					            self._children[item] = child
 | 
				
			||||||
 | 
					        return child
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _provide(self, args, kwargs):
 | 
				
			||||||
 | 
					        if self._cache is not self.UNDEFINED:
 | 
				
			||||||
 | 
					            return self._cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        root = self._root_ref()
 | 
				
			||||||
 | 
					        value = root.get(self._name)
 | 
				
			||||||
 | 
					        self._cache = value
 | 
				
			||||||
 | 
					        return value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def override(self, value):
 | 
				
			||||||
 | 
					        if isinstance(value, providers.Provider):
 | 
				
			||||||
 | 
					            raise providers.Error('Configuration option can only be overridden by a value')
 | 
				
			||||||
 | 
					        root = self._root_ref()
 | 
				
			||||||
 | 
					        return root.set(self._name, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_last_overriding(self):
 | 
				
			||||||
 | 
					        raise providers.Error('Configuration option does not support this method')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_override(self):
 | 
				
			||||||
 | 
					        raise providers.Error('Configuration option does not support this method')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_cache(self):
 | 
				
			||||||
 | 
					        self._cache = self.UNDEFINED
 | 
				
			||||||
 | 
					        for child in self._children.values():
 | 
				
			||||||
 | 
					            child.reset_cache()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def update(self, value):
 | 
				
			||||||
 | 
					        """Set configuration options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .. deprecated:: 3.11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Use :py:meth:`Configuration.override` instead.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param value: Value of configuration option.
 | 
				
			||||||
 | 
					        :type value: object | dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.override(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_ini(self, filepath):
 | 
				
			||||||
 | 
					        """Load configuration from the ini file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Loaded configuration is merged recursively over existing configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param filepath: Path to the configuration file.
 | 
				
			||||||
 | 
					        :type filepath: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        parser = _parse_ini_file(filepath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        config = {}
 | 
				
			||||||
 | 
					        for section in parser.sections():
 | 
				
			||||||
 | 
					            config[section] = dict(parser.items(section))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        current_config = self.__call__()
 | 
				
			||||||
 | 
					        if not current_config:
 | 
				
			||||||
 | 
					            current_config = {}
 | 
				
			||||||
 | 
					        self.override(merge_dicts(current_config, config))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_yaml(self, filepath):
 | 
				
			||||||
 | 
					        """Load configuration from the yaml file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Loaded configuration is merged recursively over existing configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param filepath: Path to the configuration file.
 | 
				
			||||||
 | 
					        :type filepath: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if yaml is None:
 | 
				
			||||||
 | 
					            raise Error(
 | 
				
			||||||
 | 
					                'Unable to load yaml configuration - PyYAML is not installed. '
 | 
				
			||||||
 | 
					                'Install PyYAML or install Dependency Injector with yaml extras: '
 | 
				
			||||||
 | 
					                '"pip install dependency-injector[yaml]"'
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            with open(filepath) as opened_file:
 | 
				
			||||||
 | 
					                config = yaml.load(opened_file, yaml.Loader)
 | 
				
			||||||
 | 
					        except IOError:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        current_config = self.__call__()
 | 
				
			||||||
 | 
					        if not current_config:
 | 
				
			||||||
 | 
					            current_config = {}
 | 
				
			||||||
 | 
					        self.override(merge_dicts(current_config, config))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_dict(self, options):
 | 
				
			||||||
 | 
					        """Load configuration from the dictionary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Loaded configuration is merged recursively over existing configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param options: Configuration options.
 | 
				
			||||||
 | 
					        :type options: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        current_config = self.__call__()
 | 
				
			||||||
 | 
					        if not current_config:
 | 
				
			||||||
 | 
					            current_config = {}
 | 
				
			||||||
 | 
					        self.override(merge_dicts(current_config, options))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_env(self, name, default=None):
 | 
				
			||||||
 | 
					        """Load configuration value from the environment variable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param name: Name of the environment variable.
 | 
				
			||||||
 | 
					        :type name: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param default: Default value that is used if environment variable does not exist.
 | 
				
			||||||
 | 
					        :type default: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        value = os.getenv(name, default)
 | 
				
			||||||
 | 
					        self.override(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Configuration(providers.Object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DEFAULT_NAME = 'config'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, name=DEFAULT_NAME, default=None):
 | 
				
			||||||
 | 
					        self._name = name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        value = {}
 | 
				
			||||||
 | 
					        if default is not None:
 | 
				
			||||||
 | 
					            assert isinstance(default, dict)
 | 
				
			||||||
 | 
					            value = default.copy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._children = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        super().__init__(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __deepcopy__(self, memo):
 | 
				
			||||||
 | 
					        """Create and return full copy of provider."""
 | 
				
			||||||
 | 
					        copied = memo.get(id(self))
 | 
				
			||||||
 | 
					        if copied is not None:
 | 
				
			||||||
 | 
					            return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        copied = self.__class__(self._name, self.__provides)
 | 
				
			||||||
 | 
					        copied._children = providers.deepcopy(self._children, memo)
 | 
				
			||||||
 | 
					        self._copy_overridings(copied, memo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __getattr__(self, item):
 | 
				
			||||||
 | 
					        child = self._children.get(item)
 | 
				
			||||||
 | 
					        if child is None:
 | 
				
			||||||
 | 
					            child = ConfigurationOption(item, self)
 | 
				
			||||||
 | 
					            self._children[item] = child
 | 
				
			||||||
 | 
					        return child
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_name(self):
 | 
				
			||||||
 | 
					        return self._name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get(self, selector):
 | 
				
			||||||
 | 
					        keys = selector.split('.')
 | 
				
			||||||
 | 
					        value = self.__call__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while len(keys) > 0:
 | 
				
			||||||
 | 
					            key = keys.pop(0)
 | 
				
			||||||
 | 
					            value = value.get(key)
 | 
				
			||||||
 | 
					            if value is None:
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set(self, selector, value):
 | 
				
			||||||
 | 
					        keys = selector.split('.')
 | 
				
			||||||
 | 
					        original_value = current_value = self.__call__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while len(keys) > 0:
 | 
				
			||||||
 | 
					            key = keys.pop(0)
 | 
				
			||||||
 | 
					            if len(keys) == 0:
 | 
				
			||||||
 | 
					                current_value[key] = value
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					            temp_value = current_value.get(key, {})
 | 
				
			||||||
 | 
					            current_value[key] = temp_value
 | 
				
			||||||
 | 
					            current_value = temp_value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return self.override(original_value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def override(self, provider):
 | 
				
			||||||
 | 
					        context = super().override(provider)
 | 
				
			||||||
 | 
					        self.reset_cache()
 | 
				
			||||||
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_last_overriding(self):
 | 
				
			||||||
 | 
					        super().reset_last_overriding()
 | 
				
			||||||
 | 
					        self.reset_cache()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_override(self):
 | 
				
			||||||
 | 
					        super().reset_override()
 | 
				
			||||||
 | 
					        self.reset_cache()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_cache(self):
 | 
				
			||||||
 | 
					        for child in self._children.values():
 | 
				
			||||||
 | 
					            child.reset_cache()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def update(self, value):
 | 
				
			||||||
 | 
					        """Set configuration options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .. deprecated:: 3.11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Use :py:meth:`Configuration.override` instead.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param value: Value of configuration option.
 | 
				
			||||||
 | 
					        :type value: object | dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.override(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_ini(self, filepath):
 | 
				
			||||||
 | 
					        """Load configuration from the ini file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Loaded configuration is merged recursively over existing configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param filepath: Path to the configuration file.
 | 
				
			||||||
 | 
					        :type filepath: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        parser = _parse_ini_file(filepath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        config = {}
 | 
				
			||||||
 | 
					        for section in parser.sections():
 | 
				
			||||||
 | 
					            config[section] = dict(parser.items(section))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        current_config = self.__call__()
 | 
				
			||||||
 | 
					        if not current_config:
 | 
				
			||||||
 | 
					            current_config = {}
 | 
				
			||||||
 | 
					        self.override(merge_dicts(current_config, config))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_yaml(self, filepath):
 | 
				
			||||||
 | 
					        """Load configuration from the yaml file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Loaded configuration is merged recursively over existing configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param filepath: Path to the configuration file.
 | 
				
			||||||
 | 
					        :type filepath: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if yaml is None:
 | 
				
			||||||
 | 
					            raise Error(
 | 
				
			||||||
 | 
					                'Unable to load yaml configuration - PyYAML is not installed. '
 | 
				
			||||||
 | 
					                'Install PyYAML or install Dependency Injector with yaml extras: '
 | 
				
			||||||
 | 
					                '"pip install dependency-injector[yaml]"'
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            with open(filepath) as opened_file:
 | 
				
			||||||
 | 
					                config = yaml.load(opened_file, yaml.Loader)
 | 
				
			||||||
 | 
					        except IOError:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        current_config = self.__call__()
 | 
				
			||||||
 | 
					        if not current_config:
 | 
				
			||||||
 | 
					            current_config = {}
 | 
				
			||||||
 | 
					        self.override(merge_dicts(current_config, config))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_dict(self, options):
 | 
				
			||||||
 | 
					        """Load configuration from the dictionary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Loaded configuration is merged recursively over existing configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param options: Configuration options.
 | 
				
			||||||
 | 
					        :type options: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        current_config = self.__call__()
 | 
				
			||||||
 | 
					        if not current_config:
 | 
				
			||||||
 | 
					            current_config = {}
 | 
				
			||||||
 | 
					        self.override(merge_dicts(current_config, options))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def from_env(self, name, default=None):
 | 
				
			||||||
 | 
					        """Load configuration value from the environment variable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param name: Name of the environment variable.
 | 
				
			||||||
 | 
					        :type name: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param default: Default value that is used if environment variable does not exist.
 | 
				
			||||||
 | 
					        :type default: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        value = os.getenv(name, default)
 | 
				
			||||||
 | 
					        self.override(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    config = Configuration()
 | 
				
			||||||
 | 
					    config.override({'a': {'b': 1}, 'c': 2})
 | 
				
			||||||
 | 
					    print(config())
 | 
				
			||||||
 | 
					    print(config.get('a.b'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    config.set('x.y.z', 123)
 | 
				
			||||||
 | 
					    print(config())
 | 
				
			||||||
 | 
					    assert config.get('x.y.z') == 123
 | 
				
			||||||
 | 
					    assert config.x.y.z() == 123
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    config.set('a.c', 321)
 | 
				
			||||||
 | 
					    print(config())
 | 
				
			||||||
 | 
					    assert config.get('a.c') == 321
 | 
				
			||||||
 | 
					    assert config.a.c() == 321
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    config.set('a.b', 111)
 | 
				
			||||||
 | 
					    print(config())
 | 
				
			||||||
 | 
					    assert config.get('a.b') == 111
 | 
				
			||||||
 | 
					    assert config.a.b() == 111
 | 
				
			||||||
 | 
					    assert config.get('a') == {'b': 111, 'c': 321}
 | 
				
			||||||
 | 
					    assert config.a() == {'b': 111, 'c': 321}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    config = Configuration()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    core_config = Configuration()
 | 
				
			||||||
 | 
					    core_config.override(config.core)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    config.override({'core': {'a': {'b': 1}}})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print(config.core.a.b())
 | 
				
			||||||
 | 
					    print(core_config.a.b())
 | 
				
			||||||
 | 
					    assert config.core.a.b() == 1
 | 
				
			||||||
 | 
					    assert core_config.a.b() == 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -183,7 +183,7 @@ class ConfigTests(unittest.TestCase):
 | 
				
			||||||
    def test_repr_child(self):
 | 
					    def test_repr_child(self):
 | 
				
			||||||
        self.assertEqual(repr(self.config.a.b.c),
 | 
					        self.assertEqual(repr(self.config.a.b.c),
 | 
				
			||||||
                         '<dependency_injector.providers.'
 | 
					                         '<dependency_injector.providers.'
 | 
				
			||||||
                         'Configuration({0}) at {1}>'.format(
 | 
					                         'ConfigurationOption({0}) at {1}>'.format(
 | 
				
			||||||
                             repr('config.a.b.c'),
 | 
					                             repr('config.a.b.c'),
 | 
				
			||||||
                             hex(id(self.config.a.b.c))))
 | 
					                             hex(id(self.config.a.b.c))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -565,6 +565,6 @@ class ConfigFromEnvTests(unittest.TestCase):
 | 
				
			||||||
    def test_with_children(self):
 | 
					    def test_with_children(self):
 | 
				
			||||||
        self.config.section1.value1.from_env('CONFIG_TEST_ENV')
 | 
					        self.config.section1.value1.from_env('CONFIG_TEST_ENV')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertIsNone(self.config())
 | 
					        self.assertEqual(self.config(), {'section1': {'value1': 'test-value'}})
 | 
				
			||||||
        self.assertIsNone(self.config.section1())
 | 
					        self.assertEqual(self.config.section1(), {'value1': 'test-value'})
 | 
				
			||||||
        self.assertEqual(self.config.section1.value1(), 'test-value')
 | 
					        self.assertEqual(self.config.section1.value1(), 'test-value')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user