diff --git a/backends/com_backend.py b/backends/com_backend.py index 7436dec..5f506d7 100644 --- a/backends/com_backend.py +++ b/backends/com_backend.py @@ -3990,15 +3990,18 @@ class ComBackend(AutoCADBackend): return await self._run(_sync) async def system_get_variable(self, name) -> Any: + # GetVariable / SetVariable are members of AcadDocument, not of + # AcadApplication: `AutoCAD.Application.GetVariable` raises + # AttributeError on a live seat before anything reaches AutoCAD. def _sync(): - app = _acad_app() - return app.GetVariable(name) + doc = _acad_doc() + return doc.GetVariable(name) return await self._run(_sync) async def system_set_variable(self, name, value) -> dict: def _sync(): - app = _acad_app() + doc = _acad_doc() # the sysvar host is the document (see system_get_variable) # Coerce to the sysvar's actual type (NEW-com-set-variable-coercion): # AutoCAD rejects e.g. a string "0" for the integer OSMODE. Probe the # current value's type and convert to match; pass through on failure. @@ -4010,7 +4013,7 @@ class ComBackend(AutoCADBackend): # AutoCAD had already applied the write. payload = value try: - current = app.GetVariable(name) + current = doc.GetVariable(name) if isinstance(current, bool): coerced = bool(int(value)) if isinstance(value, str) else bool(value) elif isinstance(current, int): @@ -4027,7 +4030,7 @@ class ComBackend(AutoCADBackend): payload = _av(coerced) if isinstance(current, (tuple, list)) else coerced except Exception as exc: log.debug("set_variable type probe for %s failed: %s", name, exc) - app.SetVariable(name, payload) + doc.SetVariable(name, payload) return {"ok": True, "variable": name, "value": coerced} return await self._run(_sync) diff --git a/tests/test_com_backend.py b/tests/test_com_backend.py index 8646a5f..3033553 100644 --- a/tests/test_com_backend.py +++ b/tests/test_com_backend.py @@ -317,6 +317,19 @@ async def test_com_backend_connects(): # number it already has? +@pytest.fixture(autouse=True) +def _restore_acad_doc(): + """`_measure_backend` swaps the module-level `_acad_doc`; put it back after + every test here. Left in place, the MagicMock document leaked into every + later test of the session that resolves the document itself (the settings + facade's COM tests read sysvars through `_acad_doc()`).""" + import backends.com_backend as cb + + original = cb._acad_doc + yield + cb._acad_doc = original + + def _measure_backend(entity): """A ComBackend whose HandleToObject returns exactly this entity.""" import backends.com_backend as cb @@ -329,7 +342,7 @@ def _measure_backend(entity): backend._run = _run doc = MagicMock() doc.HandleToObject.return_value = entity - cb._acad_doc = lambda: doc + cb._acad_doc = lambda: doc # restored by `_restore_acad_doc` return backend diff --git a/tests/test_com_sprint3.py b/tests/test_com_sprint3.py index 743ff11..b90c35f 100644 --- a/tests/test_com_sprint3.py +++ b/tests/test_com_sprint3.py @@ -55,14 +55,16 @@ class _Doc: async def test_set_variable_coerces_string_to_sysvar_int_type(monkeypatch): - app = MagicMock() - app.GetVariable.return_value = 4159 # OSMODE current value is an int - monkeypatch.setattr(cb, "_acad_app", lambda: app) + # GetVariable / SetVariable are AcadDocument members (the Application has + # neither), so the fake is the document that `_acad_doc()` returns. + doc = MagicMock() + doc.GetVariable.return_value = 4159 # OSMODE current value is an int + monkeypatch.setattr(cb, "_acad_doc", lambda: doc) b = _backend_no_executor() out = await b.system_set_variable("OSMODE", "0") - name, val = app.SetVariable.call_args[0] + name, val = doc.SetVariable.call_args[0] assert name == "OSMODE" assert val == 0 and isinstance(val, int) # coerced from "0" to int 0 assert out["value"] == 0