prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Better YAML overriding
  Now it does not take just the root element into the account, but it crawls throught the dictionary and only updates the values that are present in the new dictionary. It converts all dicts to Configs, other values than specified in override dict are not touched.
  
  It also improves the `__getattribute__` behaviour - now it propagates the interface to the child nodes by converting all `dict` to `Config` before returning the value, so the dot operator can be used everywhere.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `utils/conf_loader.py`
  Content:
  ```
  1 import os
  2 from collections import OrderedDict
  3 
  4 import py.path
  5 import yaml
  6 from yaml.loader import Loader
  7 
  8 
  9 class OrderedYamlLoader(Loader):
  10     def construct_yaml_map(self, node):
  11         data = OrderedDict()
  12         yield data
  13         value = self.construct_mapping(node)
  14         data.update(value)
  15 
  16 
  17 class ConfigNotFoundException(Exception):
  18     pass
  19 
  20 
  21 class Config(dict):
  22     """A dict subclass with knowledge of conf yamls and how to load them
  23 
  24     Also supports descriptor access, e.g. conf.configfile
  25     (compared to the normal dict access, conf['configfile'])
  26     """
  27     # Stash the exception on the class for convenience, e.g.
  28     # try:
  29     #     conf[does_not_exist]
  30     # except conf.NotFoundException
  31     #     ...
  32     NotFoundException = ConfigNotFoundException
  33 
  34     # Support for descriptor access, e.g. instance.attrname
  35     # Note that this is only on the get side, for support of nefarious things
  36     # like setting and deleting, use the normal dict interface.
  37     def __getattribute__(self, attr):
  38         # Attempt normal object attr lookup; delegate to the dict interface if that fails
  39         try:
  40             return super(Config, self).__getattribute__(attr)
  41         except AttributeError:
  42             return self[attr]
  43 
  44     def __getitem__(self, key):
  45         # Attempt a normal dict lookup to pull a cached conf
  46         try:
  47             return super(Config, self).__getitem__(key)
  48         except KeyError:
  49              # Cache miss, load the requested yaml
  50             yaml_dict = load_yaml(key)
  51 
  52             # Graft in local yaml updates if they're available
  53             try:
  54                 local_yaml = '%s.local' % key
  55                 local_yaml_dict = load_yaml(local_yaml)
  56                 yaml_dict.update(local_yaml_dict)
  57             except ConfigNotFoundException:
  58                 pass
  59 
  60             # Returning self[key] instead of yaml_dict as a small sanity check
  61             self[key] = yaml_dict
  62             return self[key]
  63 
  64 
  65 def load_yaml(filename=None):
  66     # Find the requested yaml in the config dir, relative to this file's location
  67     # (aiming for cfme_tests/config)
  68     this_file = os.path.abspath(__file__)
  69     path = py.path.local(this_file).new(basename='../conf/%s.yaml' % filename)
  70 
  71     if path.check():
  72         with path.open() as config_fh:
  73             return yaml.load(config_fh, Loader=OrderedYamlLoader)
  74     else:
  75         msg = 'Unable to load configuration file at %s' % path
  76         raise ConfigNotFoundException(msg)
  77
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/utils/conf_loader.py b/utils/conf_loader.py
  --- a/utils/conf_loader.py
  +++ b/utils/conf_loader.py
  @@ -1,17 +1,19 @@
   import os
  -from collections import OrderedDict
   
   import py.path
   import yaml
   from yaml.loader import Loader
   
   
  -class OrderedYamlLoader(Loader):
  +class YamlConfigLoader(Loader):
  +    # Override the root yaml node to be a RecursiveUpdateDict
       def construct_yaml_map(self, node):
  -        data = OrderedDict()
  +        data = RecursiveUpdateDict()
           yield data
           value = self.construct_mapping(node)
           data.update(value)
  +# Do the same for child nodes of the yaml mapping type
  +YamlConfigLoader.add_constructor('tag:yaml.org,2002:map', YamlConfigLoader.construct_yaml_map)
   
   
   class ConfigNotFoundException(Exception):
  @@ -62,6 +64,43 @@
               return self[key]
   
   
  +class RecursiveUpdateDict(dict):
  +    def update(self, new_data):
  +        """ More intelligent dictionary update.
  +
  +        This method changes just data that have been changed. How does it work?
  +        Imagine you want to change just VM name, other things should stay the same.
  +
  +        Original config:
  +        something:
  +            somewhere:
  +                VM:
  +                    a: 1
  +                    b: 2
  +                    name: qwer
  +                    c: 3
  +
  +        Instead of copying the whole part from original to the override with just 'name' changed,
  +        you will write this:
  +
  +        something:
  +            somewhere:
  +                VM:
  +                    name: tzui
  +
  +        This digging deeper affects only dictionary values. Lists are unaffected! And so do other
  +        types.
  +
  +        Args:
  +            new_data: Update data.
  +        """
  +        for key, value in new_data.iteritems():
  +            if isinstance(value, type(self)) and key in self:
  +                type(self).update(self[key], value)
  +            else:
  +                self[key] = new_data[key]
  +
  +
   def load_yaml(filename=None):
       # Find the requested yaml in the config dir, relative to this file's location
       # (aiming for cfme_tests/config)
  @@ -70,7 +109,7 @@
   
       if path.check():
           with path.open() as config_fh:
  -            return yaml.load(config_fh, Loader=OrderedYamlLoader)
  +            return yaml.load(config_fh, Loader=YamlConfigLoader)
       else:
           msg = 'Unable to load configuration file at %s' % path
           raise ConfigNotFoundException(msg)
  
verification_info: {"golden_diff": "diff --git a/utils/conf_loader.py b/utils/conf_loader.py\n--- a/utils/conf_loader.py\n+++ b/utils/conf_loader.py\n@@ -1,17 +1,19 @@\n import os\n-from collections import OrderedDict\n \n import py.path\n import yaml\n from yaml.loader import Loader\n \n \n-class OrderedYamlLoader(Loader):\n+class YamlConfigLoader(Loader):\n+    # Override the root yaml node to be a RecursiveUpdateDict\n     def construct_yaml_map(self, node):\n-        data = OrderedDict()\n+        data = RecursiveUpdateDict()\n         yield data\n         value = self.construct_mapping(node)\n         data.update(value)\n+# Do the same for child nodes of the yaml mapping type\n+YamlConfigLoader.add_constructor('tag:yaml.org,2002:map', YamlConfigLoader.construct_yaml_map)\n \n \n class ConfigNotFoundException(Exception):\n@@ -62,6 +64,43 @@\n             return self[key]\n \n \n+class RecursiveUpdateDict(dict):\n+    def update(self, new_data):\n+        \"\"\" More intelligent dictionary update.\n+\n+        This method changes just data that have been changed. How does it work?\n+        Imagine you want to change just VM name, other things should stay the same.\n+\n+        Original config:\n+        something:\n+            somewhere:\n+                VM:\n+                    a: 1\n+                    b: 2\n+                    name: qwer\n+                    c: 3\n+\n+        Instead of copying the whole part from original to the override with just 'name' changed,\n+        you will write this:\n+\n+        something:\n+            somewhere:\n+                VM:\n+                    name: tzui\n+\n+        This digging deeper affects only dictionary values. Lists are unaffected! And so do other\n+        types.\n+\n+        Args:\n+            new_data: Update data.\n+        \"\"\"\n+        for key, value in new_data.iteritems():\n+            if isinstance(value, type(self)) and key in self:\n+                type(self).update(self[key], value)\n+            else:\n+                self[key] = new_data[key]\n+\n+\n def load_yaml(filename=None):\n     # Find the requested yaml in the config dir, relative to this file's location\n     # (aiming for cfme_tests/config)\n@@ -70,7 +109,7 @@\n \n     if path.check():\n         with path.open() as config_fh:\n-            return yaml.load(config_fh, Loader=OrderedYamlLoader)\n+            return yaml.load(config_fh, Loader=YamlConfigLoader)\n     else:\n         msg = 'Unable to load configuration file at %s' % path\n         raise ConfigNotFoundException(msg)\n", "issue": "Better YAML overriding\nNow it does not take just the root element into the account, but it crawls throught the dictionary and only updates the values that are present in the new dictionary. It converts all dicts to Configs, other values than specified in override dict are not touched.\n\nIt also improves the `__getattribute__` behaviour - now it propagates the interface to the child nodes by converting all `dict` to `Config` before returning the value, so the dot operator can be used everywhere.\n\n", "before_files": [{"content": "import os\nfrom collections import OrderedDict\n\nimport py.path\nimport yaml\nfrom yaml.loader import Loader\n\n\nclass OrderedYamlLoader(Loader):\n    def construct_yaml_map(self, node):\n        data = OrderedDict()\n        yield data\n        value = self.construct_mapping(node)\n        data.update(value)\n\n\nclass ConfigNotFoundException(Exception):\n    pass\n\n\nclass Config(dict):\n    \"\"\"A dict subclass with knowledge of conf yamls and how to load them\n\n    Also supports descriptor access, e.g. conf.configfile\n    (compared to the normal dict access, conf['configfile'])\n    \"\"\"\n    # Stash the exception on the class for convenience, e.g.\n    # try:\n    #     conf[does_not_exist]\n    # except conf.NotFoundException\n    #     ...\n    NotFoundException = ConfigNotFoundException\n\n    # Support for descriptor access, e.g. instance.attrname\n    # Note that this is only on the get side, for support of nefarious things\n    # like setting and deleting, use the normal dict interface.\n    def __getattribute__(self, attr):\n        # Attempt normal object attr lookup; delegate to the dict interface if that fails\n        try:\n            return super(Config, self).__getattribute__(attr)\n        except AttributeError:\n            return self[attr]\n\n    def __getitem__(self, key):\n        # Attempt a normal dict lookup to pull a cached conf\n        try:\n            return super(Config, self).__getitem__(key)\n        except KeyError:\n             # Cache miss, load the requested yaml\n            yaml_dict = load_yaml(key)\n\n            # Graft in local yaml updates if they're available\n            try:\n                local_yaml = '%s.local' % key\n                local_yaml_dict = load_yaml(local_yaml)\n                yaml_dict.update(local_yaml_dict)\n            except ConfigNotFoundException:\n                pass\n\n            # Returning self[key] instead of yaml_dict as a small sanity check\n            self[key] = yaml_dict\n            return self[key]\n\n\ndef load_yaml(filename=None):\n    # Find the requested yaml in the config dir, relative to this file's location\n    # (aiming for cfme_tests/config)\n    this_file = os.path.abspath(__file__)\n    path = py.path.local(this_file).new(basename='../conf/%s.yaml' % filename)\n\n    if path.check():\n        with path.open() as config_fh:\n            return yaml.load(config_fh, Loader=OrderedYamlLoader)\n    else:\n        msg = 'Unable to load configuration file at %s' % path\n        raise ConfigNotFoundException(msg)\n", "path": "utils/conf_loader.py"}], "after_files": [{"content": "import os\n\nimport py.path\nimport yaml\nfrom yaml.loader import Loader\n\n\nclass YamlConfigLoader(Loader):\n    # Override the root yaml node to be a RecursiveUpdateDict\n    def construct_yaml_map(self, node):\n        data = RecursiveUpdateDict()\n        yield data\n        value = self.construct_mapping(node)\n        data.update(value)\n# Do the same for child nodes of the yaml mapping type\nYamlConfigLoader.add_constructor('tag:yaml.org,2002:map', YamlConfigLoader.construct_yaml_map)\n\n\nclass ConfigNotFoundException(Exception):\n    pass\n\n\nclass Config(dict):\n    \"\"\"A dict subclass with knowledge of conf yamls and how to load them\n\n    Also supports descriptor access, e.g. conf.configfile\n    (compared to the normal dict access, conf['configfile'])\n    \"\"\"\n    # Stash the exception on the class for convenience, e.g.\n    # try:\n    #     conf[does_not_exist]\n    # except conf.NotFoundException\n    #     ...\n    NotFoundException = ConfigNotFoundException\n\n    # Support for descriptor access, e.g. instance.attrname\n    # Note that this is only on the get side, for support of nefarious things\n    # like setting and deleting, use the normal dict interface.\n    def __getattribute__(self, attr):\n        # Attempt normal object attr lookup; delegate to the dict interface if that fails\n        try:\n            return super(Config, self).__getattribute__(attr)\n        except AttributeError:\n            return self[attr]\n\n    def __getitem__(self, key):\n        # Attempt a normal dict lookup to pull a cached conf\n        try:\n            return super(Config, self).__getitem__(key)\n        except KeyError:\n             # Cache miss, load the requested yaml\n            yaml_dict = load_yaml(key)\n\n            # Graft in local yaml updates if they're available\n            try:\n                local_yaml = '%s.local' % key\n                local_yaml_dict = load_yaml(local_yaml)\n                yaml_dict.update(local_yaml_dict)\n            except ConfigNotFoundException:\n                pass\n\n            # Returning self[key] instead of yaml_dict as a small sanity check\n            self[key] = yaml_dict\n            return self[key]\n\n\nclass RecursiveUpdateDict(dict):\n    def update(self, new_data):\n        \"\"\" More intelligent dictionary update.\n\n        This method changes just data that have been changed. How does it work?\n        Imagine you want to change just VM name, other things should stay the same.\n\n        Original config:\n        something:\n            somewhere:\n                VM:\n                    a: 1\n                    b: 2\n                    name: qwer\n                    c: 3\n\n        Instead of copying the whole part from original to the override with just 'name' changed,\n        you will write this:\n\n        something:\n            somewhere:\n                VM:\n                    name: tzui\n\n        This digging deeper affects only dictionary values. Lists are unaffected! And so do other\n        types.\n\n        Args:\n            new_data: Update data.\n        \"\"\"\n        for key, value in new_data.iteritems():\n            if isinstance(value, type(self)) and key in self:\n                type(self).update(self[key], value)\n            else:\n                self[key] = new_data[key]\n\n\ndef load_yaml(filename=None):\n    # Find the requested yaml in the config dir, relative to this file's location\n    # (aiming for cfme_tests/config)\n    this_file = os.path.abspath(__file__)\n    path = py.path.local(this_file).new(basename='../conf/%s.yaml' % filename)\n\n    if path.check():\n        with path.open() as config_fh:\n            return yaml.load(config_fh, Loader=YamlConfigLoader)\n    else:\n        msg = 'Unable to load configuration file at %s' % path\n        raise ConfigNotFoundException(msg)\n", "path": "utils/conf_loader.py"}]}