提交 101ec096 authored 作者: Michael Osthege's avatar Michael Osthege 提交者: Brandon T. Willard

Add backwards-compatibility for dot-based sectioning.

上级 936554c1
...@@ -28,6 +28,33 @@ def test_api_deprecation_warning(): ...@@ -28,6 +28,33 @@ def test_api_deprecation_warning():
pass pass
def test_api_redirect():
root = configdefaults.config
# one section level
root.add(
"test__section_redirect",
"A config var from a test case.",
configparser.StrParam("test_default"),
)
assert hasattr(root, "test__section_redirect")
assert root.test__section_redirect == "test_default"
assert hasattr(root, "test")
assert isinstance(root.test, configparser._SectionRedirect)
with pytest.warns(DeprecationWarning):
assert root.test.section_redirect == "test_default"
# two section levels
root.add(
"test__subsection__redirect",
"A config var from a test case.",
configparser.StrParam("test_default2"),
)
assert hasattr(root, "test__subsection__redirect")
assert root.test__subsection__redirect == "test_default2"
with pytest.warns(DeprecationWarning):
assert root.test.subsection.redirect == "test_default2"
def test_invalid_default(): def test_invalid_default():
# Ensure an invalid default value found in the Theano code only causes # Ensure an invalid default value found in the Theano code only causes
# a crash if it is not overridden by the user. # a crash if it is not overridden by the user.
......
...@@ -74,6 +74,27 @@ def _hash_from_code(msg): ...@@ -74,6 +74,27 @@ def _hash_from_code(msg):
return "m" + hashlib.sha256(msg).hexdigest() return "m" + hashlib.sha256(msg).hexdigest()
class _SectionRedirect:
"""Functions as a mock property on the TheanoConfigParser.
It redirects attribute access (to config subsectinos) to the
new config variable properties that use "__" in their name.
"""
def __init__(self, root, section_name):
self._root = root
self._section_name = section_name
super().__init__()
def __getattr__(self, attr):
warnings.warn(
f"Accessing section '{attr}' through old .-based API. "
f"This will be removed. Use 'config.{self._section_name}__{attr}' instead.",
DeprecationWarning,
)
return getattr(self._root, f"{self._section_name}__{attr}")
class TheanoConfigParser: class TheanoConfigParser:
""" Object that holds configuration settings. """ """ Object that holds configuration settings. """
...@@ -175,6 +196,18 @@ class TheanoConfigParser: ...@@ -175,6 +196,18 @@ class TheanoConfigParser:
# keep the ConfigParam object in a dictionary: # keep the ConfigParam object in a dictionary:
self._config_var_dict[name] = configparam self._config_var_dict[name] = configparam
# The old API used dots for accessing a hierarchy of sections.
# The following code adds redirects that spill DeprecationWarnings
# while allowing backwards-compatible access to dot-based subsections.
# Because the subsectioning is recursive, redirects must be added for
# all levels. For example: ".test", ".test.subsection".
sections = name.split("__")
for s in range(1, len(sections)):
section_name = "__".join(sections[:s])
if not hasattr(self, section_name):
redirect = _SectionRedirect(self, section_name)
setattr(self.__class__, section_name, redirect)
def fetch_val_for_key(self, key, delete_key=False): def fetch_val_for_key(self, key, delete_key=False):
"""Return the overriding config value for a key. """Return the overriding config value for a key.
A successful search returns a string value. A successful search returns a string value.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论