bench: matrix v6 adds arch_roundtrip; four architectural correctness checks; the live arch smoke
The evidence for track F, in the shape tracks A, E and B + G used. - benchmarks/tasks_v6.py: 19 tasks, DEFAULT_MATRIX = "v6"; v5 to v2 stay addressable. arch_roundtrip draws the example plan with arch_plan_from_spec and reads it back without the spec: rooms_detect must find each labelled room within 0.1 % of its label and of the net floor computed by hand (4825 x 5750 and 3825 x 5750), the schedules must list D1, D2, W1, W2, and the plan is gated on a zero-issue critique and a finalize score of at least 90. A test removes one room label and the gate fails naming arch_room_unlabelled. - Four correctness checks, every number worked out by hand in the docstring: L / T / X junction corners and wall areas, a 4 x 5 m room labelled 20.00 m2 rather than its 21.84 m2 axis area, a door interrupting both faces, and a plan of plain lines read as 20 and 15 m2 at confidence 0.6. The published A/B report is re-run over 43 checks: 26 / 43 -> 43 / 43, zero regressed. - scripts/smoke_arch_com.py runs the whole plan once on a live seat and closes every document it opens; the CHANGELOG records what it returned. - The token suite measures a TOOL_PACKS=core,arch row; check_doc_numbers derives the task count from the v6 matrix; CLAUDE.md, both READMEs and the spec status line say what shipped. - fix(com): the first live smoke exited 1 - the room reader found 0 wall segments. Measured on AutoCAD 2026 (2026-09-23): with a makepy cache, ModelSpace.Item(i) returns the gen_py IAcadEntity wrapper (type(item).__name__ == "IAcadEntity") and item.StartPoint on an AcDbLine raises AttributeError, so every entity_list row lost its type-specific properties (28 wall LINEs, 0 with start/end). _entity_info now re-dispatches exactly that wrapper through _com_unnarrow; after the fix 38 of 53 rows carry start/end and the smoke exits 0 with both rooms at 27 743 750 / 21 993 750 mm2 and 0 critique issues. Re-dispatch measured at ~1.7 ms per entity (dynamic vs gencache alike). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6e004cc658
commit
0abbe55041
+30
-4
@@ -897,10 +897,10 @@ def _com_unnarrow(obj):
|
||||
such a return in the gen_py class of the *declared* type, and that wrapper
|
||||
exposes only ``IAcadObject`` members: ``.Count`` / ``.Item`` / ``.GetName``
|
||||
on the dictionary and ``.ArrowSize`` / ``.TextStyle`` on a leader style all
|
||||
raise ``AttributeError`` even though the live object answers them. (The
|
||||
rest of this backend never meets the problem: ``HandleToObject`` is declared
|
||||
``IDispatch*``, which keeps the concrete class, and ``ModelSpace.Item`` is
|
||||
read only through ``IAcadEntity`` members.)
|
||||
raise ``AttributeError`` even though the live object answers them.
|
||||
(``HandleToObject`` is declared ``IDispatch*``, which keeps the concrete
|
||||
class; ``ModelSpace.Item`` is declared ``IAcadEntity*`` and meets the same
|
||||
problem - ``_entity_info`` un-narrows it through ``_com_concrete_entity``.)
|
||||
|
||||
``win32com.client.dynamic.Dispatch`` on the raw interface builds a
|
||||
late-bound proxy from the object's own type info, so every member of the
|
||||
@@ -1358,8 +1358,34 @@ def _temporary_edge_entity(space, kind: str, edge: dict):
|
||||
return ellipse
|
||||
|
||||
|
||||
#: The gen_py class names pywin32 gives a result whose *declared* type is an
|
||||
#: ActiveX base interface. ``ModelSpace.Item``, ``SelectionSet.Item`` and
|
||||
#: ``IAcadBlock.Item`` are declared ``IAcadEntity*`` (acax25enu.tlb).
|
||||
_COM_NARROWED_WRAPPERS = frozenset({"IAcadEntity", "IAcadObject"})
|
||||
|
||||
|
||||
def _com_concrete_entity(entity):
|
||||
"""The entity through its runtime class when a makepy wrapper narrowed it.
|
||||
|
||||
With a makepy cache for the AutoCAD type library, ``ModelSpace.Item(i)``
|
||||
comes back as the gen_py ``IAcadEntity`` class, which answers only the
|
||||
entity base's members. Measured on AutoCAD 2026 (2026-09-23): on an
|
||||
AcDbLine, ``type(item).__name__ == "IAcadEntity"`` and ``item.StartPoint``
|
||||
raises ``AttributeError`` - so every ``entity_list`` row lost its
|
||||
type-specific properties (a LINE kept only its bounding box) and the room
|
||||
reader saw no wall segments at all. Only that wrapper is re-dispatched:
|
||||
``_com_unnarrow`` walks the object's type info across the process
|
||||
boundary, and a concrete wrapper (``HandleToObject`` is declared
|
||||
``IDispatch*``) needs none of it.
|
||||
"""
|
||||
if type(entity).__name__ in _COM_NARROWED_WRAPPERS:
|
||||
return _com_unnarrow(entity)
|
||||
return entity
|
||||
|
||||
|
||||
def _entity_info(entity) -> EntityInfo:
|
||||
"""Convert a COM entity object to EntityInfo dataclass."""
|
||||
entity = _com_concrete_entity(entity)
|
||||
try:
|
||||
bb_min, bb_max = entity.GetBoundingBox()
|
||||
props = {
|
||||
|
||||
Reference in New Issue
Block a user