Skip to content

Commit bb15c51

Browse files
committed
Fix: Use try/except with allow_module_level=True for optional dependency tests
1 parent 26447a9 commit bb15c51

12 files changed

Lines changed: 57 additions & 38 deletions

File tree

.github/workflows/release.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ jobs:
5151
artifact: [wheel, sdist]
5252
steps:
5353
- uses: actions/checkout@v6
54+
with:
55+
sparse-checkout: |
56+
tests/
57+
pyproject.toml
58+
.gitignore
5459
5560
- uses: actions/setup-python@v6
5661
with:
@@ -80,10 +85,10 @@ jobs:
8085
8186
- name: Run packaging smoke tests against installed ${{ matrix.artifact }}
8287
run: |
83-
cd /tmp
84-
python -m pytest "$GITHUB_WORKSPACE/tests/gatt/test_uuid_registry.py" \
85-
--override-ini="pythonpath=" \
88+
python -m pytest tests/ \
8689
-m packaging \
90+
--ignore=tests/docs \
91+
--override-ini="pythonpath=" \
8792
-v
8893
8994
publish-pypi:

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
"chat.tools.terminal.autoApprove": {
33
"bluetoothctl": true,
44
"hciconfig": true
5-
}
5+
},
6+
"python.defaultInterpreterPath": "${workspaceFolder}/../../../.venv/bin/python",
7+
"python.venvPath": "${workspaceFolder}/../../../",
8+
"python.analysis.extraPaths": ["${workspaceFolder}/src"]
69
}

src/bluetooth_sig/gatt/uuid_registry.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ def get_service_info(self, key: str | BluetoothUUID) -> ServiceInfo | None:
383383
if canonical_key in self._services:
384384
return self._services[canonical_key]
385385
except ValueError:
386-
logger.warning("UUID normalization failed for service lookup: %s", search_key)
386+
pass # UUID normalization failed, continue to alias lookup
387387

388388
# Check alias index (normalized to lowercase)
389389
alias_key = self._service_aliases.get(search_key.lower())
@@ -411,7 +411,7 @@ def get_characteristic_info(self, identifier: str | BluetoothUUID) -> Characteri
411411
if canonical_key in self._characteristics:
412412
return self._characteristics[canonical_key]
413413
except ValueError:
414-
logger.warning("UUID normalization failed for characteristic lookup: %s", search_key)
414+
pass # UUID normalization failed, continue to alias lookup
415415

416416
# Check alias index (normalized to lowercase)
417417
alias_key = self._characteristic_aliases.get(search_key.lower())
@@ -439,7 +439,7 @@ def get_descriptor_info(self, identifier: str | BluetoothUUID) -> DescriptorInfo
439439
if canonical_key in self._descriptors:
440440
return self._descriptors[canonical_key]
441441
except ValueError:
442-
logger.warning("UUID normalization failed for descriptor lookup: %s", search_key)
442+
pass # UUID normalization failed, continue to alias lookup
443443

444444
# Check alias index (normalized to lowercase)
445445
alias_key = self._descriptor_aliases.get(search_key.lower())

src/bluetooth_sig/registry/base.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from __future__ import annotations
44

5-
import logging
65
import threading
76
from abc import ABC, abstractmethod
87
from collections.abc import Callable
@@ -18,8 +17,6 @@
1817
from bluetooth_sig.types.registry import BaseUuidInfo, generate_basic_aliases
1918
from bluetooth_sig.types.uuid import BluetoothUUID
2019

21-
logger = logging.getLogger(__name__)
22-
2320
T = TypeVar("T")
2421
E = TypeVar("E", bound=Enum) # For enum-keyed registries
2522
C = TypeVar("C") # For class types
@@ -213,8 +210,7 @@ def get_info(self, identifier: str | BluetoothUUID) -> U | None:
213210
if canonical_key in self._canonical_store:
214211
return self._canonical_store[canonical_key]
215212
except ValueError:
216-
logger.warning("UUID normalization failed for registry lookup: %s", search_key)
217-
213+
pass # UUID normalization failed, continue to alias lookup
218214
# Check alias index (normalized to lowercase)
219215
alias_key = self._alias_index.get(search_key.lower())
220216
if alias_key and alias_key in self._canonical_store:

tests/conftest.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
"""Pytest configuration helpers.
2-
3-
Ensure repository root and `src/` are on `sys.path` so tests can import
4-
local packages without per-test sys.path hacks.
5-
"""
1+
"""Pytest configuration helpers."""
62

73
from __future__ import annotations
84

@@ -28,12 +24,6 @@
2824
ROOT = Path(__file__).resolve().parent.parent
2925
# Export ROOT_DIR for tests that need to construct paths relative to project root
3026
ROOT_DIR = ROOT
31-
if str(ROOT) not in sys.path:
32-
sys.path.insert(0, str(ROOT))
33-
34-
SRC = ROOT / "src"
35-
if SRC.exists() and str(SRC) not in sys.path:
36-
sys.path.insert(0, str(SRC))
3727

3828

3929
def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None:

tests/docs/html/test_accessibility_static.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
from pathlib import Path
1313

1414
import pytest
15-
from bs4 import BeautifulSoup, Tag
15+
16+
# Skip this entire module if beautifulsoup4 is not installed
17+
try:
18+
from bs4 import BeautifulSoup, Tag
19+
except ModuleNotFoundError:
20+
pytest.skip("beautifulsoup4 not installed", allow_module_level=True)
1621

1722

1823
@pytest.mark.built_docs

tests/docs/html/test_content_quality_static.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
from pathlib import Path
1010

1111
import pytest
12-
from bs4 import BeautifulSoup
12+
13+
# Skip this entire module if beautifulsoup4 is not installed
14+
try:
15+
from bs4 import BeautifulSoup
16+
except ModuleNotFoundError:
17+
pytest.skip("beautifulsoup4 not installed", allow_module_level=True)
1318

1419

1520
@pytest.mark.built_docs

tests/docs/html/test_structure_static.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010
from pathlib import Path
1111

1212
import pytest
13-
from bs4 import BeautifulSoup
13+
14+
# Skip this entire module if beautifulsoup4 is not installed
15+
try:
16+
from bs4 import BeautifulSoup
17+
except ModuleNotFoundError:
18+
pytest.skip("beautifulsoup4 not installed", allow_module_level=True)
1419

1520

1621
@pytest.mark.built_docs

tests/docs/test_readme_badges.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
from urllib.parse import urlparse
88

99
import pytest
10-
import requests
10+
11+
# Skip this entire module if requests is not installed
12+
try:
13+
import requests
14+
except ModuleNotFoundError:
15+
pytest.skip("requests not installed", allow_module_level=True)
1116

1217

1318
def _is_trusted_domain(url: str, trusted_domains: list[str]) -> bool:

tests/gatt/test_uuid_registry.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
from bluetooth_sig.gatt.services.battery_service import BatteryService
1616
from bluetooth_sig.gatt.services.environmental_sensing import EnvironmentalSensingService
1717
from bluetooth_sig.gatt.uuid_registry import UuidRegistry
18+
from bluetooth_sig.registry.utils import find_bluetooth_sig_path
1819
from bluetooth_sig.types.gatt_services import ServiceDiscoveryData
1920
from bluetooth_sig.types.uuid import BluetoothUUID
20-
from tests.conftest import ROOT_DIR
2121

2222

2323
@pytest.fixture(scope="session")
@@ -191,7 +191,8 @@ def test_invalid_uuid_lookup(mock_uuid_registry: UuidRegistry) -> None:
191191
@pytest.mark.packaging
192192
def test_yaml_file_presence() -> None:
193193
"""Test that required YAML files exist."""
194-
base_path = ROOT_DIR / "bluetooth_sig" / "assigned_numbers" / "uuids"
194+
base_path = find_bluetooth_sig_path()
195+
assert base_path is not None, "Cannot locate bluetooth_sig data path (submodule or installed package)"
195196

196197
assert (base_path / "service_uuids.yaml").exists(), "Service UUIDs YAML file missing"
197198
assert (base_path / "characteristic_uuids.yaml").exists(), "Characteristic UUIDs YAML file missing"
@@ -200,7 +201,8 @@ def test_yaml_file_presence() -> None:
200201
@pytest.fixture(scope="session")
201202
def yaml_data() -> dict[str, Any]:
202203
"""Load YAML data once per session for performance."""
203-
base_path = ROOT_DIR / "bluetooth_sig" / "assigned_numbers" / "uuids"
204+
base_path = find_bluetooth_sig_path()
205+
assert base_path is not None, "Cannot locate bluetooth_sig data path"
204206

205207
# Load service data
206208
service_file = base_path / "service_uuids.yaml"

0 commit comments

Comments
 (0)