def _merge_default_lists(primary: ListConfig, merged_list: ListConfig) -> None: assert isinstance(primary, ListConfig) assert isinstance(merged_list, ListConfig) def get_key(d1: DictConfig) -> str: keys_iter = iter(d1.keys()) key1 = next(keys_iter) if key1 == "optional": key1 = next(keys_iter) assert isinstance(key1, str) return key1 key_to_idx = {} for idx, d in enumerate(primary): assert isinstance(d, (DictConfig, str)) if isinstance(d, DictConfig): key = get_key(d) key_to_idx[key] = idx for d in copy.deepcopy(merged_list): if isinstance(d, DictConfig): key = get_key(d) if key in key_to_idx.keys(): idx = key_to_idx[key] primary[idx] = d merged_list.remove(d) # append remaining items that were not matched to existing keys for d in merged_list: primary.append(d)
def _apply_free_defaults(self, defaults: ListConfig, overrides: List[str]) -> List[str]: consumed = [] for override in copy.copy(overrides): key, value = split_key_val(override) if self.exists_in_search_path(key): # Do not add multirun configs into defaults, those will be added to the defaults # during the runs after list is broken into items if "," not in value: defaults.append({key: value}) overrides.remove(override) consumed.append(override) return consumed
def test_list_setitem_invalid_element_type( lc: ListConfig, index: Optional[int], value: Any, err_msg: str, ) -> None: lc_orig = lc lc = copy.deepcopy(lc) with raises(ValidationError, match=err_msg): if index is None: lc.append(value) else: lc[index] = value assert lc == lc_orig
def test_list_assign_to_container_typed_element_special( cfg: ListConfig, value: Any, type_hint: Any, key_type: Any, elt_type: Any, ) -> None: cfg = copy.deepcopy(cfg) n = len(cfg) for idx in range(n): cfg[idx] = value check_subnode(cfg, idx, value, type_hint, key_type, elt_type, None) cfg.append(value) check_subnode(cfg, n, value, type_hint, key_type, elt_type, None)
def test_append_to_typed( cfg: ListConfig, value: Any, expected: Any, expected_ref_type: type, ) -> None: cfg = _ensure_container(cfg) if isinstance(expected, type): with raises(expected): cfg.append(value) else: cfg.append(value) assert cfg == expected node = cfg._get_node(-1) assert isinstance(node, Node) assert node._metadata.ref_type == expected_ref_type validate_list_keys(cfg)
def test_list_assign_to_container_typed_element( cfg: ListConfig, value: Any, type_hint: Any, key_type: Any, elt_type: Any, obj_type: Any, ensure_container: bool, ) -> None: cfg = copy.deepcopy(cfg) if ensure_container: value = _ensure_container(value) n = len(cfg) for idx in range(n): cfg[idx] = value check_subnode(cfg, idx, value, type_hint, key_type, elt_type, obj_type) cfg.append(value) check_subnode(cfg, n, value, type_hint, key_type, elt_type, obj_type)
def values(key: str, _root_: BaseContainer, _parent_: Container) -> ListConfig: assert isinstance(_parent_, BaseContainer) in_dict = _get_and_validate_dict_input(key, parent=_parent_, resolver_name="oc.dict.values") content = in_dict._content assert isinstance(content, dict) ret = ListConfig([]) for k in content: ref_node = AnyNode(f"${{{key}.{k!s}}}") ret.append(ref_node) # Finalize result by setting proper type and parent. element_type: Any = in_dict._metadata.element_type ret._metadata.element_type = element_type ret._metadata.ref_type = List[element_type] ret._set_parent(_parent_) return ret
def _list_merge(dest: Any, src: Any) -> None: from omegaconf import DictConfig, ListConfig, OmegaConf assert isinstance(dest, ListConfig) assert isinstance(src, ListConfig) if src._is_none(): dest._set_value(None) elif src._is_missing(): # do not change dest if src is MISSING. if dest._metadata.element_type is Any: dest._metadata.element_type = src._metadata.element_type elif src._is_interpolation(): dest._set_value(src._value()) else: temp_target = ListConfig(content=[], parent=dest._get_parent()) temp_target.__dict__["_metadata"] = copy.deepcopy( dest.__dict__["_metadata"]) is_optional, et = _resolve_optional(dest._metadata.element_type) if is_structured_config(et): prototype = DictConfig(et, ref_type=et, is_optional=is_optional) for item in src._iter_ex(resolve=False): if isinstance(item, DictConfig): item = OmegaConf.merge(prototype, item) temp_target.append(item) else: for item in src._iter_ex(resolve=False): temp_target.append(item) dest.__dict__["_content"] = temp_target.__dict__["_content"] # explicit flags on the source config are replacing the flag values in the destination flags = src._metadata.flags assert flags is not None for flag, value in flags.items(): if value is not None: dest._set_flag(flag, value)
def test_append_convert(lc: ListConfig, element: Any, expected: Any) -> None: lc.append(element) value = lc[-1] assert value == expected assert type(value) == type(expected)
def test_append_invalid_element_type(lc: ListConfig, element: Any, expected: Any) -> None: with expected: lc.append(element)
def test_append_invalid_element_type(lc: ListConfig, element: Any, err: Any) -> None: with raises(ValidationError, match=re.escape(err)): lc.append(element)