Skip to content

Commit a9ac5b4

Browse files
committed
backends: consolidate platform detection functions
Consolidate get_platform_client_backend_type() and get_platform_scanner_backend_type() into a single get_backend() function that returns both types. This reduces code duplication and makes it easier to maintain platform detection logic in one place.
1 parent a4a8755 commit a9ac5b4

File tree

6 files changed

+87
-95
lines changed

6 files changed

+87
-95
lines changed

CHANGELOG.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0
1010
`Unreleased`_
1111
=============
1212

13+
Changed
14+
-------
15+
- Changed internal backend detection to use a single common function.
16+
1317
`1.1.1`_ (2025-09-07)
1418
=====================
1519

bleak/__init__.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@
3333
from bleak.args.bluez import BlueZScannerArgs
3434
from bleak.args.corebluetooth import CBScannerArgs, CBStartNotifyArgs
3535
from bleak.args.winrt import WinRTClientArgs
36+
from bleak.backends import get_backend
3637
from bleak.backends.characteristic import BleakGATTCharacteristic
37-
from bleak.backends.client import BaseBleakClient, get_platform_client_backend_type
38+
from bleak.backends.client import BaseBleakClient
3839
from bleak.backends.descriptor import BleakGATTDescriptor
3940
from bleak.backends.device import BLEDevice
4041
from bleak.backends.scanner import (
4142
AdvertisementData,
4243
AdvertisementDataCallback,
4344
AdvertisementDataFilter,
4445
BaseBleakScanner,
45-
get_platform_scanner_backend_type,
4646
)
4747
from bleak.backends.service import BleakGATTServiceCollection
4848
from bleak.exc import BleakCharacteristicNotFoundError, BleakError
@@ -124,7 +124,7 @@ def __init__(
124124
**kwargs: Any,
125125
) -> None:
126126
PlatformBleakScanner = (
127-
get_platform_scanner_backend_type() if backend is None else backend
127+
get_backend().scanner_type if backend is None else backend
128128
)
129129

130130
self._backend = PlatformBleakScanner(
@@ -490,9 +490,7 @@ def __init__(
490490
backend: Optional[type[BaseBleakClient]] = None,
491491
**kwargs: Any,
492492
) -> None:
493-
PlatformBleakClient = (
494-
get_platform_client_backend_type() if backend is None else backend
495-
)
493+
PlatformBleakClient = get_backend().client_type if backend is None else backend
496494

497495
self._backend = PlatformBleakClient(
498496
address_or_ble_device,

bleak/backends/__init__.py

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,76 @@
1-
# -*- coding: utf-8 -*-
2-
# Created on 2017-11-19 by hbldh <[email protected]>
3-
"""
4-
__init__.py
5-
"""
1+
import os
2+
import platform
3+
import sys
4+
from dataclasses import dataclass
5+
6+
from bleak.backends.client import BaseBleakClient
7+
from bleak.backends.scanner import BaseBleakScanner
8+
from bleak.exc import BleakError
9+
10+
11+
@dataclass(frozen=True)
12+
class BleakBackendProvider:
13+
client_type: type[BaseBleakClient]
14+
scanner_type: type[BaseBleakScanner]
15+
16+
17+
def get_backend() -> BleakBackendProvider:
18+
"""
19+
Gets the platform-specific backend provider.
20+
"""
21+
if sys.platform == "android" and os.environ.get("P4A_BOOTSTRAP") is not None:
22+
from bleak.backends.p4android.client import BleakClientP4Android
23+
from bleak.backends.p4android.scanner import BleakScannerP4Android
24+
25+
return BleakBackendProvider(
26+
client_type=BleakClientP4Android,
27+
scanner_type=BleakScannerP4Android,
28+
)
29+
30+
if sys.platform == "linux":
31+
from bleak.backends.bluezdbus.client import BleakClientBlueZDBus
32+
from bleak.backends.bluezdbus.scanner import BleakScannerBlueZDBus
33+
34+
return BleakBackendProvider(
35+
client_type=BleakClientBlueZDBus,
36+
scanner_type=BleakScannerBlueZDBus,
37+
)
38+
39+
if sys.platform == "ios" and "Pythonista3.app" in sys.executable:
40+
# Must be resolved before checking for "Darwin" (macOS),
41+
# as both the Pythonista app for iOS and macOS
42+
# return "Darwin" from platform.system()
43+
try:
44+
from bleak_pythonista import (
45+
BleakClientPythonistaCB,
46+
BleakScannerPythonistaCB,
47+
)
48+
49+
return BleakBackendProvider(
50+
client_type=BleakClientPythonistaCB,
51+
scanner_type=BleakScannerPythonistaCB,
52+
)
53+
except ImportError as e:
54+
raise ImportError(
55+
"Ensure you have `bleak-pythonista` package installed."
56+
) from e
57+
58+
if sys.platform == "darwin":
59+
from bleak.backends.corebluetooth.client import BleakClientCoreBluetooth
60+
from bleak.backends.corebluetooth.scanner import BleakScannerCoreBluetooth
61+
62+
return BleakBackendProvider(
63+
client_type=BleakClientCoreBluetooth,
64+
scanner_type=BleakScannerCoreBluetooth,
65+
)
66+
67+
if sys.platform == "win32":
68+
from bleak.backends.winrt.client import BleakClientWinRT
69+
from bleak.backends.winrt.scanner import BleakScannerWinRT
70+
71+
return BleakBackendProvider(
72+
client_type=BleakClientWinRT,
73+
scanner_type=BleakScannerWinRT,
74+
)
75+
76+
raise BleakError(f"Unsupported platform: {platform.system()}")

bleak/backends/client.py

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -207,43 +207,3 @@ async def stop_notify(self, characteristic: BleakGATTCharacteristic) -> None:
207207
208208
"""
209209
raise NotImplementedError()
210-
211-
212-
def get_platform_client_backend_type() -> type[BaseBleakClient]:
213-
"""
214-
Gets the platform-specific :class:`BaseBleakClient` type.
215-
"""
216-
if os.environ.get("P4A_BOOTSTRAP") is not None:
217-
from bleak.backends.p4android.client import BleakClientP4Android
218-
219-
return BleakClientP4Android
220-
221-
if platform.system() == "Linux":
222-
from bleak.backends.bluezdbus.client import BleakClientBlueZDBus
223-
224-
return BleakClientBlueZDBus
225-
226-
if sys.platform == "ios" and "Pythonista3.app" in sys.executable:
227-
# Must be resolved before checking for "Darwin" (macOS),
228-
# as both the Pythonista app for iOS and macOS
229-
# return "Darwin" from platform.system()
230-
try:
231-
from bleak_pythonista import BleakClientPythonistaCB
232-
233-
return BleakClientPythonistaCB
234-
except ImportError as e:
235-
raise ImportError(
236-
"Ensure you have `bleak-pythonista` package installed."
237-
) from e
238-
239-
if platform.system() == "Darwin":
240-
from bleak.backends.corebluetooth.client import BleakClientCoreBluetooth
241-
242-
return BleakClientCoreBluetooth
243-
244-
if platform.system() == "Windows":
245-
from bleak.backends.winrt.client import BleakClientWinRT
246-
247-
return BleakClientWinRT
248-
249-
raise BleakError(f"Unsupported platform: {platform.system()}")

bleak/backends/scanner.py

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -280,43 +280,3 @@ async def start(self) -> None:
280280
async def stop(self) -> None:
281281
"""Stop scanning for devices"""
282282
raise NotImplementedError()
283-
284-
285-
def get_platform_scanner_backend_type() -> type[BaseBleakScanner]:
286-
"""
287-
Gets the platform-specific :class:`BaseBleakScanner` type.
288-
"""
289-
if os.environ.get("P4A_BOOTSTRAP") is not None:
290-
from bleak.backends.p4android.scanner import BleakScannerP4Android
291-
292-
return BleakScannerP4Android
293-
294-
if platform.system() == "Linux":
295-
from bleak.backends.bluezdbus.scanner import BleakScannerBlueZDBus
296-
297-
return BleakScannerBlueZDBus
298-
299-
if sys.platform == "ios" and "Pythonista3.app" in sys.executable:
300-
# Must be resolved before checking for "Darwin" (macOS),
301-
# as both the Pythonista app for iOS and macOS
302-
# return "Darwin" from platform.system()
303-
try:
304-
from bleak_pythonista import BleakScannerPythonistaCB
305-
306-
return BleakScannerPythonistaCB
307-
except ImportError as e:
308-
raise ImportError(
309-
"Ensure you have `bleak-pythonista` package installed."
310-
) from e
311-
312-
if platform.system() == "Darwin":
313-
from bleak.backends.corebluetooth.scanner import BleakScannerCoreBluetooth
314-
315-
return BleakScannerCoreBluetooth
316-
317-
if platform.system() == "Windows":
318-
from bleak.backends.winrt.scanner import BleakScannerWinRT
319-
320-
return BleakScannerWinRT
321-
322-
raise BleakError(f"Unsupported platform: {platform.system()}")

tests/test_platform_detection.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55

66
import platform
77

8-
from bleak.backends.client import get_platform_client_backend_type
9-
from bleak.backends.scanner import get_platform_scanner_backend_type
8+
from bleak.backends import get_backend
109

1110

1211
def test_platform_detection():
1312
"""Test by importing the client and assert correct client by OS."""
1413

15-
client_backend_type = get_platform_client_backend_type()
16-
scanner_backend_type = get_platform_scanner_backend_type()
14+
client_backend_type = get_backend().client_type
15+
scanner_backend_type = get_backend().scanner_type
1716

1817
if platform.system() == "Linux":
1918
assert client_backend_type.__name__ == "BleakClientBlueZDBus"

0 commit comments

Comments
 (0)