From 528af0d33852ae64d0f9efb277bc1c5b789bbfb3 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Sat, 19 Oct 2024 07:46:37 -0700 Subject: [PATCH 1/3] remove test for deprecated Python 3.8 and add 3.13 --- .github/workflows/code-check.yml | 2 +- .github/workflows/python-build-test.yml | 4 ++-- docs/mkdocs/src/getting_started.md | 4 +--- docs/mkdocs/src/index.md | 2 +- docs/mkdocs/src/platforms/index.md | 2 +- environment.yml | 2 +- 6 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/code-check.yml b/.github/workflows/code-check.yml index 37fb816..45cf7da 100644 --- a/.github/workflows/code-check.yml +++ b/.github/workflows/code-check.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] fail-fast: false steps: diff --git a/.github/workflows/python-build-test.yml b/.github/workflows/python-build-test.yml index 230779f..ccb1030 100644 --- a/.github/workflows/python-build-test.yml +++ b/.github/workflows/python-build-test.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] fail-fast: false steps: @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] rust-version: [ "1.76.0", "stable" ] fail-fast: false steps: diff --git a/docs/mkdocs/src/getting_started.md b/docs/mkdocs/src/getting_started.md index b2063d1..476ecc0 100644 --- a/docs/mkdocs/src/getting_started.md +++ b/docs/mkdocs/src/getting_started.md @@ -3,9 +3,7 @@ GETTING STARTED WITH BUMBLE # Prerequisites -You need Python 3.8 or above. Python >= 3.9 is recommended, but 3.8 should be sufficient if -necessary (there may be some optional functionality that will not work on some platforms with -python 3.8). +You need Python 3.9 or above. Visit the [Python site](https://www.python.org/) for instructions on how to install Python for your platform. Throughout the documentation, when shell commands are shown, it is assumed that you can diff --git a/docs/mkdocs/src/index.md b/docs/mkdocs/src/index.md index aae6e54..8c057c8 100644 --- a/docs/mkdocs/src/index.md +++ b/docs/mkdocs/src/index.md @@ -31,7 +31,7 @@ Some of the configurations that may be useful: See the [use cases page](use_cases/index.md) for more use cases. -The project is implemented in Python (Python >= 3.8 is required). A number of APIs for functionality that is inherently I/O bound is implemented in terms of python coroutines with async IO. This means that all of the concurrent tasks run in the same thread, which makes everything much simpler and more predictable. +The project is implemented in Python (Python >= 3.9 is required). A number of APIs for functionality that is inherently I/O bound is implemented in terms of python coroutines with async IO. This means that all of the concurrent tasks run in the same thread, which makes everything much simpler and more predictable. ![layers](images/bumble_layers.svg) diff --git a/docs/mkdocs/src/platforms/index.md b/docs/mkdocs/src/platforms/index.md index 858785f..9bf7c29 100644 --- a/docs/mkdocs/src/platforms/index.md +++ b/docs/mkdocs/src/platforms/index.md @@ -1,7 +1,7 @@ PLATFORMS ========= -Most of the code included in the project should run on any platform that supports Python >= 3.8. Not all features are supported on all platforms (for example, USB dongle support is only available on platforms where the python USB library is functional). +Most of the code included in the project should run on any platform that supports Python >= 3.9. Not all features are supported on all platforms (for example, USB dongle support is only available on platforms where the python USB library is functional). For platform-specific information, see the following pages: diff --git a/environment.yml b/environment.yml index 2e927cb..bb65722 100644 --- a/environment.yml +++ b/environment.yml @@ -4,6 +4,6 @@ channels: - conda-forge dependencies: - pip=23 - - python=3.8 + - python=3.9 - pip: - --editable .[development,documentation,test] From f169ceaebb8a25bb3525efa8cd46ac1260c35ba4 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Sat, 19 Oct 2024 08:04:13 -0700 Subject: [PATCH 2/3] update linter and type checker --- setup.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index bb9b49f..0f0dd4e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -92,9 +92,9 @@ development = grpcio-tools >= 1.62.1 invoke >= 1.7.3 mobly >= 1.12.2 - mypy == 1.10.0 + mypy == 1.12.0 nox >= 2022 - pylint == 3.1.0 + pylint == 3.3.1 pyyaml >= 6.0 types-appdirs >= 1.4.3 types-invoke >= 1.7.3 From a00abd65b3728d57211a1e2e6c31b19a117e5dc8 Mon Sep 17 00:00:00 2001 From: Gilles Boccon-Gibod Date: Mon, 21 Oct 2024 23:58:50 -0700 Subject: [PATCH 3/3] fix some linter warnings --- bumble/avc.py | 2 ++ bumble/l2cap.py | 1 + bumble/link.py | 2 ++ bumble/profiles/bap.py | 2 ++ bumble/sdp.py | 2 ++ examples/run_extended_advertiser_2.py | 1 + examples/run_hfp_handsfree.py | 3 +++ pyproject.toml | 1 + 8 files changed, 14 insertions(+) diff --git a/bumble/avc.py b/bumble/avc.py index 8150278..7e60d83 100644 --- a/bumble/avc.py +++ b/bumble/avc.py @@ -134,6 +134,8 @@ class Frame: opcode_offset = 3 elif subunit_id == 6: raise core.InvalidPacketError("reserved subunit ID") + else: + raise core.InvalidPacketError("invalid subunit ID") opcode = Frame.OperationCode(data[opcode_offset]) operands = data[opcode_offset + 1 :] diff --git a/bumble/l2cap.py b/bumble/l2cap.py index 53c84d5..75e554c 100644 --- a/bumble/l2cap.py +++ b/bumble/l2cap.py @@ -1911,6 +1911,7 @@ class ChannelManager: data = sum(1 << cid for cid in self.fixed_channels).to_bytes(8, 'little') else: result = L2CAP_Information_Response.NOT_SUPPORTED + data = b'' self.send_control_frame( connection, diff --git a/bumble/link.py b/bumble/link.py index 8971e21..9c7f466 100644 --- a/bumble/link.py +++ b/bumble/link.py @@ -122,6 +122,8 @@ class LocalLink: elif transport == BT_BR_EDR_TRANSPORT: destination_controller = self.find_classic_controller(destination_address) source_address = sender_controller.public_address + else: + raise ValueError("unsupported transport type") if destination_controller is not None: destination_controller.on_link_acl_data(source_address, transport, data) diff --git a/bumble/profiles/bap.py b/bumble/profiles/bap.py index 8a00eaf..cd14bf1 100644 --- a/bumble/profiles/bap.py +++ b/bumble/profiles/bap.py @@ -350,6 +350,7 @@ class CodecSpecificCapabilities: supported_max_codec_frames_per_sdu = value # It is expected here that if some fields are missing, an error should be raised. + # pylint: disable=possibly-used-before-assignment,used-before-assignment return CodecSpecificCapabilities( supported_sampling_frequencies=supported_sampling_frequencies, supported_frame_durations=supported_frame_durations, @@ -426,6 +427,7 @@ class CodecSpecificConfiguration: codec_frames_per_sdu = value # It is expected here that if some fields are missing, an error should be raised. + # pylint: disable=possibly-used-before-assignment,used-before-assignment return CodecSpecificConfiguration( sampling_frequency=sampling_frequency, frame_duration=frame_duration, diff --git a/bumble/sdp.py b/bumble/sdp.py index 88c575d..90ac07c 100644 --- a/bumble/sdp.py +++ b/bumble/sdp.py @@ -434,6 +434,8 @@ class DataElement: if size != 1: raise InvalidArgumentError('boolean must be 1 byte') size_index = 0 + else: + raise RuntimeError("internal error - self.type not supported") self.bytes = bytes([self.type << 3 | size_index]) + size_bytes + data return self.bytes diff --git a/examples/run_extended_advertiser_2.py b/examples/run_extended_advertiser_2.py index 735e1c5..6f8d123 100644 --- a/examples/run_extended_advertiser_2.py +++ b/examples/run_extended_advertiser_2.py @@ -64,6 +64,7 @@ async def main() -> None: [(AdvertisingData.COMPLETE_LOCAL_NAME, "Bumble 2".encode("utf-8"))] ) + # pylint: disable=possibly-used-before-assignment if device.host.number_of_supported_advertising_sets >= 2: set2 = await device.create_advertising_set( random_address=Address("F0:F0:F0:F0:F0:F1"), diff --git a/examples/run_hfp_handsfree.py b/examples/run_hfp_handsfree.py index 5433284..be1d1ba 100644 --- a/examples/run_hfp_handsfree.py +++ b/examples/run_hfp_handsfree.py @@ -57,6 +57,9 @@ def on_dlc(dlc: rfcomm.DLC, configuration: hfp.HfConfiguration): esco_parameters = hfp.ESCO_PARAMETERS[ hfp.DefaultCodecParameters.ESCO_CVSD_S4 ] + else: + raise RuntimeError("unknown active codec") + connection.abort_on( 'disconnection', connection.device.send_command( diff --git a/pyproject.toml b/pyproject.toml index eb22842..8aa13c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,6 +45,7 @@ ignore="pandora" # FIXME: pylint does not support stubs yet: [tool.pylint.typecheck] signature-mutators="AsyncRunner.run_in_task" +disable="not-callable" [tool.black] skip-string-normalization = true