Fix item_name -> attribute_name KeyError in select_config().
[h5config.git] / h5config / config.py
index 65687603917fdb31cd19394d6fa855d746b2a1a5..bbe9469ee1dc1d1dc34f49b07bd59464ec28db33 100644 (file)
@@ -240,17 +240,25 @@ class ConfigListSetting (ConfigSetting):
 
 
 class Config (dict):
-    "A class with a list `._keys` of `Setting`\s."
+    """A class with a list of `Setting`\s.
+
+    `Config` instances store their values just like dictionaries, but
+    the attached list of `Settings`\s allows them to intelligently
+    dump, save, and load those values.
+    """
     settings = []
 
     def __init__(self, storage=None):
         super(Config, self).__init__()
         self.clear()
-        self._storage = storage
+        self.set_storage(storage=storage)
 
     def __repr__(self):
         return '<{} {}>'.format(self.__class__.__name__, id(self))
 
+    def set_storage(self, storage):
+        self._storage = storage
+
     def clear(self):
         super(Config, self).clear()
         for s in self.settings:
@@ -324,3 +332,35 @@ class Config (dict):
                 _LOG.error('could not dump {} ({!r})'.format(name, value))
                 raise
         return '\n'.join(lines)
+
+    def select_config(self, setting_name, attribute_value=None,
+                      attribute_name='name'):
+        """Select a `Config` instance from `ConfigListSetting` values
+
+        If your don't want to select `ConfigListSetting` items by
+        index, you can select them by matching another attribute.  For
+        example:
+
+        >>> from .test import TestConfig
+        >>> c = TestConfig()
+        >>> c['children'] = []
+        >>> for name in ['Jack', 'Jill']:
+        ...     child = TestConfig()
+        ...     child['name'] = name
+        ...     c['children'].append(child)
+        >>> child = c.select_config('children', 'Jack')
+        >>> child  # doctest: +ELLIPSIS
+        <TestConfig ...>
+        >>> child['name']
+        'Jack'
+
+        `attribute_value` defaults to `name`, because I expect that to
+        be the most common case.
+        """
+        setting_value = self[setting_name]
+        if not setting_value:
+            raise KeyError(setting_value)
+        for item in setting_value:
+            if item[attribute_name] == attribute_value:
+                return item
+        raise KeyError(attribute_value)