Skip to content

solidworks_mcp.adapters.solidworks.com_utils

solidworks_mcp.adapters.solidworks.com_utils

Small COM helpers shared by the selection / face / rebuild modules.

One copy of each, so error-handling and flagging behaviour cannot drift between modules.

Functions:

as_list

as_list(value: Any) -> list[Any]

Normalise a COM array/scalar/None return into a list.

Source code in src/solidworks_mcp/adapters/solidworks/com_utils.py
def as_list(value: Any) -> list[Any]:
    """Normalise a COM array/scalar/None return into a list."""
    if value is None:
        return []
    if isinstance(value, (list, tuple)):
        return list(value)
    return [value]

attempt

attempt(adapter: Any, fn: Any, default: Any = None) -> Any

Run fn through the adapter's _attempt (exceptions -> default).

Source code in src/solidworks_mcp/adapters/solidworks/com_utils.py
def attempt(adapter: Any, fn: Any, default: Any = None) -> Any:
    """Run ``fn`` through the adapter's ``_attempt`` (exceptions -> default)."""
    return adapter._attempt(fn, default=default)

flag

flag(adapter: Any, obj: Any, *names: str) -> None

Flag just names as methods on obj (no-op for None/fakes).

Flagging a whole interface costs ~27 ms per fresh dispatch (see _WALK_MEMBERS in pywin32_adapter); SolidWorks hands back a fresh dispatch on most calls, so flag only what is about to be read.

Source code in src/solidworks_mcp/adapters/solidworks/com_utils.py
def flag(adapter: Any, obj: Any, *names: str) -> None:
    """Flag just ``names`` as methods on ``obj`` (no-op for ``None``/fakes).

    Flagging a whole interface costs ~27 ms per fresh dispatch (see
    ``_WALK_MEMBERS`` in pywin32_adapter); SolidWorks hands back a fresh
    dispatch on most calls, so flag only what is about to be read.
    """
    attempt(adapter, lambda: _sw_type_info.flag_members(obj, *names), 0)

selection_count

selection_count(adapter: Any, model: Any) -> int | None

Number of entities currently selected in model, or None.

Source code in src/solidworks_mcp/adapters/solidworks/com_utils.py
def selection_count(adapter: Any, model: Any) -> int | None:
    """Number of entities currently selected in ``model``, or None."""
    sel_mgr = attempt(adapter, lambda: model.SelectionManager)
    if sel_mgr is None:
        return None
    flag(adapter, sel_mgr, "GetSelectedObjectCount2")
    count = attempt(adapter, lambda: sel_mgr.GetSelectedObjectCount2(-1))
    return int(count) if isinstance(count, (int, float)) else None

strip_op_prefix

strip_op_prefix(error: str | None, operation_name: str) -> str | None

Drop _handle_com_operation's generic "Error in <op>: " prefix.

Expected failures (not found, nothing to select, rebuild errors) then read as plain sentences for the LLM caller.

Source code in src/solidworks_mcp/adapters/solidworks/com_utils.py
def strip_op_prefix(error: str | None, operation_name: str) -> str | None:
    """Drop ``_handle_com_operation``'s generic ``"Error in <op>: "`` prefix.

    Expected failures (not found, nothing to select, rebuild errors) then read
    as plain sentences for the LLM caller.
    """
    if not error:
        return error
    return error.removeprefix(f"Error in {operation_name}: ")