fix(com): four live defects the settings smoke measured on AutoCAD 2026 — rejected calls after a document switch, typelib spelling of color/Lineweight, narrowed layer-state dictionary, layer 0 Freeze put

Measured 2026-09-22 by scripts/smoke_settings_com.py --build-dwt against the
running AutoCAD 2026 (25.1s), each on a scratch Documents.Add() document:

1. RPC_E_CALL_REJECTED (-2147418111) on Documents.Count straight after
   Documents.Open, after Close(False) inside document_close, and in
   _ensure_document_state: AutoCAD's own message filter refuses incoming
   calls while it is still switching documents. pywin32 exposes no
   CoRegisterMessageFilter, so _wait_out_rejected_call waits the window out
   for read-only callables (0.25 s -> 1 s pauses, 20 s budget, inside
   COM_CALL_TIMEOUT) at those sites and after Documents.Add/Open; any other
   com_error is not retried.
2. layer_list raised "'IAcadLayer' object has no attribute 'Color'. Did you
   mean: 'color'?": acax25enu.tlb spells IAcadEntity/IAcadLayer `color` and
   `Lineweight`. Late-bound dispatch resolved .Color/.LineWeight
   case-insensitively; with a makepy cache present (this machine's gen_py was
   regenerated on 2026-09-17, and every object a method returns is then a
   generated wrapper) the lookup is exact. All 17 sites now use the typelib
   spelling, which works on both wrappers; the fakes model the measured names.
3. layer_state_restore raised "'IAcadObject' object has no attribute
   'Count'": Dictionaries.Item and IAcadDictionary.Item are declared
   IAcadObject* (the narrowing _com_unnarrow already handles for MLEADER
   styles). The save path went through the typed Dictionaries.Add, so only
   the reopen paths failed. Both now un-narrow; the fakes narrow like pywin32.
4. The Freeze put on layer 0 raises 'Invalid layer' whatever the value, even
   False while thawed (color/Linetype/Lineweight/Plottable/LayerOn/Lock/
   ActiveLayer all fine on it), so a state saved with 0 current restored with
   two warnings and 0 unapplied. Freeze is written only when it changes the
   layer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
Umut CAN
2026-09-22 13:07:31 +03:00
co-authored by Claude Opus 5
parent 0514f8f15d
commit b54271f4ac
9 changed files with 291 additions and 61 deletions
+4 -4
View File
@@ -483,7 +483,7 @@ async def test_com_explode_carries_the_attrib_frame_and_style_onto_the_text(com)
UpsideDown=False,
Alignment=4,
TextAlignmentPoint=(-20.0, 13.0, 0.0),
Color=3,
color=3,
)
ref = _FakeObject(
"AcDbBlockReference",
@@ -537,7 +537,7 @@ async def test_com_explode_carries_the_attrib_frame_and_style_onto_the_text(com)
"Alignment": 4,
"TextAlignmentPoint": (-20.0, 13.0, 0.0),
"Layer": "PID-TAG",
"Color": 3,
"color": 3,
}
@@ -963,7 +963,7 @@ async def test_com_explode_turns_a_multi_line_attrib_into_mtext(com):
Rotation=0.5236,
StyleName="ISO",
Layer="PID-TAG",
Color=3,
color=3,
Invisible=False,
)
plain = _FakeObject(
@@ -1010,7 +1010,7 @@ async def test_com_explode_turns_a_multi_line_attrib_into_mtext(com):
("AttachmentPoint", 9), # acAttachmentPointBottomRight
("InsertionPoint", (7.0, 15.2, 0.0)), # re-asserted after the attachment moved it
("Layer", "PID-TAG"),
("Color", 3),
("color", 3),
]
assert tuple(space.texts[0].InsertionPoint.value) == (7.0, 15.2, 0.0), (
"the MTEXT ends up anchored at the ATTRIB's alignment point"