Resolve Client.Python-001/002/004/006/007/008/010/011/012 findings

Client.Python-001: dropped "scaffold" from the stale pyproject description.
Client.Python-002 (re-triaged): stale finding — MxGatewayCommandError is
already exported and in __all__; no change needed.
Client.Python-004: removed the dead `closed` variable in _smoke; the CLI
smoke now uses `async with session`.
Client.Python-006: close() on both clients and Session had an unlocked
check-then-set race; `_closed` is now set before the await.
Client.Python-007: gateway stream iterators now share one helper that
explicitly catches CancelledError and cancels the call.
Client.Python-008: to_mx_value now rejects nan/inf; float/bytes mapping
documented.
Client.Python-010: removed the circular-import-workaround late imports in
favour of TYPE_CHECKING / module-scope imports.
Client.Python-011: ensure_mxaccess_success no longer treats a proto3-default
success==0 with an unset category as a failure.
Client.Python-012 (Won't Fix): invoke_raw deliberately skips MXAccess-failure
detection for parity tests; documented the contract instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-18 22:59:24 -04:00
parent b4f5e8eb48
commit a7bf1ef95d
10 changed files with 385 additions and 79 deletions
+23 -1
View File
@@ -138,7 +138,7 @@ def ensure_mxaccess_success(operation: str, reply: pb.MxCommandReply) -> pb.MxCo
)
for mx_status in reply.statuses:
if mx_status.success == 0:
if _is_mxaccess_status_failure(mx_status):
raise MxAccessError(
_mxaccess_message(operation, reply),
protocol_status=status,
@@ -148,6 +148,28 @@ def ensure_mxaccess_success(operation: str, reply: pb.MxCommandReply) -> pb.MxCo
return reply
def _is_mxaccess_status_failure(mx_status: pb.MxStatusProxy) -> bool:
"""Return ``True`` only for a populated MXAccess status reporting failure.
MXAccess uses ``success == 0`` as the failure flag, but ``0`` is also the
proto3 scalar default. The gateway emits placeholder ``MxStatusProxy``
entries with ``success`` unset for null ``MXSTATUS_PROXY`` COM entries
(see ``MxStatusProxyConverter.ConvertMany``); such an entry has
``category`` of ``UNSPECIFIED`` or ``UNKNOWN``. Treating it as a failure
would raise ``MxAccessError`` for a reply that carries no real failure,
so failure is keyed on ``success == 0`` together with a populated,
non-OK status category.
"""
if mx_status.success != 0:
return False
return mx_status.category not in (
pb.MX_STATUS_CATEGORY_UNSPECIFIED,
pb.MX_STATUS_CATEGORY_UNKNOWN,
pb.MX_STATUS_CATEGORY_OK,
)
def _mxaccess_message(operation: str, reply: pb.MxCommandReply) -> str:
status_text = reply.protocol_status.message or "MXAccess command failed"
hresult = reply.hresult if reply.HasField("hresult") else None