From a6d1d1e5979b3d0174c2d6c59b24e83eda786165 Mon Sep 17 00:00:00 2001 From: Christian Manivong Date: Fri, 23 Oct 2026 08:57:52 +0200 Subject: [PATCH] fix: what bandit and the remaining lint rules found - open() raises ConnectionException from the SoCo error (B904), so the cause stays attached. - _check_wired_connection: the except Exception: pass (B110) now logs at debug level, so a swallowed failure leaves a trace. A module logger is new. - nosec for the empty password default (B107): a Sonos speaker takes no login, the argument exists for NAPALM's constructor signature. - tests: raise AssertionError instead of assert False (B011). --- napalm_sonos/sonos_driver.py | 11 ++++++++--- tests/test_sonos.py | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/napalm_sonos/sonos_driver.py b/napalm_sonos/sonos_driver.py index 160e09f..dbf7992 100644 --- a/napalm_sonos/sonos_driver.py +++ b/napalm_sonos/sonos_driver.py @@ -1,5 +1,6 @@ from __future__ import annotations +import logging import socket from typing import Any @@ -13,6 +14,8 @@ SoCo library, exposing NAPALM standard methods alongside Sonos-specific media-playback controls. """ +logger = logging.getLogger(__name__) + class SonosDriver(MediaDriver): """NAPALM driver for controlling Sonos speakers. @@ -33,7 +36,9 @@ class SonosDriver(MediaDriver): FingerprintRule("rincon", weight=5.0), ] - def __init__( + # A Sonos speaker takes no login: username and password exist only for NAPALM's + # constructor signature, and the empty default is no credential. + def __init__( # nosec B107 self, hostname: str, username: str = "", @@ -60,7 +65,7 @@ class SonosDriver(MediaDriver): self._speaker_info = self._device.get_speaker_info() except Exception as e: # Broad catch: SoCo can raise a variety of transport/XML errors - raise ConnectionException(f"Cannot connect to Sonos at {self.hostname}: {e}") + raise ConnectionException(f"Cannot connect to Sonos at {self.hostname}: {e}") from e def close(self) -> None: """Close the connection to the Sonos speaker.""" @@ -112,7 +117,7 @@ class SonosDriver(MediaDriver): return wifimode in ("0", "", None) except Exception: # Broad catch: SoCo device_properties may fail for many reasons - pass + logger.debug("Sonos device properties: ignored", exc_info=True) return False def get_interfaces(self) -> dict[str, dict[str, Any]]: diff --git a/tests/test_sonos.py b/tests/test_sonos.py index f3106b8..35ba906 100644 --- a/tests/test_sonos.py +++ b/tests/test_sonos.py @@ -52,7 +52,7 @@ class TestSonosDriver: mock_soco.side_effect = Exception("Connection refused") try: driver.open() - assert False, "Expected ConnectionException" + raise AssertionError("Expected ConnectionException") except ConnectionException: pass