Skip to content

Commit 77c6b38

Browse files
committed
Enable ruff PTH rule and migrate to pathlib
Replace os.path usage with pathlib.Path in test_client.py and mask_fixtures.py for more idiomatic path handling.
1 parent 825b6b7 commit 77c6b38

File tree

3 files changed

+24
-35
lines changed

3 files changed

+24
-35
lines changed

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ select = [
7373
"C4",
7474
# pep8-naming
7575
"N",
76+
# flake8-pathlib
77+
"PTH",
7678
]
7779
ignore = ["E501"] # Line too long
7880

tests/test_client.py

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
"""Unit tests for the high-level OverkizClient behaviour and responses."""
22

3-
# ruff: noqa: ASYNC230, S106
3+
# ruff: noqa: S106
44
# S106: Test credentials use dummy values.
55
# ASYNC230: Blocking open() is acceptable for reading test fixtures
66

77
from __future__ import annotations
88

99
import json
10-
import os
10+
from pathlib import Path
1111
from unittest.mock import AsyncMock, patch
1212

1313
import aiohttp
@@ -25,7 +25,7 @@
2525
from pyoverkiz.response_handler import check_response
2626
from pyoverkiz.utils import create_local_server_config
2727

28-
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
28+
CURRENT_DIR = Path(__file__).resolve().parent
2929

3030

3131
class TestOverkizClient:
@@ -60,9 +60,7 @@ async def test_get_api_type_local(self, local_client: OverkizClient):
6060
@pytest.mark.asyncio
6161
async def test_get_devices_basic(self, client: OverkizClient):
6262
"""Ensure the client can fetch and parse the basic devices fixture."""
63-
with open(
64-
os.path.join(CURRENT_DIR, "devices.json"), encoding="utf-8"
65-
) as raw_devices:
63+
with (CURRENT_DIR / "devices.json").open(encoding="utf-8") as raw_devices:
6664
resp = MockResponse(raw_devices.read())
6765

6866
with patch.object(aiohttp.ClientSession, "get", return_value=resp):
@@ -81,8 +79,7 @@ async def test_fetch_events_basic(
8179
self, client: OverkizClient, fixture_name: str, event_length: int
8280
):
8381
"""Parameterised test that fetches events fixture and checks the expected count."""
84-
with open(
85-
os.path.join(CURRENT_DIR, "fixtures/event/" + fixture_name),
82+
with (CURRENT_DIR / "fixtures/event" / fixture_name).open(
8683
encoding="utf-8",
8784
) as raw_events:
8885
resp = MockResponse(raw_events.read())
@@ -94,8 +91,8 @@ async def test_fetch_events_basic(
9491
@pytest.mark.asyncio
9592
async def test_fetch_events_simple_cast(self, client: OverkizClient):
9693
"""Check that event state values from the cloud (strings) are cast to appropriate types."""
97-
with open(
98-
os.path.join(CURRENT_DIR, "fixtures/event/events.json"), encoding="utf-8"
94+
with (CURRENT_DIR / "fixtures/event/events.json").open(
95+
encoding="utf-8",
9996
) as raw_events:
10097
resp = MockResponse(raw_events.read())
10198

@@ -195,8 +192,7 @@ async def test_backoff_retries_on_concurrent_requests(
195192
@pytest.mark.asyncio
196193
async def test_fetch_events_casting(self, client: OverkizClient, fixture_name: str):
197194
"""Validate that fetched event states are cast to the expected Python types for each data type."""
198-
with open(
199-
os.path.join(CURRENT_DIR, "fixtures/event/" + fixture_name),
195+
with (CURRENT_DIR / "fixtures/event" / fixture_name).open(
200196
encoding="utf-8",
201197
) as raw_events:
202198
resp = MockResponse(raw_events.read())
@@ -264,8 +260,7 @@ async def test_get_setup(
264260
gateway_count: int,
265261
):
266262
"""Ensure setup parsing yields expected device and gateway counts and device metadata."""
267-
with open(
268-
os.path.join(CURRENT_DIR, "fixtures/setup/" + fixture_name),
263+
with (CURRENT_DIR / "fixtures/setup" / fixture_name).open(
269264
encoding="utf-8",
270265
) as setup_mock:
271266
resp = MockResponse(setup_mock.read())
@@ -316,8 +311,7 @@ async def test_get_setup(
316311
@pytest.mark.asyncio
317312
async def test_get_diagnostic_data(self, client: OverkizClient, fixture_name: str):
318313
"""Verify that diagnostic data can be fetched and is not empty."""
319-
with open(
320-
os.path.join(CURRENT_DIR, "fixtures/setup/" + fixture_name),
314+
with (CURRENT_DIR / "fixtures/setup" / fixture_name).open(
321315
encoding="utf-8",
322316
) as setup_mock:
323317
resp = MockResponse(setup_mock.read())
@@ -329,8 +323,7 @@ async def test_get_diagnostic_data(self, client: OverkizClient, fixture_name: st
329323
@pytest.mark.asyncio
330324
async def test_get_diagnostic_data_redacted_by_default(self, client: OverkizClient):
331325
"""Ensure diagnostics are redacted when no argument is provided."""
332-
with open(
333-
os.path.join(CURRENT_DIR, "fixtures/setup/setup_tahoma_1.json"),
326+
with (CURRENT_DIR / "fixtures/setup/setup_tahoma_1.json").open(
334327
encoding="utf-8",
335328
) as setup_mock:
336329
resp = MockResponse(setup_mock.read())
@@ -349,8 +342,7 @@ async def test_get_diagnostic_data_redacted_by_default(self, client: OverkizClie
349342
@pytest.mark.asyncio
350343
async def test_get_diagnostic_data_without_masking(self, client: OverkizClient):
351344
"""Ensure diagnostics can be returned without masking when requested."""
352-
with open(
353-
os.path.join(CURRENT_DIR, "fixtures/setup/setup_tahoma_1.json"),
345+
with (CURRENT_DIR / "fixtures/setup/setup_tahoma_1.json").open(
354346
encoding="utf-8",
355347
) as setup_mock:
356348
raw_setup = setup_mock.read()
@@ -552,8 +544,7 @@ async def test_check_response_exception_handling(
552544
"""Ensure client raises the correct error for various error fixtures/status codes."""
553545
with pytest.raises(exception):
554546
if fixture_name:
555-
with open(
556-
os.path.join(CURRENT_DIR, "fixtures/exceptions/" + fixture_name),
547+
with (CURRENT_DIR / "fixtures/exceptions" / fixture_name).open(
557548
encoding="utf-8",
558549
) as raw_events:
559550
resp = MockResponse(raw_events.read(), status_code)
@@ -568,8 +559,7 @@ async def test_get_setup_options(
568559
client: OverkizClient,
569560
):
570561
"""Check that setup options are parsed and return the expected number of Option instances."""
571-
with open(
572-
os.path.join(CURRENT_DIR, "fixtures/endpoints/setup-options.json"),
562+
with (CURRENT_DIR / "fixtures/endpoints/setup-options.json").open(
573563
encoding="utf-8",
574564
) as raw_events:
575565
resp = MockResponse(raw_events.read())
@@ -670,8 +660,7 @@ async def test_get_setup_option(
670660
instance: Option | None,
671661
):
672662
"""Verify retrieval of a single setup option by name, including non-existent options."""
673-
with open(
674-
os.path.join(CURRENT_DIR, "fixtures/endpoints/" + fixture_name),
663+
with (CURRENT_DIR / "fixtures/endpoints" / fixture_name).open(
675664
encoding="utf-8",
676665
) as raw_events:
677666
resp = MockResponse(raw_events.read())
@@ -701,8 +690,7 @@ async def test_get_action_groups(
701690
scenario_count: int,
702691
):
703692
"""Ensure action groups (scenarios) are parsed correctly and contain actions and commands."""
704-
with open(
705-
os.path.join(CURRENT_DIR, "fixtures/action_groups/" + fixture_name),
693+
with (CURRENT_DIR / "fixtures/action_groups" / fixture_name).open(
706694
encoding="utf-8",
707695
) as action_group_mock:
708696
resp = MockResponse(action_group_mock.read())

utils/mask_fixtures.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,23 @@
55

66
from __future__ import annotations
77

8-
import glob
98
import json
10-
import os
9+
from pathlib import Path
1110

1211
from pyoverkiz.obfuscate import obfuscate_sensitive_data
1312

1413
# only process .JSON files in folder.
15-
for filename in glob.glob(os.path.join("tests/fixtures/setup", "*.json")):
16-
with open(filename, encoding="utf-8") as input_file:
17-
print(f"Masking {filename}")
14+
for filepath in Path("tests/fixtures/setup").glob("*.json"):
15+
with filepath.open(encoding="utf-8") as input_file:
16+
print(f"Masking {filepath}")
1817

1918
try:
2019
file = json.loads(input_file.read())
2120
output = obfuscate_sensitive_data(file)
2221
except Exception as exception: # pylint: disable=broad-except
23-
print(f"Error while masking: {filename}")
22+
print(f"Error while masking: {filepath}")
2423
print(exception)
2524
continue
2625

27-
with open(filename, encoding="utf-8", mode="w") as output_file:
26+
with filepath.open(encoding="utf-8", mode="w") as output_file:
2827
json.dump(output, output_file, ensure_ascii=False, indent=4)

0 commit comments

Comments
 (0)