Source code for flexicon.code.FLExInit

#
#   FLExInit.py
#
#   Module: Fieldworks Language Explorer initialisation.
#
#   Note:   This module needs to be imported before importing or
#           using any Fieldworks Assemblies as it sets up the
#           path, and other low-level things.
#
#   Usage:  Call FLExInitialize() and FLExCleanup() as the first and
#           last actions from the main application.
#
#   Platform: Python.NET & IRONPython
#             FieldWorks Version 9
#
#   Copyright Craig Farrow, 2011 - 2022
#

import sys
import os
import glob
import shutil

import logging

logger = logging.getLogger(__name__)

# Defer version import to avoid circular dependency during initialization
try:
    from .. import version

    logger.info("flexlibs version: %s" % version)
except ImportError:
    # Version module not yet available during initialization
    version = None

logger.info("Python version: %s" % sys.version)

import clr
import System

# Configure the path for accessing the FW DLLs
from . import FLExGlobals

FLExGlobals.InitialiseFWGlobals()

clr.AddReference("FwUtils")
from SIL.FieldWorks.Common.FwUtils import FwRegistryHelper, FwUtils

clr.AddReference("SIL.WritingSystems")
from SIL.WritingSystems import Sldr

# -------------------------------------------------------------------


[docs] def FLExInitialize(): """ Initialize the Fieldworks libraries. An application should call this as the first thing it does. """ # [FW9] These 3 inits copied from LCMBrowser::Main() logger.debug("Calling RegistryHelper.Initialize()") FwRegistryHelper.Initialize() logger.debug("Calling InitializeIcu()") FwUtils.InitializeIcu() # No need to access the online SLDR: Offline mode = True # # [#249] Sldr.Initialize() must NOT be wrapped in a bare `except # Exception`. If it fails for a real reason the SLDR stays down for the # whole process; every subsequent LDML read inside # CoreLdmlInFolderWritingSystemRepository then throws "The SLDR has not # been initialized", and liblcm responds by renaming the project's # .ldml files to .ldml.bad and re-synthesizing the writing systems from # defaults. That cycle repeats on every open and never terminates, so a # genuine failure has to reach the caller instead of being downgraded to # a warning that misattributes it as "already initialized?". # # Sldr exposes a public static IsInitialized probe (verified by live # reflection against SIL.WritingSystems 18.0.0.0 / FieldWorks 9.3.10), # which is safe to read before any init and mirrors the guard that # Initialize() itself uses. Probing it means the benign # already-initialized case never raises at all, which keeps repeated # FLExInitialize() calls a no-op -- examples and per-test setUp rely on # that. if Sldr.IsInitialized: logger.debug("Sldr already initialized; skipping Sldr.Initialize()") else: logger.debug("Calling Sldr.Initialize()") try: Sldr.Initialize(True) # offlineTestMode=True except System.InvalidOperationException as e: # Retained only as a backstop for the check-then-act race: # Initialize()/Cleanup() serialize on a private lock, so another # thread can win between the probe and the call. Anything that is # not that exact benign message is a real failure and must # propagate. if "already been initialized" not in e.Message: raise logger.debug( "Sldr was initialized concurrently by another caller; continuing" ) # Sldr.Initialize() can fail silently. If it doesn't return, # then it is likely a dll issue. logger.debug("FLExInit.Initialize complete")
[docs] def FLExCleanup(): """ Close up the Fieldworks libraries. An application should call this before exiting. """ # [#249] Sldr.Cleanup() throws System.InvalidOperationException("The SLDR # has not been initialized.") when the SLDR is down -- so an unguarded # call made FLExCleanup() raise whenever FLExInitialize() was never run or # cleanup ran twice (several shipped examples call it twice by design). # Cleanup is a teardown step and must be tolerant of already being done. if not Sldr.IsInitialized: logger.debug("Sldr not initialized; skipping Sldr.Cleanup()") return logger.debug("Calling Sldr.Cleanup()") Sldr.Cleanup()