Skip to content

Commit

Permalink
Merge pull request #1116 from hbldh/release/0.19.2
Browse files Browse the repository at this point in the history
Release/0.19.2
  • Loading branch information
dlech authored Nov 6, 2022
2 parents 433d2a6 + 4371cb4 commit f3a66f8
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 9 deletions.
12 changes: 11 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0
`Unreleased`_
=============

`0.19.2`_ (2022-11-06)
======================

Fixed
------
* Fixed crash when getting services in WinRT backend in Python 3.11. Fixes #1112.
* Fixed cache mode when retrying get services in WinRT backend. Merged #1102.
* Fixed ``KeyError`` crash in BlueZ backend when removing non-existent property. Fixes #1107.

`0.19.1`_ (2022-10-29)
======================

Expand Down Expand Up @@ -850,7 +859,8 @@ Fixed
* Bleak created.


.. _Unreleased: https://github.com/hbldh/bleak/compare/v0.19.1...develop
.. _Unreleased: https://github.com/hbldh/bleak/compare/v0.19.2...develop
.. _0.19.2: https://github.com/hbldh/bleak/compare/v0.19.1...v0.19.2
.. _0.19.1: https://github.com/hbldh/bleak/compare/v0.19.0...v0.19.1
.. _0.19.0: https://github.com/hbldh/bleak/compare/v0.18.1...v0.19.0
.. _0.18.1: https://github.com/hbldh/bleak/compare/v0.18.0...v0.18.1
Expand Down
7 changes: 6 additions & 1 deletion bleak/backends/bluezdbus/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,12 @@ def _parse_msg(self, message: Message):
self_interface.update(unpack_variants(changed))

for name in invalidated:
del self_interface[name]
try:
del self_interface[name]
except KeyError:
# sometimes there BlueZ tries to remove properties
# that were never added
pass

# then call any callbacks so they will be called with the
# updated state
Expand Down
82 changes: 76 additions & 6 deletions bleak/backends/winrt/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
"""

import asyncio
import functools
import logging
import sys
import uuid
import warnings
from ctypes import pythonapi
from typing import Any, Dict, List, Optional, Sequence, Union, cast

import async_timeout
Expand Down Expand Up @@ -44,11 +46,15 @@
DevicePairingResultStatus,
DeviceUnpairingResultStatus,
)
from bleak_winrt.windows.foundation import EventRegistrationToken
from bleak_winrt.windows.foundation import (
AsyncStatus,
EventRegistrationToken,
IAsyncOperation,
)
from bleak_winrt.windows.storage.streams import Buffer

from ... import BleakScanner
from ...exc import PROTOCOL_ERROR_CODES, BleakError, BleakDeviceNotFoundError
from ...exc import PROTOCOL_ERROR_CODES, BleakDeviceNotFoundError, BleakError
from ..characteristic import BleakGATTCharacteristic
from ..client import BaseBleakClient, NotifyCallback
from ..device import BLEDevice
Expand Down Expand Up @@ -250,7 +256,7 @@ async def connect(self, **kwargs) -> bool:

def handle_services_changed():
if not self._services_changed_events:
logger.warn("%s: unhandled services changed event", self.address)
logger.warning("%s: unhandled services changed event", self.address)
else:
for event in self._services_changed_events:
event.set()
Expand Down Expand Up @@ -568,7 +574,10 @@ async def get_services(self, **kwargs) -> BleakGATTServiceCollection:
services_changed_event.wait()
)
self._services_changed_events.append(services_changed_event)
get_services_task = self._requester.get_gatt_services_async(*args)

get_services_task = FutureLike(
self._requester.get_gatt_services_async(*args)
)

try:
await asyncio.wait(
Expand All @@ -587,10 +596,10 @@ async def get_services(self, **kwargs) -> BleakGATTServiceCollection:
"%s: restarting get services due to services changed event",
self.address,
)
args = [BluetoothCacheMode.UNCACHED]
args = [BluetoothCacheMode.CACHED]

services: Sequence[GattDeviceService] = _ensure_success(
get_services_task.get_results(),
get_services_task.result(),
"services",
"Could not get GATT services",
)
Expand Down Expand Up @@ -885,3 +894,64 @@ async def stop_notify(

event_handler_token = self._notification_callbacks.pop(characteristic.handle)
characteristic.obj.remove_value_changed(event_handler_token)


class FutureLike:
"""
Wraps a WinRT IAsyncOperation in a "future-like" object so that it can
be passed to Python APIs.
Needed until https://github.com/pywinrt/pywinrt/issues/14
"""

_asyncio_future_blocking = True

def __init__(self, async_result: IAsyncOperation) -> None:
self._async_result = async_result
self._callbacks = []
self._loop = asyncio.get_running_loop()

def call_callbacks(op: IAsyncOperation, status: AsyncStatus):
for c in self._callbacks:
c(self)

async_result.completed = functools.partial(
self._loop.call_soon_threadsafe, call_callbacks
)

def result(self) -> Any:
return self._async_result.get_results()

def done(self) -> bool:
return self._async_result.status != AsyncStatus.STARTED

def cancelled(self) -> bool:
return self._async_result.status == AsyncStatus.CANCELED

def add_done_callback(self, callback, *, context=None) -> None:
self._callbacks.append(callback)

def remove_done_callback(self, callback) -> None:
self._callbacks.remove(callback)

def cancel(self, msg=None) -> bool:
if self._async_result.status != AsyncStatus.STARTED:
return False
self._async_result.cancel()
return True

def exception(self) -> Optional[Exception]:
if self._async_result.status == AsyncStatus.STARTED:
raise asyncio.InvalidStateError
if self._async_result.status == AsyncStatus.COMPLETED:
return None
if self._async_result.status == AsyncStatus.CANCELED:
raise asyncio.CancelledError
if self._async_result.status == AsyncStatus.ERROR:
try:
pythonapi.PyErr_SetFromWindowsErr(self._async_result.error_code)
except OSError as e:
return e

def get_loop(self) -> asyncio.AbstractEventLoop:
return self._loop
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "bleak"
version = "0.19.1"
version = "0.19.2"
description = "Bluetooth Low Energy platform Agnostic Klient"
authors = ["Henrik Blidh <henrik.blidh@nedomkull.com>"]
license = "MIT"
Expand Down

0 comments on commit f3a66f8

Please sign in to comment.