flexicon package

Subpackages

Module contents

flexicon.CAPABILITIES = frozenset({'parser', 'per-operation-uow', 'refresh-from-disk', 'transaction-rollback', 'ui-injection'})

Capabilities this build of flexicon implements, probed with in.

Consumers (notably FlexToolsMCP) must probe defensively, because releases at or below 4.3.0 do not define this name at all:

CAPS = getattr(flexicon, "CAPABILITIES", frozenset())
if "per-operation-uow" in CAPS:
    ...          # post-Track-B surface
else:
    ...          # 4.3.0 floor: session-envelope path

Use the one-line getattr(..., frozenset()) form, not a two-step hasattr() check. See docs/FLEXTOOLSMCP_WRITE_CONTRACT.md section 3.

IMPORTANT – a token here means “this build implements the capability”, NOT “the capability is active in your session”. Two of the four are mode-dependent: they are active under undoable=True, which is the default since 4.4.0, and deliver nothing if a caller opts out with undoable=False:

"ui-injection" Always active. OpenProject(..., ui=...)

accepts an ILcmUI; defaults to a bare HeadlessLcmUI() since issue #285 (a conflicting save raises FP_ConflictingSaveError rather than blocking on or silently discarding through the historical FwLcmUI, which remains reachable by passing it explicitly).

"refresh-from-disk" Always active. FLExProject.RefreshFromDisk()

wraps IUndoStackManager.Refresh(); needed in BOTH modes, since one foreign FLEx save otherwise wedges auto-save for the rest of the session.

"per-operation-uow" Requires undoable=True (the default). Every

LCM mutation runs inside a named, nesting-aware unit of work. If a caller opts out with undoable=False the atomicity unit is the whole SESSION, not the operation.

"transaction-rollback"``Requires ``undoable=True (the default). An

exception escaping a transaction reverts that operation’s mutations via UndoableUnitOfWorkHelper’s Rollback(0). Under undoable=False there is NO rollback – liblcm exposes no reachable rollback-to-mark API in that mode (issue #236), and mutations applied before a failure are still written to disk by CloseProject().

OpenProject() already warns once per call when writeEnabled=True is combined with an explicit undoable=False, so the mode dependence is surfaced at the boundary where the mode is chosen as well as here.

parser is mode-independent but MACHINE-dependent, and the distinction matters more here than for the four above. The token says this build ships project.Parser; it says NOTHING about whether the machine reading it can reach a parser, because that depends on a FieldWorks component this package does not install and deliberately does not require. A consumer must therefore PROBE rather than infer:

if "parser" in getattr(flexicon, "CAPABILITIES", frozenset()):
    status = project.Parser.GetAvailability()   # ask the machine
    if status.available:
        ...

Treating the token as “a parser is available” is the one misreading that turns a degrade-with-a-reason into a crash.