0.4.12
No breaking changes.
session.py: fixed a thread-safety race betweenSHCPollingThread
(sole mutator of_devices_by_id/_services_by_device_id) and cross-thread
readers (devicesproperty,device()) — a device add/remove racing a
concurrent read could raise an unhandledRuntimeError: dictionary changed size during iterationin the reading thread. Addedself._devices_lock
(threading.RLock), held only for the actual dict mutation/snapshot —
never across I/O (get_device_services) or subscriber-callback invocation,
to avoid stalling readers/writers or risking deadlock. Found via a targeted
bug-hunt round; not tied to a user report.