Skip to content

Enable ruff B (bugbear) and fix violations#1683

Merged
bdraco merged 1 commit into
esphome:mainfrom
bluetoothbot:koan/enable-ruff-bugbear
May 20, 2026
Merged

Enable ruff B (bugbear) and fix violations#1683
bdraco merged 1 commit into
esphome:mainfrom
bluetoothbot:koan/enable-ruff-bugbear

Conversation

@bluetoothbot
Copy link
Copy Markdown
Contributor

@bluetoothbot bluetoothbot commented May 20, 2026

What does this implement/fix?

Adds the B (flake8-bugbear) rule set to the enforced ruff lint
configuration and fixes the 7 existing violations across the repo.

The notable fix is tests/test_model.py:840, where
services == BluetoothGATTServicesModel.from_dict(...) was a
no-op expression (B015 caught it). The intent was to rebuild
services from the dict form and verify it parses to the same
structure — the next assert services.services[0] == ... was
otherwise re-checking the from_pb-derived model. Changing == to
= makes the from_dict path the one actually being asserted,
matching the test name test_bluetooth_gatt_services_from_dict.

Other violations:

  • B904 — re-raises now use from err / from None in
    _frame_helper/noise.py::_decode_noise_psk,
    host_resolver.py::_async_resolve_host_getaddrinfo, and the
    resolver test helper. Preserves the cause chain on tracebacks.
  • B007 — three unused loop control variables renamed to _.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Code quality improvements to existing code or addition of tests
  • Other

Related issue or feature (if applicable):

Follows the same pattern as the recent PT006/PT007 (#1679) and PTH
(#1678) rule-set additions: enable one ruff family at a time, fix
the existing violations, lock it in.

Pull request in esphome (if applicable):

n/a — no api.proto changes.

Checklist:

  • The code change is tested and works locally.
  • If api.proto was modified, a linked pull request has been made to esphome with the same changes.
  • Tests have been added to verify that the new code works (under tests/ folder).

Quality Report

Changes: 9 files changed, 11 insertions(+), 10 deletions(-)

Code scan: clean

Tests: failed (FAILED)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

Adds flake8-bugbear to the enforced ruff rule set and fixes the
existing 7 violations.

Notable: tests/test_model.py:840 had `services == X(...)` instead of
`services = X(...)`, leaving the subsequent `services.services[0] ==`
assertion checking the same from_pb-derived model twice instead of
exercising from_dict. The reassignment now makes the `from_dict` path
the one being verified, matching the test's name.

Other fixes:
- B904: chain `raise X from err` in _frame_helper/noise.py and
  host_resolver.py so re-raised exceptions preserve their cause.
- B007: drop unused loop variables (`for _ in range(5)` and iterate
  dict keys directly in test_core).
@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (f544437) to head (7ad00cf).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #1683   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           25        25           
  Lines         4152      4152           
=========================================
  Hits          4152      4152           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 20, 2026

Merging this PR will not alter performance

✅ 40 untouched benchmarks


Comparing bluetoothbot:koan/enable-ruff-bugbear (7ad00cf) with main (f544437)

Open in CodSpeed

@bdraco bdraco marked this pull request as ready for review May 20, 2026 11:26
Copilot AI review requested due to automatic review settings May 20, 2026 11:26
@bdraco bdraco merged commit 11fb7ee into esphome:main May 20, 2026
16 checks passed
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 879e21cf-333e-4d44-aaa5-53a837a6064e

📥 Commits

Reviewing files that changed from the base of the PR and between f544437 and 7ad00cf.

📒 Files selected for processing (9)
  • aioesphomeapi/_frame_helper/noise.py
  • aioesphomeapi/host_resolver.py
  • bench/raw_ble_plain_text.py
  • pyproject.toml
  • tests/benchmarks/test_bluetooth.py
  • tests/test__frame_helper.py
  • tests/test_core.py
  • tests/test_model.py
  • tests/test_reconnect_logic.py

Walkthrough

PR adds exception chaining to preserve error context in API error handlers, enables flake8-bugbear linting rules, fixes unused variable warnings across benchmarks and tests, and corrects test logic bugs in model and message type tests.

Changes

API Quality and Code Health

Layer / File(s) Summary
Exception context preservation in error handlers
aioesphomeapi/_frame_helper/noise.py, aioesphomeapi/host_resolver.py, tests/test_reconnect_logic.py
APINoiseFrameHelper._decode_noise_psk() captures ValueError from base64 decoding and chains it when raising InvalidEncryptionKeyAPIError. _async_resolve_host_getaddrinfo chains caught OSError when raising ResolveAPIError. Test mock validates chaining behavior for timeout errors in reconnection logic.
Linting rules and code quality fixes
pyproject.toml, bench/raw_ble_plain_text.py, tests/benchmarks/test_bluetooth.py, tests/test__frame_helper.py
Ruff configuration adds flake8-bugbear ("B") rule group to lint selection. Unused loop variables renamed from i to _ in benchmark and three test files to match linting standards.
Test logic fixes and refactoring
tests/test_model.py, tests/test_core.py
Bluetooth GATT services test fixed to assign parsed model result instead of comparing for equality. Message type test refactored to iterate MESSAGE_TYPE_TO_PROTO keys directly instead of unpacking key-value pairs.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

minor

Suggested reviewers

  • bdraco
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the repository’s Ruff lint enforcement by enabling the B (flake8-bugbear) ruleset and applies small targeted code/test changes to resolve the newly-enforced violations.

Changes:

  • Enable Ruff B (bugbear) rules in pyproject.toml.
  • Fix a no-op comparison in test_bluetooth_gatt_services_from_dict so the test actually validates the from_dict path.
  • Improve exception chaining (raise ... from err) and rename unused loop variables to _ to satisfy bugbear rules.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pyproject.toml Enables Ruff bugbear (B) lint rules.
tests/test_model.py Fixes a no-op expression by assigning the from_dict result before assertions.
tests/test_core.py Avoids an unused loop variable by iterating dict keys only.
tests/test__frame_helper.py Renames an unused loop variable to _.
tests/benchmarks/test_bluetooth.py Renames an unused loop variable to _ in benchmark setup.
bench/raw_ble_plain_text.py Renames an unused loop variable to _ in the bench script.
aioesphomeapi/host_resolver.py Preserves exception cause when wrapping getaddrinfo failures.
aioesphomeapi/_frame_helper/noise.py Preserves exception cause when rejecting malformed PSKs.
tests/test_reconnect_logic.py Preserves exception cause when translating a timeout into APIConnectionError.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 257 to +265
try:
psk_bytes = binascii.a2b_base64(psk)
except ValueError:
except ValueError as err:
raise InvalidEncryptionKeyAPIError(
f"{self._log_name}: Malformed PSK (length={len(psk)}), "
"expected base64-encoded 32-byte value",
server_name,
server_mac,
)
) from err
@bluetoothbot bluetoothbot deleted the koan/enable-ruff-bugbear branch May 20, 2026 11:33
bluetoothbot added a commit to bluetoothbot/aioesphomeapi that referenced this pull request May 20, 2026
Adds PGH (pygrep-hooks) to the ruff rule selection so blanket
`# type: ignore` and `# flake8: noqa` directives are flagged. All 12
existing violations are converted to specific codes:

- 10 `# type: ignore` -> `# type: ignore[attr-defined]` on
  `from .api_pb2 import (...)` blocks (protobuf-generated module
  lacks stubs for its dynamically-emitted symbols).
- 1 `# type: ignore` -> `# type: ignore[union-attr]` on the
  HomeassistantServiceMap iteration in `_convert_homeassistant_service_map`
  (mypy widens the iter element to `str | Any` after the dict
  isinstance branch).
- `# flake8: noqa` on `aioesphomeapi/__init__.py` -> `# ruff: noqa: F401, F403`
  (file is the public re-export surface; F401 covers the unused-name
  warnings on each re-export and F403 covers the `from .model import *`).

Follows the cadence of esphome#1678 (PTH) and esphome#1679 (PT006/PT007) and esphome#1683
(B) -- one ruff family at a time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants