mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-25 11:04:01 +03:00
Merge branch 'release/3.18.1' into master
This commit is contained in:
commit
783be3ad36
|
@ -7,6 +7,12 @@ that were made in every particular version.
|
||||||
From version 0.7.6 *Dependency Injector* framework strictly
|
From version 0.7.6 *Dependency Injector* framework strictly
|
||||||
follows `Semantic versioning`_
|
follows `Semantic versioning`_
|
||||||
|
|
||||||
|
3.18.1
|
||||||
|
------
|
||||||
|
- Add interpolation of environment variables to ``Configuration.from_yaml()`` and
|
||||||
|
``Configuration.from_ini()``.
|
||||||
|
- Add ignoring of ``IOError`` to ``Configuration.from_yaml()``.
|
||||||
|
|
||||||
3.18.0
|
3.18.0
|
||||||
------
|
------
|
||||||
- Add ``Configuration.from_yaml()`` method to load configuration from the yaml file.
|
- Add ``Configuration.from_yaml()`` method to load configuration from the yaml file.
|
||||||
|
|
|
@ -30,6 +30,10 @@ where ``examples/providers/configuration/config.ini`` is:
|
||||||
:language: ini
|
:language: ini
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
|
:py:meth:`Configuration.from_ini` supports environment variables interpolation. Use
|
||||||
|
``${ENV_NAME}`` format in the configuration file to substitute value of environment
|
||||||
|
variable ``ENV_NAME``.
|
||||||
|
|
||||||
Loading from ``yaml`` file
|
Loading from ``yaml`` file
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -48,6 +52,10 @@ where ``examples/providers/configuration/config.yml`` is:
|
||||||
:language: ini
|
:language: ini
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
|
:py:meth:`Configuration.from_yaml` supports environment variables interpolation. Use
|
||||||
|
``${ENV_NAME}`` format in the configuration file to substitute value of environment
|
||||||
|
variable ``ENV_NAME``.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Loading configuration from yaml requires ``PyYAML`` package. You can install
|
Loading configuration from yaml requires ``PyYAML`` package. You can install
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Dependency injector top-level package."""
|
"""Dependency injector top-level package."""
|
||||||
|
|
||||||
__version__ = '3.18.0'
|
__version__ = '3.18.1'
|
||||||
"""Version number that follows semantic versioning.
|
"""Version number that follows semantic versioning.
|
||||||
|
|
||||||
:type: str
|
:type: str
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,6 +5,7 @@ Powered by Cython.
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
import threading
|
import threading
|
||||||
|
@ -49,6 +50,41 @@ else: # pragma: no cover
|
||||||
copy.deepcopy(obj.im_self, memo),
|
copy.deepcopy(obj.im_self, memo),
|
||||||
obj.im_class)
|
obj.im_class)
|
||||||
|
|
||||||
|
if yaml:
|
||||||
|
yaml_env_marker_pattern = re.compile(r'\$\{([^}^{]+)\}')
|
||||||
|
def yaml_env_marker_constructor(_, node):
|
||||||
|
""""Replace environment variable marker with its value."""
|
||||||
|
return os.path.expandvars(node.value)
|
||||||
|
|
||||||
|
yaml.add_implicit_resolver('!path', yaml_env_marker_pattern)
|
||||||
|
yaml.add_constructor('!path', yaml_env_marker_constructor)
|
||||||
|
|
||||||
|
if sys.version_info[0] == 3:
|
||||||
|
class EnvInterpolation(iniconfigparser.BasicInterpolation):
|
||||||
|
"""Interpolation which expands environment variables in values."""
|
||||||
|
|
||||||
|
def before_get(self, parser, section, option, value, defaults):
|
||||||
|
value = super().before_get(parser, section, option, value, defaults)
|
||||||
|
return os.path.expandvars(value)
|
||||||
|
|
||||||
|
def _parse_ini_file(filepath):
|
||||||
|
parser = iniconfigparser.ConfigParser(interpolation=EnvInterpolation())
|
||||||
|
parser.read(filepath)
|
||||||
|
return parser
|
||||||
|
else:
|
||||||
|
import StringIO
|
||||||
|
|
||||||
|
def _parse_ini_file(filepath):
|
||||||
|
parser = iniconfigparser.ConfigParser()
|
||||||
|
try:
|
||||||
|
with open(filepath) as config_file:
|
||||||
|
config_string = os.path.expandvars(config_file.read())
|
||||||
|
except IOError:
|
||||||
|
return parser
|
||||||
|
else:
|
||||||
|
parser.readfp(StringIO.StringIO(config_string))
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
cdef class Provider(object):
|
cdef class Provider(object):
|
||||||
"""Base provider class.
|
"""Base provider class.
|
||||||
|
@ -1178,8 +1214,7 @@ cdef class Configuration(Object):
|
||||||
|
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
parser = iniconfigparser.ConfigParser()
|
parser = _parse_ini_file(filepath)
|
||||||
parser.read([filepath])
|
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
for section in parser.sections():
|
for section in parser.sections():
|
||||||
|
@ -1207,8 +1242,11 @@ cdef class Configuration(Object):
|
||||||
'"pip install dependency-injector[yaml]"'
|
'"pip install dependency-injector[yaml]"'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
with open(filepath) as opened_file:
|
with open(filepath) as opened_file:
|
||||||
config = yaml.load(opened_file, yaml.Loader)
|
config = yaml.load(opened_file, yaml.Loader)
|
||||||
|
except IOError:
|
||||||
|
return
|
||||||
|
|
||||||
current_config = self.__call__()
|
current_config = self.__call__()
|
||||||
if not current_config:
|
if not current_config:
|
||||||
|
|
|
@ -324,6 +324,41 @@ class ConfigFromIniTests(unittest.TestCase):
|
||||||
self.assertEqual(self.config.section3.value3(), '3')
|
self.assertEqual(self.config.section3.value3(), '3')
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigFromIniWithEnvInterpolationTests(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.config = providers.Configuration(name='config')
|
||||||
|
|
||||||
|
os.environ['CONFIG_TEST_ENV'] = 'test-value'
|
||||||
|
|
||||||
|
_, self.config_file = tempfile.mkstemp()
|
||||||
|
with open(self.config_file, 'w') as config_file:
|
||||||
|
config_file.write(
|
||||||
|
'[section1]\n'
|
||||||
|
'value1=${CONFIG_TEST_ENV}\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
del self.config
|
||||||
|
del os.environ['CONFIG_TEST_ENV']
|
||||||
|
os.unlink(self.config_file)
|
||||||
|
|
||||||
|
def test_env_variable_interpolation(self):
|
||||||
|
self.config.from_ini(self.config_file)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.config(),
|
||||||
|
{
|
||||||
|
'section1': {
|
||||||
|
'value1': 'test-value',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertEqual(self.config.section1(), {'value1': 'test-value'})
|
||||||
|
self.assertEqual(self.config.section1.value1(), 'test-value')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigFromYamlTests(unittest.TestCase):
|
class ConfigFromYamlTests(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -414,6 +449,41 @@ class ConfigFromYamlTests(unittest.TestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigFromYamlWithEnvInterpolationTests(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.config = providers.Configuration(name='config')
|
||||||
|
|
||||||
|
os.environ['CONFIG_TEST_ENV'] = 'test-value'
|
||||||
|
|
||||||
|
_, self.config_file = tempfile.mkstemp()
|
||||||
|
with open(self.config_file, 'w') as config_file:
|
||||||
|
config_file.write(
|
||||||
|
'section1:\n'
|
||||||
|
' value1: ${CONFIG_TEST_ENV}\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
del self.config
|
||||||
|
del os.environ['CONFIG_TEST_ENV']
|
||||||
|
os.unlink(self.config_file)
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.version_info[:2] == (3, 4), 'PyYAML does not support Python 3.4')
|
||||||
|
def test_env_variable_interpolation(self):
|
||||||
|
self.config.from_yaml(self.config_file)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.config(),
|
||||||
|
{
|
||||||
|
'section1': {
|
||||||
|
'value1': 'test-value',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertEqual(self.config.section1(), {'value1': 'test-value'})
|
||||||
|
self.assertEqual(self.config.section1.value1(), 'test-value')
|
||||||
|
|
||||||
|
|
||||||
class ConfigFromDict(unittest.TestCase):
|
class ConfigFromDict(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user