示例#1
0
    def pfset(self, key='', value=None, yaml_file=None, yaml_content=None,
              pfidb_file=None, hierarchical_map=None, flat_map=None,
              exit_if_undefined=False):
        """
        Allow to define any parflow key so it can be exported.
        Many formats are supported:
            - key/value: To set a single value relative to our current
                PFDBObj.
            - yaml_file: YAML file path to load and import using the
                current PFDBObj as root.
            - yaml_content: YAML string to load and import using the
                current PFDBObj as root.
            - hierarchical_map: Nested dict containing several key/value
                pair using the current PFDBObj as root.
            - flat_map: Flat dict with parflow key/value pair to set
                using the current PFDBObj as root.
        """
        if yaml_file:
            yaml_content = get_text_file_content(yaml_file)

        if yaml_content:
            hierarchical_map = yaml.safe_load(yaml_content)

        if pfidb_file:
            flat_map = read_pfidb(pfidb_file)

        if hierarchical_map:
            flat_map = flatten_hierarchical_map(hierarchical_map)

        if flat_map:
            sorted_flat_map = sort_dict_by_priority(flat_map)
            for key, value in sorted_flat_map.items():
                self.pfset(key=key, value=value,
                           exit_if_undefined=exit_if_undefined)

        if not key:
            return

        key_stored = False
        tokens = key.split('.')
        if len(tokens) > 1:
            container, = self.select('/'.join(tokens[:-1]))
            if container is not None:
                container[tokens[-1]] = value
                key_stored = True
        elif len(tokens) == 1:
            self[tokens[0]] = value
            key_stored = True

        if not key_stored:
            # store key on the side
            if '_pfstore_' not in self.__dict__:
                self.__dict__['_pfstore_'] = {}
            parent_namespace = self.full_name()
            full_key_name = f"{parent_namespace}" \
                            f"{'.' if parent_namespace else ''}{key}"
            self.__dict__['_pfstore_'][full_key_name] = value
            root_path = self.full_name()
            print(f"Caution: Using internal store of "
                  f"{root_path if root_path else 'run'} "
                  f"to save {full_key_name} = {value}")
            if exit_if_undefined:
                sys.exit(1)
示例#2
0
文件: core.py 项目: smithsg84/parflow
    def pfset(self,
              key='',
              value=None,
              yaml_file=None,
              yaml_content=None,
              pfidb_file=None,
              hierarchical_map=None,
              flat_map=None,
              exit_if_undefined=False,
              silence_if_undefined=False):
        """
        Allow to define any parflow key so it can be exported.
        Many formats are supported:
            - key/value: To set a single value relative to our current
                PFDBObj.
            - yaml_file: YAML file path to load and import using the
                current PFDBObj as root.
            - yaml_content: YAML string to load and import using the
                current PFDBObj as root.
            - hierarchical_map: Nested dict containing several key/value
                pair using the current PFDBObj as root.
            - flat_map: Flat dict with parflow key/value pair to set
                using the current PFDBObj as root.
        """
        if yaml_file:
            yaml_content = get_text_file_content(yaml_file)

        if yaml_content:
            hierarchical_map = yaml.safe_load(yaml_content)

        if pfidb_file:
            flat_map = read_pfidb(pfidb_file)

        if hierarchical_map:
            flat_map = flatten_hierarchical_map(hierarchical_map)

        if flat_map:
            sorted_flat_map = sort_dict_by_priority(flat_map)
            for key, value in sorted_flat_map.items():
                self.pfset(key=key,
                           value=value,
                           exit_if_undefined=exit_if_undefined,
                           silence_if_undefined=silence_if_undefined)

        if not key:
            return

        key_stored = False
        tokens = key.split('.')
        if len(tokens) > 1:
            value_key = tokens[-1]
            container, = self.select('/'.join(tokens[:-1]))

            if container is None:
                # We need to maybe handle prefix
                value_key = tokens.pop()
                container = self
                for name in tokens:
                    if container is None:
                        break

                    if name in container.__dict__:
                        container = container[name]
                    else:
                        # Extract available prefix
                        known_prefixes = set('_')
                        for child_name in container.keys():
                            if isinstance(container[child_name], PFDBObj):
                                prefix = getattr(container[child_name],
                                                 '_prefix_', '')
                                if prefix is not None:
                                    known_prefixes.add(prefix)

                        found = False

                        # Test names with prefix
                        for prefix in known_prefixes:
                            if found:
                                break
                            name_w_prefix = f'{prefix}{name}'
                            if name_w_prefix in container.__dict__:
                                found = True
                                container = container[name_w_prefix]

                        # No matching prefix
                        if not found:
                            container = None

            if container is not None:
                container[value_key] = value
                key_stored = True
        elif len(tokens) == 1:
            self[tokens[0]] = value
            key_stored = True

        if not key_stored:
            # Only create a store at the root node
            root = self
            while root._parent_ is not None:
                root = root._parent_

            # store key on the side
            if '_pfstore_' not in root.__dict__:
                root.__dict__['_pfstore_'] = {}
            parent_namespace = self.full_name()
            full_key_name = f"{parent_namespace}" \
                            f"{'.' if parent_namespace else ''}{key}"
            root.__dict__['_pfstore_'][full_key_name] = value
            root_path = self.full_name()
            if not silence_if_undefined:
                print(f"Caution: Using internal store of "
                      f"{root_path if root_path else 'run'} "
                      f"to save {full_key_name} = {value}")
            if exit_if_undefined:
                sys.exit(1)