diff --git a/ale/util.py b/ale/util.py index 35ce235caed5a9a9d1dc3f667b31fcf453eb05d5..dd841c238ef44cd77755bfd895b987b14ea894ad 100644 --- a/ale/util.py +++ b/ale/util.py @@ -131,14 +131,15 @@ def find_latest_metakernel(path, year): def dict_merge(dct, merge_dct): + new_dct = dct.copy() for k, v in merge_dct.items(): if (k in dct and isinstance(dct[k], dict) and isinstance(merge_dct[k], Mapping)): - dict_merge(dct[k], merge_dct[k]) + new_dct[k] = dict_merge(dct[k], merge_dct[k]) else: - dct[k] = merge_dct[k] + new_dct[k] = merge_dct[k] - return dct + return new_dct def get_isis_preferences(isis_preferences=None): @@ -178,15 +179,23 @@ def dict_to_lower(d): def expandvars(path, env_dict=os.environ, default=None, case_sensitive=True): - user_dict = env_dict if case_sensitive else dict_to_lower(env_dict) + if env_dict != os.environ: + env_dict = dict_merge(env_dict, os.environ) - def replace_var(m): - group0 = m.group(0) if case_sensitive else m.group(0).lower() - group1 = m.group(1) if case_sensitive else m.group(1).lower() + while "$" in path: + user_dict = env_dict if case_sensitive else dict_to_lower(env_dict) - return user_dict.get(m.group(2) or group1, group0 if default is None else default) - reVar = r'\$(\w+|\{([^}]*)\})' - return re.sub(reVar, replace_var, path) + def replace_var(m): + group1 = m.group(1) if case_sensitive else m.group(1).lower() + val = user_dict.get(m.group(2) or group1 if default is None else default) + if not val: + raise KeyError(f"Failed to evaluate {m.group(0)} from env_dict. " + + f"Should {m.group(0)} be an environment variable?") + + return val + reVar = r'\$(\w+|\{([^}]*)\})' + path = re.sub(reVar, replace_var, path) + return path def generate_kernels_from_cube(cube, expand=False, format_as='list'): @@ -281,7 +290,7 @@ def get_kernels_from_isis_pvl(kernel_group, expand=True, format_as="list"): if not "DataDirectory" in isisprefs: warnings.warn("No IsisPreferences file found, is your ISISROOT env var set?") - kernels = [expandvars(expandvars(k, isisprefs['DataDirectory'], case_sensitive=False)) for k in kernels] + kernels = [expandvars(k, isisprefs['DataDirectory'], case_sensitive=False) for k in kernels] # Ensure that the ISIS Addendum kernel is last in case it overrides # some values from the default Instrument kernel # Sorts planetary constants kernel first so it can be overridden by more specific kernels @@ -295,7 +304,7 @@ def get_kernels_from_isis_pvl(kernel_group, expand=True, format_as="list"): for kern_list in mk_paths: for index, kern in enumerate(mk_paths[kern_list]): if kern is not None: - mk_paths[kern_list][index] = expandvars(expandvars(kern, isisprefs['DataDirectory'], case_sensitive=False)) + mk_paths[kern_list][index] = expandvars(kern, isisprefs['DataDirectory'], case_sensitive=False) return mk_paths else: raise Exception(f'{format_as} is not a valid return format')