예제 #1
0
    def test_nested_set(self):
        dict = {
            'a': {
                'b': {
                    'c': 1,
                    'd': 2,
                },
            },
            'e': {
                'f': 3,
                'g': 4,
            },
        }

        new_val = 3
        expected = deepcopy(dict)
        expected['a']['b'] = new_val
        self.assertEqual(DictUtil.nested_set(deepcopy(dict), 'a.b', new_val), expected)

        new_val = 10
        expected = deepcopy(dict)
        expected['a']['b']['c'] = new_val
        self.assertEqual(DictUtil.nested_set(deepcopy(dict), 'a.b.c', new_val), expected)

        new_val = {'x': {'y': 'z'}}
        expected = deepcopy(dict)
        expected['e'] = new_val
        self.assertEqual(DictUtil.nested_set(deepcopy(dict), 'e', new_val), expected)

        new_val = [-1, 0, 1]
        expected = deepcopy(dict)
        expected['e']['g'] = new_val
        self.assertEqual(DictUtil.nested_set(deepcopy(dict), 'e.g', new_val), expected)
예제 #2
0
    def test_set_value(self):
        key = 'key'
        key_a_dict_value = 8
        key_b_dict_value = 3
        key_c_dict_value = 'hi'
        test_dict = {
        'a_dict':
            {'nested': {'key': key_a_dict_value,
                       'not_key': 9}},
        'b_dict':
            {'nested': {'key': key_b_dict_value,
                    'not_key': 15}},
        'c_dict':
            {'key': {'key': key_c_dict_value,
                    'not_key': 15}}
                    }
        self.assertEqual(test_dict['a_dict']['nested'][key], key_a_dict_value)
        self.assertEqual(test_dict['b_dict']['nested'][key], key_b_dict_value)
        self.assertEqual(test_dict['c_dict']['key'][key], key_c_dict_value)

        new_value = 11
        DictUtil.set_value(test_dict, key, new_value)
        self.assertEqual(test_dict['a_dict']['nested'][key], new_value)
        self.assertEqual(test_dict['b_dict']['nested'][key], new_value)
        self.assertEqual(test_dict['c_dict']['key'][key], key_c_dict_value)

        DictUtil.set_value(test_dict, key, new_value, match_type=False)
        self.assertEqual(test_dict['a_dict']['nested'][key], new_value)
        self.assertEqual(test_dict['b_dict']['nested'][key], new_value)
        self.assertEqual(test_dict['c_dict']['key'][key], new_value)
예제 #3
0
    def test_dict_filtering(self):
        d = {'a': 1, 'b': 2, 'c': 3}
        self.assertEqual(DictUtil.filtered_dict(d, []), {})
        self.assertEqual(DictUtil.filtered_dict(d, ['a']), {'a': 1})
        self.assertEqual(DictUtil.filtered_dict(d, ['a', 'd', 'a', 'b', 'c']), d)

        self.assertEqual({(k, v) for k, v in DictUtil.filtered_iteritems(d, ['a', 'b', 'd'])},
                         {('a', 1), ('b', 2)})
예제 #4
0
    def convert_metadata(self, metadata_class):
        """ Convert the saved simulation metadata into HDF5 attributes on a `metadata` Group

        Args:
            metadata_class (:obj:`EnhancedDataClass`): the class that stored the metadata
        """
        metadata = metadata_class.read_dataclass(self.results_dir)

        # open the metadata file
        metadata_file = self._hdf_file()
        with h5py.File(metadata_file, 'a') as hdf5_file:
            # open or make a group in metadata_file called 'metadata'
            if self.METADATA_GROUP in hdf5_file:
                metadata_group = hdf5_file[self.METADATA_GROUP]
            else:
                metadata_group = hdf5_file.create_group(self.METADATA_GROUP)

            # make a nested dict of the metadata
            metadata_as_dict = dataclasses.asdict(metadata)
            metadata_class_name = self.METADATA_CLASS_TO_NAME[metadata_class]
            flat_metadata_as_dict = DictUtil.flatten_dict(metadata_as_dict)

            for key, value in flat_metadata_as_dict.items():
                # make a dotted string for each value in the metadata
                # metadata_as_dict keys cannot contain '.' because they're attribute names
                separator = '.'
                name = f'{metadata_class_name}{separator}{separator.join(key)}'

                # make an attribute for each value
                if value is None:
                    value = 'NA'
                if not isinstance(value, (int, float, str)):
                    value = str(value)
                metadata_group.attrs[name] = value
예제 #5
0
    def test_nested_in(self):
        dict = {
            'a': {
                'b': {
                    'c': 1,
                    'd': 2,
                },
            },
            'e': {
                'f': 3,
                'g': 4,
            },
        }

        self.assertEqual(DictUtil.nested_in(dict, 'a.b'), 'a' in dict and 'b' in dict['a'])
        self.assertEqual(DictUtil.nested_in(dict, 'a.b.c'), 'a' in dict and 'b' in dict['a'] and 'c' in dict['a']['b'])
        self.assertEqual(DictUtil.nested_in(dict, 'a.b.e'), 'a' in dict and 'b' in dict['a'] and 'e' in dict['a']['b'])
예제 #6
0
    def test_nested_get(self):
        dict = {
            'a': {
                'b': {
                    'c': 1,
                    'd': 2,
                },
            },
            'e': {
                'f': 3,
                'g': 4,
            },
        }

        self.assertEqual(DictUtil.nested_get(dict, 'a.b'), dict['a']['b'])
        self.assertEqual(DictUtil.nested_get(dict, 'a.b.c'), dict['a']['b']['c'])
        self.assertEqual(DictUtil.nested_get(dict, 'e'), dict['e'])
        self.assertEqual(DictUtil.nested_get(dict, 'e.g'), dict['e']['g'])
예제 #7
0
    def get_metadata(self):
        """ Get simulation metadata from the HDF5 file

        Returns:
            :obj:`dict`: a nested dictionary of metadata corresponding to the attributes in
                :obj:`SimulationMetadata` and :obj:`WCSimulationMetadata`
        """
        hdf5_file = h5py.File(self._hdf_file(), 'r')
        metadata_attrs = hdf5_file[self.METADATA_GROUP].attrs
        metadata_attrs_as_dict = {}
        for key, value in metadata_attrs.items():
            metadata_attrs_as_dict[key] = value
        return DictUtil.expand_dict(metadata_attrs_as_dict)
예제 #8
0
파일: core.py 프로젝트: highdxy/wc_utils
    def get_config(self, extra=None, context=None):
        """ Setup configuration from config file(s), environment variables, and/or function arguments.

        1. Setup configuration from default values specified in `paths.default`.
        2. If `paths.user` is set, find the first file in it that exists, and override
           the default configuration with the values specified in the file.
        3. Override configuration with values from environment variables. Environment variables
           can be set with the following syntax::

               CONFIG.level1.level2...=val

        4. Override configuration with additional configuration in `extra`.
        5. Substitute context into templates
        6. Validate configuration against the schema specified in `paths.schema`.

        Args:
            extra (:obj:`dict`, optional): additional configuration to override
            context (:obj:`dict`, optional): context for template substitution

        Returns:
            :obj:`configobj.ConfigObj`: nested dictionary with the configuration settings loaded from the configuration source(s).

        Raises:
            :obj:`InvalidConfigError`: if configuration doesn't validate against schema
            :obj:`ValueError`: if no configuration is found
        """

        # read configuration schema/specification
        config_specification = ConfigObj(self.paths.schema,
                                         list_values=False,
                                         _inspec=True)

        # read default configuration
        value_sources = []
        if os.path.isfile(self.paths.default):
            value_sources.append(self.paths.default)
        config = ConfigObj(infile=self.paths.default,
                           configspec=config_specification)
        self.validate(config, value_sources)

        # read user's configuration files
        for user_config_filename in self.paths.user:
            if os.path.isfile(user_config_filename):
                override_config = ConfigObj(infile=user_config_filename,
                                            configspec=config_specification)
                config.merge(override_config)
                self.validate(config, [user_config_filename])
                break

        # read configuration from environment variables
        value_sources = []
        for key, val in os.environ.items():
            if key.startswith('CONFIG__DOT__'):
                nested_keys = key[13:].split('__DOT__')
                if nested_keys[0] in config:
                    DictUtil.nested_set(config, nested_keys, val)
                    value_sources.append(
                        "Environment variable '{}'".format(key))
        self.validate(config, value_sources)

        # merge extra configuration
        if extra is None:
            extra = {}
        else:
            config.merge(extra)
            self.validate(config, ["'extra' argument"])

        # ensure that a configuration is found
        if not config:
            raise ValueError(
                ("No configuration found in:\n"
                 "  Default path: {}\n"
                 "  User paths: {}\n"
                 "  Extras: {}\n"
                 "  Environment variables").format(self.paths.default,
                                                   ', '.join(self.paths.user),
                                                   extra))

        # perform template substitution
        to_sub = [config]
        while to_sub:
            dictionary = to_sub.pop()
            keys = list(dictionary.keys())
            for key in keys:
                val = dictionary[key]
                key2 = string.Template(key).substitute(context)

                val2 = val
                if isinstance(val, dict):
                    to_sub.append(val)
                elif isinstance(val, (list, tuple)):
                    val2 = [
                        string.Template(v).substitute(context) for v in val
                    ]
                elif isinstance(val, six.string_types):
                    val2 = string.Template(val).substitute(context)

                dictionary.pop(key)
                dictionary[key2] = val2

        # re-validate configuration against schema after substitution
        self.validate(config, value_sources)

        # return config
        return config
예제 #9
0
 def test_to_string_sorted_by_key(self):
     self.assertEqual(DictUtil.to_string_sorted_by_key(None), '{}')
     self.assertEqual(DictUtil.to_string_sorted_by_key({'b': 2, 'c': 3, 'a': 1, 'd': 4}), "{'a': 1, 'b': 2, 'c': 3, 'd': 4}")