personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

observe/describe: lazy-import av and aruco to silence macOS ObjC dup-class warning

`import av` and `from observe.aruco import ...` at module scope dragged
PyAV and cv2 into every caller that only needed `CATEGORIES` (e.g.
`observe/screen.py`, `apps/settings/routes.py`), producing the macOS
`objc[PID]: Class AVF* is implemented in both ...` duplicate-class
warning on every `sol` CLI invocation that doesn't decode video.

Move both imports into `VideoProcessor.process()` — the only call site
for `av.*` and the aruco helpers. Add a rationale comment so a future
refactor doesn't hoist them back.

Regression test asserts that importing `CATEGORIES` from `observe.describe`
does not pull `av` or `cv2` into `sys.modules`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+30 -2
+8 -2
observe/describe.py
··· 28 28 from pathlib import Path 29 29 from typing import List, Optional 30 30 31 - import av 32 31 from PIL import Image 33 32 34 - from observe.aruco import detect_markers, mask_convey_region, polygon_area 35 33 from observe.extract import DEFAULT_MAX_EXTRACTIONS, select_frames_for_extraction 36 34 from observe.utils import get_segment_key 37 35 from think.callosum import callosum_send ··· 221 219 """ 222 220 # Cache for the last qualified frame hash 223 221 last_hash: Optional[int] = None 222 + 223 + # Imports deferred: av (PyAV) and cv2 (via observe.aruco) bundle 224 + # mismatched libavdevice majors. Keeping them out of module scope 225 + # avoids the macOS ObjC duplicate-class warning on every caller that 226 + # only needs CATEGORIES (see observe/screen.py). 227 + import av 228 + 229 + from observe.aruco import detect_markers, mask_convey_region, polygon_area 224 230 225 231 try: 226 232 with av.open(str(self.video_path)) as container:
+22
tests/test_describe_lazy_imports.py
··· 1 + # SPDX-License-Identifier: AGPL-3.0-only 2 + # Copyright (c) 2026 sol pbc 3 + 4 + import sys 5 + 6 + 7 + def test_importing_categories_does_not_load_av_or_cv2(monkeypatch): 8 + for mod in ( 9 + "av", 10 + "cv2", 11 + "observe.aruco", 12 + "observe.describe", 13 + "observe.screen", 14 + ): 15 + monkeypatch.delitem(sys.modules, mod, raising=False) 16 + 17 + from observe.describe import CATEGORIES 18 + 19 + assert isinstance(CATEGORIES, dict) 20 + assert len(CATEGORIES) > 0 21 + assert "av" not in sys.modules 22 + assert "cv2" not in sys.modules