euromod_linking.compat¶
Method requirements versus what the model actually provides.
A methodology declares what its runs need — lma_labour_alignment needs the
LMA add-on and the LMA_trans extension switch — and this module checks that
the model in front of it has them. An unknown add-on is dropped by the engine
with only a console message, so left unchecked both simulations complete
normally and produce identical output, and the failure surfaces at the end as
NoEffectError, after paying for two runs. Answering the question first is why
this is called from the validate_only path.
Two kinds of evidence, deliberately unequal.
Release — advisory¶
Which EUROMOD release a model folder holds is not reliably knowable. The
documented marker XMLParam/Config/EuromodVersion.txt has writer code in the
UI but ships in no real release; the folder name is what the UI itself falls
back to (EM_AppContext.GetProjectName feeding <EMVERSION>), and renaming
the folder erases it. So a detected release only enriches the message — “the
LMA_trans extension is first shipped in J2.54, this model looks like J2.19” —
and failing to detect one never blocks anything.
Set EUROMOD_SKIP_COMPAT_CHECK=1 to bypass the check, mirroring the
connector’s own EUROMOD_SKIP_VERSION_CHECK.
Attributes¶
Classes¶
What one method needs, what this model has, and the gap between them. |
|
One thing a method needs from the model, and whether it is there. |
Functions¶
|
|
|
A report per registered methodology, in registry order. |
|
Can this methodology actually run against this model and system? |
|
Which methodologies this model supports, as a DataFrame. |
|
Best-effort |
|
Split |
|
Is release at least floor? None when either cannot be parsed. |
Module Contents¶
- class euromod_linking.compat.CompatibilityReport[source]¶
What one method needs, what this model has, and the gap between them.
problemsare hard failures — the run would not do what was asked.notesare advisory: an undeterminable requirement, or a release that looks older than the method’s floor.Read-only property
okis True when there are no problems; notes never make a report not-ok. This is the field to check.
- class euromod_linking.compat.Requirement[source]¶
One thing a method needs from the model, and whether it is there.
satisfiedis tri-state: True, False, or None when the model could not be read — a distinction that matters, because treating “cannot read” as “not present” would refuse to run against a perfectly good model.
- euromod_linking.compat.canonical_release(release: str | None) str | None[source]¶
"..._j2.54"->"J2.54"; unparseable input comes back stripped.Every detection source is run through this, so a report shows one spelling of a release whether it came from a lowercased folder name, a licence file or the change log.
- euromod_linking.compat.check_all(system, *, deep_release: bool = False) list[CompatibilityReport][source]¶
A report per registered methodology, in registry order.
- euromod_linking.compat.check_compatibility(system, method, *, deep_release: bool = False) CompatibilityReport[source]¶
Can this methodology actually run against this model and system?
method is a reference like
"lma_labour_alignment"or an MethodSpec. system is a live connector System, from which the country, the model and the model path are reached.Checks each declared add-on and extension switch against the model, and compares the detected release against the method’s
min_model_release. Only the first of those can produce a problem; the release only ever adds a note explaining one. Withdeep_releasethe change log is parsed too, at the cost of reading a large workbook.
- euromod_linking.compat.compatibility_matrix(model, country_code: str | None = None, *, deep_release: bool = False)[source]¶
Which methodologies this model supports, as a DataFrame.
One row per (country, system, methodology) with
ok, the detected release, and the problems — the answer to “what can I actually run here” without writing a scenario first. Restrict with country_code, since walking every country of a full model means loading every country.
- euromod_linking.compat.model_release(model_path: str, *, deep: bool = False)[source]¶
Best-effort
(release, source)for a model folder, e.g.("J2.19", "folder-name").Tries the documented version file, then the folder name, then a public release’s licence file; with
deep=Trueit finally parses the change log, which is slow but survives a renamed folder.(None, None)means the release could not be determined — which callers must treat as unknown, never as too old.
- euromod_linking.compat.parse_release(release: str | None)[source]¶
Split
"J2.54"into a sortable("J", 2, 54, False), or None.The last element is the trailing
+of a beta/rolling release, which sorts just above the bare version soJ1.86+is not read as older thanJ1.86. None for anything that does not look like a release at all — callers treat that as “cannot compare”, not as “older”.
- euromod_linking.compat.release_geq(release: str | None, floor: str | None)[source]¶
Is release at least floor? None when either cannot be parsed.
Fails open — the caller turns None into a note, not a refusal. This is the opposite of
euromod.utils._version.version_geq, which gates the engine and so fails closed; here the capability probe is the real check and the release is only there to write a better message.
- euromod_linking.compat.RELEASE_RE¶
- euromod_linking.compat.RELEASE_SOURCES = ('version-file', 'folder-name', 'licence-file', 'em-log')¶