Skip to content

Commit d0fae7d

Browse files
authored
feat: improve performance of dispatching discovery info to subclasses (#181)
1 parent 5a7f11d commit d0fae7d

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

src/habluetooth/manager.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ cdef class BluetoothManager:
5656
cdef public dict _adapter_sources
5757
cdef public dict _allocations
5858
cdef public dict _scanner_registration_callbacks
59+
cdef public object _subclass_discover_info
5960

6061
@cython.locals(stale_seconds=double)
6162
cdef bint _prefer_previous_adv_from_different_source(

src/habluetooth/manager.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ class BluetoothManager:
135135
"_unavailable_callbacks",
136136
"shutdown",
137137
"slot_manager",
138+
"_subclass_discover_info",
138139
)
139140

140141
def __init__(
@@ -184,6 +185,17 @@ def __init__(
184185
self._scanner_registration_callbacks: dict[
185186
str | None, set[Callable[[HaScannerRegistration], None]]
186187
] = {}
188+
self._subclass_discover_info = self._discover_service_info
189+
if (
190+
self._discover_service_info.__func__ # type: ignore[attr-defined]
191+
is BluetoothManager._discover_service_info
192+
):
193+
_LOGGER.warning(
194+
"%s: does not implement _discover_service_info, "
195+
"subclasses must implement this method to consume "
196+
"discovery data",
197+
type(self).__name__,
198+
)
187199

188200
@property
189201
def supports_passive_scan(self) -> bool:
@@ -639,7 +651,7 @@ def scanner_adv_received(self, service_info: BluetoothServiceInfoBleak) -> None:
639651
bleak_callback, service_info.device, advertisement_data
640652
)
641653

642-
self._discover_service_info(service_info)
654+
self._subclass_discover_info(service_info)
643655

644656
def _discover_service_info(self, service_info: BluetoothServiceInfoBleak) -> None:
645657
"""

tests/test_manager.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,3 +1214,39 @@ def _switchbot_device_unavailable_callback(
12141214
get_manager().async_get_fallback_availability_interval("44:44:33:11:23:12")
12151215
is None
12161216
)
1217+
1218+
1219+
@pytest.mark.asyncio
1220+
async def test_subclassing_bluetooth_manager(caplog: pytest.LogCaptureFixture) -> None:
1221+
"""Test subclassing BluetoothManager."""
1222+
slot_manager = BleakSlotManager()
1223+
bluetooth_adapters = FakeBluetoothAdapters()
1224+
1225+
class TestBluetoothManager(BluetoothManager):
1226+
"""
1227+
Test class for BluetoothManager.
1228+
1229+
This class implements _discover_service_info.
1230+
"""
1231+
1232+
def _discover_service_info(
1233+
self, service_info: BluetoothServiceInfoBleak
1234+
) -> None:
1235+
"""
1236+
Discover a new service info.
1237+
1238+
This method is intended to be overridden by subclasses.
1239+
"""
1240+
1241+
TestBluetoothManager(bluetooth_adapters, slot_manager)
1242+
assert "does not implement _discover_service_info" not in caplog.text
1243+
1244+
class TestBluetoothManager2(BluetoothManager):
1245+
"""
1246+
Test class for BluetoothManager.
1247+
1248+
This class does not implement _discover_service_info.
1249+
"""
1250+
1251+
TestBluetoothManager2(bluetooth_adapters, slot_manager)
1252+
assert "does not implement _discover_service_info" in caplog.text

0 commit comments

Comments
 (0)