Repository: omry/omegaconf

Issue:
open_dict change value to the inherited value
for a nested config:
```yaml
foo:
  bar:
    baz: 10
```
if foo is struct, and we do
```python
with open_dict(cfg.foo.bar):
   bar.baz = 20
```

the struct flag of foo.bar would be changed to True.

Discussion:
coveralls: ## Pull Request Test Coverage Report for [Build 256](https://coveralls.io/builds/26766909)

* **4** of **4**   **(100.0%)**  changed or added relevant lines in **2** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage decreased (**-0.08%**) to **99.19%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/26766909/badge)](https://coveralls.io/builds/26766909) |
| :-- | --: |
| Change from base [Build 254](https://coveralls.io/builds/26734871): |  -0.08% |
| Covered Lines: | 2449 |
| Relevant Lines: | 2469 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/omegaconf/config.py b/omegaconf/config.py
index 0a8995d..a1b3f14 100644
--- a/omegaconf/config.py
+++ b/omegaconf/config.py
@@ -83,6 +83,13 @@ class Config(object):
         assert value is None or isinstance(value, bool)
         self.__dict__['flags'][flag] = value
 
+    def _get_node_flag(self, flag):
+        """
+        :param flag: flag to inspect
+        :return: the state of the flag on this node.
+        """
+        return self.__dict__['flags'][flag]
+
     def _get_flag(self, flag):
         """
         Returns True if this config node flag is set
diff --git a/omegaconf/omegaconf.py b/omegaconf/omegaconf.py
index 03e908b..df3a92b 100644
--- a/omegaconf/omegaconf.py
+++ b/omegaconf/omegaconf.py
@@ -228,7 +228,8 @@ def flag_override(config, name, value):
 # noinspection PyProtectedMember
 @contextmanager
 def read_write(config):
-    prev_state = OmegaConf.is_readonly(config)
+    # noinspection PyProtectedMember
+    prev_state = config._get_node_flag("readonly")
     try:
         OmegaConf.set_readonly(config, False)
         yield config
@@ -238,7 +239,8 @@ def read_write(config):
 
 @contextmanager
 def open_dict(config):
-    prev_state = OmegaConf.is_struct(config)
+    # noinspection PyProtectedMember
+    prev_state = config._get_node_flag("struct")
     try:
         OmegaConf.set_struct(config, False)
         yield config


Test patch:
diff --git a/tests/test_base_config.py b/tests/test_base_config.py
index 713ff52..b7112ed 100644
--- a/tests/test_base_config.py
+++ b/tests/test_base_config.py
@@ -275,3 +275,19 @@ def test_struct_override(src, func, expectation):
     with does_not_raise():
         with open_dict(c):
             func(c)
+
+
+@pytest.mark.parametrize("flag_name,ctx", [("struct", open_dict), ("readonly", read_write)])
+def test_open_dict_restore(flag_name, ctx):
+    """
+    Tests that internal flags are restored properly when applying context on a child node
+    """
+    cfg = OmegaConf.create({"foo": {"bar": 10}})
+    cfg._set_flag(flag_name, True)
+    assert cfg._get_node_flag(flag_name)
+    assert not cfg.foo._get_node_flag(flag_name)
+    with ctx(cfg.foo):
+        cfg.foo.bar = 20
+    assert cfg._get_node_flag(flag_name)
+    assert not cfg.foo._get_node_flag(flag_name)
+