def test_xclim_translations(locale): registry_cp = registry.copy() loc, dic = xloc.get_local_dict(locale) assert "attrs_mapping" in dic assert "modifiers" in dic["attrs_mapping"] for translatable, translations in dic["attrs_mapping"].items(): if translatable != "modifiers": assert isinstance(translations, list) assert len(translations) <= len(dic["attrs_mapping"]["modifiers"]) assert set(dic["attrs_mapping"].keys()).symmetric_difference( default_formatter.mapping.keys()) == {"modifiers"} translated_inds = [] # Remove unofficial indicators (as those created during the tests) for identifier, cls in registry.items(): if not cls.__module__.startswith("xclim"): registry_cp.pop(identifier) for indicator, fields in dic.items(): if indicator != "attrs_mapping": # Checking that the translated indicator does exist # For translations of children of MultiIndicators, only check that the indicator exists if "." in indicator: indicator = indicator.split(".")[0] assert indicator in registry_cp or indicator in translated_inds else: assert registry_cp.pop(indicator) translated_inds.append(indicator) # Only translatable attributes are translated assert set(fields.keys()).issubset(xloc.TRANSLATABLE_ATTRS) if bool(registry_cp): pytest.fail( f"Indicators {','.join(registry_cp.keys())} do not have translations for official locale {locale}." )
def generate_local_dict(locale: str, init_english: bool = False) -> dict: """Generate a dictionary with keys for each indicator and translatable attributes. Parameters ---------- locale : str Locale in the IETF format init_english : bool If True, fills the initial dictionary with the english versions of the attributes. Defaults to False. """ from xclim.core.indicator import registry if locale in _LOCALES: locname, attrs = get_local_dict(locale) for ind_name in attrs.copy().keys(): if ind_name != "attrs_mapping" and ind_name not in registry: attrs.pop(ind_name) else: attrs = {} attrs_mapping = attrs.setdefault("attrs_mapping", {}) attrs_mapping.setdefault("modifiers", [""]) for key, value in default_formatter.mapping.items(): attrs_mapping.setdefault(key, [value[0]]) eng_attr = "" for ind_name, indicator in registry.items(): ind_attrs = attrs.setdefault(ind_name, {}) for translatable_attr in set(TRANSLATABLE_ATTRS).difference( set(indicator._cf_names) # noqa ): if init_english: eng_attr = getattr(indicator, translatable_attr) if not isinstance(eng_attr, str): eng_attr = "" ind_attrs.setdefault(f"{translatable_attr}", eng_attr) for cf_attrs in indicator.cf_attrs: # In the case of single output, put var attrs in main dict if len(indicator.cf_attrs) > 1: ind_attrs = attrs.setdefault( f"{ind_name}.{cf_attrs['var_name']}", {}) for translatable_attr in set(TRANSLATABLE_ATTRS).intersection( set(indicator._cf_names) # noqa ): if init_english: eng_attr = cf_attrs.get(translatable_attr) if not isinstance(eng_attr, str): eng_attr = "" ind_attrs.setdefault(f"{translatable_attr}", eng_attr) return attrs
def list_input_variables(submodules: Sequence[str] = None, realms: Sequence[str] = None) -> dict: """List all possible variables names used in xclim's indicators. Made for development purposes. Parses all indicator parameters with the :py:attribute:`xclim.core.utils.InputKind.VARIABLE` or `OPTIONAL_VARIABLE` kinds. Parameters ---------- realms: Sequence of str, optional Restrict the output to indicators of a list of realms only. Default None, which parses all indicators. submodules: str, optional Restrict the output to indicators of a list of submodules only. Default None, which parses all indicators. Returns ------- dict A mapping from variable name to indicator class. """ from collections import defaultdict from xclim import indicators from xclim.core.indicator import registry from xclim.core.utils import InputKind submodules = submodules or [ sub for sub in dir(indicators) if not sub.startswith("__") ] realms = realms or ["atmos", "ocean", "land", "seaIce"] variables = defaultdict(list) for name, ind in registry.items(): if "." in name: # external submodule, sub module name is prepened to registry key if name.split(".")[0] not in submodules: continue elif ind.realm not in submodules: # official indicator : realm == submodule continue if ind.realm not in realms: continue # ok we want this one. for varname, meta in ind.iter_parameters(): if meta["kind"] in [ InputKind.VARIABLE, InputKind.OPTIONAL_VARIABLE ]: var = meta.get("default") or varname variables[var].append(ind) return variables
def get_indicators(realms=["atmos"], exclude=()): """For all modules or classes listed, return the children that are instances of registered Indicator classes. module : A xclim module. """ from collections import OrderedDict from xclim.core.indicator import registry def filter_func(elem): name, ind = elem return (ind.realm in realms and ind.identifier is not None and name not in exclude and ind.identifier.upper() == ind._registry_id # official indicator ) out = OrderedDict(filter(filter_func, registry.items())) return [ind.get_instance() for ind in out.values()]