Skip to content

Commit

Permalink
Merge pull request #1562 from hbldh/release/0.22.0
Browse files Browse the repository at this point in the history
Release/0.22.0
  • Loading branch information
dlech authored May 4, 2024
2 parents 24f29b2 + a87a328 commit 93d88e0
Show file tree
Hide file tree
Showing 56 changed files with 833 additions and 493 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/format_and_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jobs:
uses: actions/setup-python@v4
- name: Install development dependencies
run: pipx run poetry install --only docs,lint
- name: Check import sort with isort
run: pipx run poetry run isort . --check --diff
- name: Check code formatting with black
run: pipx run poetry run black . --check --diff
- name: Lint with flake8
Expand Down
4 changes: 2 additions & 2 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ sphinx:
configuration: docs/conf.py

# If using Sphinx, optionally build your docs in additional formats such as PDF
# formats:
# - pdf
formats:
- pdf

# Optionally declare the Python requirements required to build your docs
python:
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
},
},
"black-formatter.importStrategy": "fromEnvironment",
Expand Down
2 changes: 2 additions & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Contributors
* Kyle J. Williams <kyle@kjwill.tech>
* Edward Betts <edward@4angle.com>
* Robbe Gaeremynck <robbe.gaeremynck@outlook.com>
* David Johansen <davejohansen@gmail.com>
* JP Hutchins <jphutchins@gmail.com>

Sponsors
--------
Expand Down
32 changes: 31 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,35 @@ and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0
`Unreleased`_
=============

`0.22.0`_ (2024-04-04)
======================

Added
-----
* Added ``BleakCharacteristicNotFoundError`` which is raised if a device does not support a characteristic.
* Added utility function to work around ``pywin32`` setting threading model to STA on Windows.

Changed
-------
* Updated PyObjC dependency on macOS to v10.x.
* Updated missing Bluetooth SIG characteristics and service UUIDs.
* Updated ``BlueZManager`` to remove empty interfaces from `_properties` during InterfacesRemoved message.
* Updated PyWinRT dependency to v2. Fixes #1529.
* Raise exception when trying to scan while in a single-treaded apartment (STA) on Windows. Fixes #1132.

Fixed
-----
* Fixed BlueZ version in passive scanning error message. Fixes #1433.
* Fixed mypy requiring ``Unpack[ExtraArgs]`` that were intended to be optional. Fixes #1487.
* Fixed ``KeyError`` in BlueZ ``is_connected()`` and ``get_global_bluez_manager()`` when device is not present. Fixes #1507.
* Fixed BlueZ ``_wait_removed`` completion on invalid object path. Fixes #1489.
* Fixed rare unhandled exception when scanning on macOS when using ``use_bdaddr``. Fixes #1523.
* Fixed scanning silently failing on Windows when Bluetooth is off. Fixes #1535.
* Fixed using wrong value for ``tx_power`` in Android backend. Fixes #1532.
* Fixed 4-character UUIDs not working on ``BleakClient.*_gatt_char`` methods. Fixes #1498.
* Fixed race condition with getting max PDU size on Windows. Fixes #1497.
* Fixed filtering advertisement data by service UUID when multiple apps are scanning. Fixes #1534.

`0.21.1`_ (2023-09-08)
======================

Expand Down Expand Up @@ -985,7 +1014,8 @@ Fixed
* Bleak created.


.. _Unreleased: https://github.com/hbldh/bleak/compare/v0.21.1...develop
.. _Unreleased: https://github.com/hbldh/bleak/compare/v0.22.0...develop
.. _0.22.0: https://github.com/hbldh/bleak/compare/v0.21.1...v0.22.0
.. _0.21.1: https://github.com/hbldh/bleak/compare/v0.21.0...v0.21.1
.. _0.21.0: https://github.com/hbldh/bleak/compare/v0.20.2...v0.21.0
.. _0.20.2: https://github.com/hbldh/bleak/compare/v0.20.1...v0.20.2
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ and your favorite text editor. And Python of course.

5. When you're done making changes, check that your changes pass linting and the tests::

$ poetry run isort .
$ poetry run black .
$ poetry run flake8
$ poetry run pytest
Expand Down
84 changes: 47 additions & 37 deletions bleak/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import os
import sys
import uuid
from types import TracebackType
from typing import (
TYPE_CHECKING,
AsyncGenerator,
Expand All @@ -22,6 +23,7 @@
Dict,
Iterable,
List,
Literal,
Optional,
Set,
Tuple,
Expand All @@ -31,7 +33,6 @@
overload,
)
from warnings import warn
from typing import Literal

if sys.version_info < (3, 12):
from typing_extensions import Buffer
Expand All @@ -45,7 +46,6 @@
from asyncio import timeout as async_timeout
from typing import Unpack


from .backends.characteristic import BleakGATTCharacteristic
from .backends.client import BaseBleakClient, get_platform_client_backend_type
from .backends.device import BLEDevice
Expand All @@ -57,7 +57,7 @@
get_platform_scanner_backend_type,
)
from .backends.service import BleakGATTServiceCollection
from .exc import BleakError
from .exc import BleakCharacteristicNotFoundError, BleakError
from .uuids import normalize_uuid_str

if TYPE_CHECKING:
Expand Down Expand Up @@ -121,11 +121,11 @@ class BleakScanner:
are matching a device based on other data but want to display the local
name to the user, be sure to wait for ``adv_data.local_name is not None``.
.. versionchanged:: 0.15.0
.. versionchanged:: 0.15
``detection_callback``, ``service_uuids`` and ``scanning_mode`` are no longer keyword-only.
Added ``bluez`` parameter.
.. versionchanged:: 0.18.0
.. versionchanged:: 0.18
No longer is alias for backend type and no longer inherits from :class:`BaseBleakScanner`.
Added ``backend`` parameter.
"""
Expand All @@ -140,7 +140,7 @@ def __init__(
cb: CBScannerArgs = {},
backend: Optional[Type[BaseBleakScanner]] = None,
**kwargs,
):
) -> None:
PlatformBleakScanner = (
get_platform_scanner_backend_type() if backend is None else backend
)
Expand All @@ -154,11 +154,16 @@ def __init__(
**kwargs,
)

async def __aenter__(self):
async def __aenter__(self) -> BleakScanner:
await self._backend.start()
return self

async def __aexit__(self, exc_type, exc_val, exc_tb):
async def __aexit__(
self,
exc_type: Type[BaseException],
exc_val: BaseException,
exc_tb: TracebackType,
) -> None:
await self._backend.stop()

def register_detection_callback(
Expand Down Expand Up @@ -193,15 +198,15 @@ def register_detection_callback(
unregister = self._backend.register_detection_callback(callback)
setattr(self, "_unregister_", unregister)

async def start(self):
async def start(self) -> None:
"""Start scanning for devices"""
await self._backend.start()

async def stop(self):
async def stop(self) -> None:
"""Stop scanning for devices"""
await self._backend.stop()

def set_scanning_filter(self, **kwargs):
def set_scanning_filter(self, **kwargs) -> None:
"""
Set scanning filter for the BleakScanner.
Expand Down Expand Up @@ -245,7 +250,7 @@ async def advertisement_data(
finally:
unregister_callback()

class ExtraArgs(TypedDict):
class ExtraArgs(TypedDict, total=False):
"""
Keyword args from :class:`~bleak.BleakScanner` that can be passed to
other convenience methods.
Expand Down Expand Up @@ -281,15 +286,13 @@ class ExtraArgs(TypedDict):
@classmethod
async def discover(
cls, timeout: float = 5.0, *, return_adv: Literal[False] = False, **kwargs
) -> List[BLEDevice]:
...
) -> List[BLEDevice]: ...

@overload
@classmethod
async def discover(
cls, timeout: float = 5.0, *, return_adv: Literal[True], **kwargs
) -> Dict[str, Tuple[BLEDevice, AdvertisementData]]:
...
) -> Dict[str, Tuple[BLEDevice, AdvertisementData]]: ...

@classmethod
async def discover(
Expand All @@ -311,7 +314,7 @@ async def discover(
The value of :attr:`discovered_devices_and_advertisement_data` if
``return_adv`` is ``True``, otherwise the value of :attr:`discovered_devices`.
.. versionchanged:: 0.19.0
.. versionchanged:: 0.19
Added ``return_adv`` parameter.
"""
async with cls(**kwargs) as scanner:
Expand Down Expand Up @@ -344,7 +347,7 @@ def discovered_devices_and_advertisement_data(
``discovered_devices_and_advertisement_data.values()`` to just get the
values instead.
.. versionadded:: 0.19.0
.. versionadded:: 0.19
"""
return self._backend.seen_devices

Expand Down Expand Up @@ -402,7 +405,7 @@ async def find_device_by_name(
Returns:
The ``BLEDevice`` sought or ``None`` if not detected.
.. versionadded:: 0.20.0
.. versionadded:: 0.20
"""
return await cls.find_device_by_filter(
lambda d, ad: ad.local_name == name,
Expand Down Expand Up @@ -495,10 +498,10 @@ class BleakClient:
This is known to cause problems when trying to connect to multiple
devices at the same time.
.. versionchanged:: 0.15.0
.. versionchanged:: 0.15
``disconnected_callback`` is no longer keyword-only. Added ``winrt`` parameter.
.. versionchanged:: 0.18.0
.. versionchanged:: 0.18
No longer is alias for backend type and no longer inherits from :class:`BaseBleakClient`.
Added ``backend`` parameter.
"""
Expand All @@ -513,19 +516,21 @@ def __init__(
winrt: WinRTClientArgs = {},
backend: Optional[Type[BaseBleakClient]] = None,
**kwargs,
):
) -> None:
PlatformBleakClient = (
get_platform_client_backend_type() if backend is None else backend
)

self._backend = PlatformBleakClient(
address_or_ble_device,
disconnected_callback=None
if disconnected_callback is None
else functools.partial(disconnected_callback, self),
services=None
if services is None
else set(map(normalize_uuid_str, services)),
disconnected_callback=(
None
if disconnected_callback is None
else functools.partial(disconnected_callback, self)
),
services=(
None if services is None else set(map(normalize_uuid_str, services))
),
timeout=timeout,
winrt=winrt,
**kwargs,
Expand Down Expand Up @@ -553,19 +558,24 @@ def mtu_size(self) -> int:
"""
return self._backend.mtu_size

def __str__(self):
def __str__(self) -> str:
return f"{self.__class__.__name__}, {self.address}"

def __repr__(self):
def __repr__(self) -> str:
return f"<{self.__class__.__name__}, {self.address}, {type(self._backend)}>"

# Async Context managers

async def __aenter__(self):
async def __aenter__(self) -> BleakClient:
await self.connect()
return self

async def __aexit__(self, exc_type, exc_val, exc_tb):
async def __aexit__(
self,
exc_type: Type[BaseException],
exc_val: BaseException,
exc_tb: TracebackType,
) -> None:
await self.disconnect()

# Connectivity methods
Expand Down Expand Up @@ -766,7 +776,7 @@ async def write_gatt_char(
characteristic = self.services.get_characteristic(char_specifier)

if not characteristic:
raise BleakError("Characteristic {char_specifier} was not found!")
raise BleakCharacteristicNotFoundError(char_specifier)

if response is None:
# if not specified, prefer write-with-response over write-without-
Expand Down Expand Up @@ -806,7 +816,7 @@ def callback(sender: BleakGATTCharacteristic, data: bytearray):
function or async function.
.. versionchanged:: 0.18.0
.. versionchanged:: 0.18
The first argument of the callback is now a :class:`BleakGATTCharacteristic`
instead of an ``int``.
"""
Expand All @@ -819,11 +829,11 @@ def callback(sender: BleakGATTCharacteristic, data: bytearray):
characteristic = char_specifier

if not characteristic:
raise BleakError(f"Characteristic {char_specifier} not found!")
raise BleakCharacteristicNotFoundError(char_specifier)

if inspect.iscoroutinefunction(callback):

def wrapped_callback(data):
def wrapped_callback(data: bytearray) -> None:
task = asyncio.create_task(callback(characteristic, data))
_background_tasks.add(task)
task.add_done_callback(_background_tasks.discard)
Expand Down Expand Up @@ -893,7 +903,7 @@ def discover(*args, **kwargs):
return BleakScanner.discover(*args, **kwargs)


def cli():
def cli() -> None:
import argparse

parser = argparse.ArgumentParser(
Expand Down
3 changes: 1 addition & 2 deletions bleak/assigned_numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
See <https://www.bluetooth.com/specifications/assigned-numbers/>.
"""


from enum import IntEnum


Expand All @@ -17,7 +16,7 @@ class AdvertisementDataType(IntEnum):
`Source <https://btprodspecificationrefs.blob.core.windows.net/assigned-numbers/Assigned%20Number%20Types/Generic%20Access%20Profile.pdf>`.
.. versionadded:: 0.15.0
.. versionadded:: 0.15
"""

FLAGS = 0x01
Expand Down
Loading

0 comments on commit 93d88e0

Please sign in to comment.