euromod_linking.query ===================== .. py:module:: euromod_linking.query .. autoapi-nested-parse:: Connector-backed read helpers for a country's policy structure. Two-stage design so extension exploration is cheap: 1. `_build_raw_country` materialises the connector object graph for a country ONCE (the expensive first-touch interop), extracting every policy/constant definition plus its extension links (shortName, baseOff) as plain data. Cached per country. 2. `_resolve` builds a CountryIndex from that raw data for a given (dataset, extensions) configuration in pure Python — no connector interop. Duplicate definitions are resolved *switch- and extension-aware*: a per-system switch config (get_switch_value baseline for a dataset + caller overrides) drives the same include/exclude logic as euromod.container.filter; the effective value is the last non-'n/a' among active definitions in spine order (fallback: last non-'n/a' overall). Both raw and resolved results are cached; the model is read-only at runtime so caches stay valid for the process lifetime. `system_extension_names`, `system_constant_names`, `system_constant_params` and `income_list_components` are kept here rather than taken from `euromod`, so the package works against every released version of the connector. Exceptions ---------- .. autoapisummary:: euromod_linking.query.IncomeListLookupError Classes ------- .. autoapisummary:: euromod_linking.query.ConstantInfo euromod_linking.query.CountryIndex euromod_linking.query.PolicyInfo euromod_linking.query.SystemInfo Functions --------- .. autoapisummary:: euromod_linking.query.build_country_index euromod_linking.query.clear_caches euromod_linking.query.get_country_index euromod_linking.query.income_list_components euromod_linking.query.iter_real_policies euromod_linking.query.resolve_income_list euromod_linking.query.system_constant_names euromod_linking.query.system_constant_params euromod_linking.query.system_extension_names Module Contents --------------- .. py:exception:: IncomeListLookupError(message: str, available: list[str]) Mapping key not found. .. py:attribute:: available .. py:class:: ConstantInfo .. py:attribute:: comment :type: str .. py:attribute:: group :type: str .. py:attribute:: name :type: str .. py:attribute:: policy :type: str .. py:class:: CountryIndex .. py:attribute:: code :type: str .. py:attribute:: constants :type: dict[str, ConstantInfo] .. py:attribute:: policies :type: dict[str, PolicyInfo] .. py:attribute:: systems :type: dict[str, SystemInfo] .. py:class:: PolicyInfo .. py:attribute:: comment :type: str .. py:attribute:: constants :type: list[str] :value: [] .. py:attribute:: name :type: str .. py:attribute:: order :type: int .. py:attribute:: type :type: str .. py:class:: SystemInfo .. py:attribute:: constant_values :type: dict[str, str] .. py:attribute:: name :type: str .. py:attribute:: policy_switches :type: dict[str, str] .. py:attribute:: year :type: str .. py:function:: build_country_index(country_code: str, dataset=None, extensions=None) -> CountryIndex Materialise (or reuse) the country's raw data and resolve it for one config. .. py:function:: clear_caches() .. py:function:: get_country_index(country_code: str, dataset=None, extensions=None) -> CountryIndex | None .. py:function:: income_list_components(country_code: str, system_name: str, list_name: str, dataset=None, extensions=None) -> list[tuple[str, str]] Effective (variable, sign) components of an income list in a live system, resolved for the given (dataset, extensions) configuration. .. py:function:: iter_real_policies(scope) Yield policies of a Country or System, skipping ReferencePolicy objects (which lack .functions/.comment and crash naive iteration/find()). .. py:function:: resolve_income_list(rsys: dict, cfg: dict, list_name: str, _seen: frozenset = frozenset()) -> list[tuple[str, str]] Pure resolution of an income list's effective components under one (dataset, extensions) switch config, from a system's raw data. Extension-aware at every level: the defining policy, the DefIl function, and each component parameter must be active/included. Duplicate DefIl definitions resolve in spine order (last active wins, the constants rule); nested ils_*/il_* components expand recursively, cycle-safe, with signs multiplied through. Deterministic; components in definition order, deduped. .. py:function:: system_constant_names(system) -> set[str] $-prefixed constant names defined (via DefConst) in a live System object. Extension-independent; used to validate constants_to_overwrite. .. py:function:: system_constant_params(system) -> dict[str, set[str]] All $-prefixed parameter names overridable via run(constantsToOverwrite=...), mapped to the set of groups they are defined with ('' = ungrouped). Walks every function, not just DefConst: uprating factors (e.g. $f_cpi) are parameters of the Uprate function keyed by year-group, and must validate as ("$f_cpi", "2023")-style overrides. .. py:function:: system_extension_names(country_code: str, system_name: str | None = None) -> set[str] Extension short names the model accepts in run(switches=...). A switch the model does not know is silently dropped by the engine (it only mutters "An error occurred during the processing of the ExtensionSwitches"), so a scenario can appear to run while the behaviour it asked for never happened. Callers validate against this first. Sources, unioned: the country's own extensions (country.extensions merges local + model-wide, i.e. everything declared in Config/SWITCHABLEPOLICYCONFIG.xml — including add-on extensions such as LMA_trans) and the per-dataset switch defaults actually observed for the system. Returns an empty set if neither can be read, which callers treat as "cannot validate" rather than "nothing is valid".