mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-10-09 17:08:02 +00:00
Remove support for python <3.11 (#1273)
Python 3.11 ships with latest Debian Bookworm. pypy is not that widely used with this library based on statistics. It could be added back when pypy supports python 3.11.
This commit is contained in:
@@ -28,7 +28,7 @@ async def handle_turn_on(dev, turn_on):
|
||||
await dev.turn_off()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture
|
||||
def dummy_protocol():
|
||||
"""Return a smart protocol instance with a mocking-ready dummy transport."""
|
||||
|
||||
@@ -95,7 +95,7 @@ def pytest_collection_modifyitems(config, items):
|
||||
for item in items:
|
||||
item.add_marker(pytest.mark.enable_socket)
|
||||
else:
|
||||
print("Running against ip %s" % config.getoption("--ip"))
|
||||
print("Running against ip {}".format(config.getoption("--ip")))
|
||||
requires_dummy = pytest.mark.skip(
|
||||
reason="test requires to be run against dummy data"
|
||||
)
|
||||
|
@@ -4,8 +4,9 @@ import copy
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
from collections.abc import Iterable
|
||||
from pathlib import Path
|
||||
from typing import Iterable, NamedTuple
|
||||
from typing import NamedTuple
|
||||
|
||||
import pytest
|
||||
|
||||
|
@@ -2,7 +2,6 @@ from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
import pytest
|
||||
from pytest_mock import MockerFixture
|
||||
@@ -23,7 +22,7 @@ autooff = parametrize(
|
||||
[
|
||||
("auto_off_enabled", "enabled", bool),
|
||||
("auto_off_minutes", "delay", int),
|
||||
("auto_off_at", "auto_off_at", Optional[datetime]),
|
||||
("auto_off_at", "auto_off_at", datetime | None),
|
||||
],
|
||||
)
|
||||
@pytest.mark.skipif(
|
||||
|
@@ -74,7 +74,7 @@ async def test_update_available_without_cloud(dev: SmartDevice):
|
||||
pytest.param(False, pytest.raises(KasaException), id="not-available"),
|
||||
],
|
||||
)
|
||||
@pytest.mark.requires_dummy()
|
||||
@pytest.mark.requires_dummy
|
||||
async def test_firmware_update(
|
||||
dev: SmartDevice,
|
||||
mocker: MockerFixture,
|
||||
|
@@ -17,8 +17,7 @@ waterleak = parametrize(
|
||||
("feature", "prop_name", "type"),
|
||||
[
|
||||
("water_alert", "alert", int),
|
||||
# Can be converted to 'datetime | None' after py3.9 support is dropped
|
||||
("water_alert_timestamp", "alert_timestamp", (datetime, type(None))),
|
||||
("water_alert_timestamp", "alert_timestamp", datetime | None),
|
||||
("water_leak", "status", Enum),
|
||||
],
|
||||
)
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from datetime import UTC, datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
@@ -91,7 +91,7 @@ async def test_hub(dev):
|
||||
@device_smartcamera
|
||||
async def test_device_time(dev: Device, freezer: FrozenDateTimeFactory):
|
||||
"""Test a child device gets the time from it's parent module."""
|
||||
fallback_time = datetime.now(timezone.utc).astimezone().replace(microsecond=0)
|
||||
fallback_time = datetime.now(UTC).astimezone().replace(microsecond=0)
|
||||
assert dev.time != fallback_time
|
||||
module = dev.modules[Module.Time]
|
||||
await module.set_time(fallback_time)
|
||||
|
@@ -278,7 +278,7 @@ async def test_non_variable_temp(dev: Device):
|
||||
@dimmable_iot
|
||||
@turn_on
|
||||
async def test_dimmable_brightness(dev: IotBulb, turn_on):
|
||||
assert isinstance(dev, (IotBulb, IotDimmer))
|
||||
assert isinstance(dev, IotBulb | IotDimmer)
|
||||
light = dev.modules.get(Module.Light)
|
||||
assert light
|
||||
await handle_turn_on(dev, turn_on)
|
||||
@@ -375,7 +375,7 @@ async def test_list_presets(dev: IotBulb):
|
||||
]
|
||||
assert len(presets) == len(raw_presets)
|
||||
|
||||
for preset, raw in zip(presets, raw_presets):
|
||||
for preset, raw in zip(presets, raw_presets, strict=False):
|
||||
assert preset.index == raw["index"]
|
||||
assert preset.brightness == raw["brightness"]
|
||||
assert preset.hue == raw["hue"]
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import inspect
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from datetime import UTC, datetime
|
||||
|
||||
import pytest
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
@@ -58,10 +57,6 @@ async def test_childdevice_update(dev, dummy_protocol, mocker):
|
||||
|
||||
|
||||
@strip_smart
|
||||
@pytest.mark.skipif(
|
||||
sys.version_info < (3, 11),
|
||||
reason="exceptiongroup requires python3.11+",
|
||||
)
|
||||
async def test_childdevice_properties(dev: SmartChildDevice):
|
||||
"""Check that accessing childdevice properties do not raise exceptions."""
|
||||
assert len(dev.children) > 0
|
||||
@@ -125,7 +120,7 @@ async def test_parent_property(dev: Device):
|
||||
|
||||
|
||||
@has_children_smart
|
||||
@pytest.mark.requires_dummy()
|
||||
@pytest.mark.requires_dummy
|
||||
async def test_child_time(dev: Device, freezer: FrozenDateTimeFactory):
|
||||
"""Test a child device gets the time from it's parent module.
|
||||
|
||||
@@ -135,7 +130,7 @@ async def test_child_time(dev: Device, freezer: FrozenDateTimeFactory):
|
||||
if not dev.children:
|
||||
pytest.skip(f"Device {dev} fixture does not have any children")
|
||||
|
||||
fallback_time = datetime.now(timezone.utc).astimezone().replace(microsecond=0)
|
||||
fallback_time = datetime.now(UTC).astimezone().replace(microsecond=0)
|
||||
assert dev.parent is None
|
||||
for child in dev.children:
|
||||
assert child.time != fallback_time
|
||||
|
@@ -3,12 +3,12 @@ import os
|
||||
import re
|
||||
from datetime import datetime
|
||||
from unittest.mock import ANY
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
import asyncclick as click
|
||||
import pytest
|
||||
from asyncclick.testing import CliRunner
|
||||
from pytest_mock import MockerFixture
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from kasa import (
|
||||
AuthenticationError,
|
||||
@@ -58,7 +58,7 @@ from .conftest import (
|
||||
pytestmark = [pytest.mark.requires_dummy]
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture
|
||||
def runner():
|
||||
"""Runner fixture that unsets the KASA_ environment variables for tests."""
|
||||
KASA_VARS = {k: None for k, v in os.environ.items() if k.startswith("KASA_")}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
from datetime import datetime
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
import pytest
|
||||
from pytest_mock import MockerFixture
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from kasa import Device, LightState, Module
|
||||
|
||||
|
@@ -6,11 +6,11 @@ import importlib
|
||||
import inspect
|
||||
import pkgutil
|
||||
import sys
|
||||
import zoneinfo
|
||||
from contextlib import AbstractContextManager, nullcontext
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
import zoneinfo
|
||||
|
||||
import kasa
|
||||
from kasa import Credentials, Device, DeviceConfig, DeviceType, KasaException, Module
|
||||
|
@@ -7,11 +7,11 @@ import json
|
||||
import logging
|
||||
import re
|
||||
import socket
|
||||
from asyncio import timeout as asyncio_timeout
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import aiohttp
|
||||
import pytest # type: ignore # https://github.com/pytest-dev/pytest/issues/3342
|
||||
from async_timeout import timeout as asyncio_timeout
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import padding as asymmetric_padding
|
||||
|
||||
|
@@ -68,7 +68,7 @@ async def test_get_emeter_realtime(dev):
|
||||
|
||||
|
||||
@has_emeter_iot
|
||||
@pytest.mark.requires_dummy()
|
||||
@pytest.mark.requires_dummy
|
||||
async def test_get_emeter_daily(dev):
|
||||
emeter = dev.modules[Module.Energy]
|
||||
|
||||
@@ -88,7 +88,7 @@ async def test_get_emeter_daily(dev):
|
||||
|
||||
|
||||
@has_emeter_iot
|
||||
@pytest.mark.requires_dummy()
|
||||
@pytest.mark.requires_dummy
|
||||
async def test_get_emeter_monthly(dev):
|
||||
emeter = dev.modules[Module.Energy]
|
||||
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import logging
|
||||
import sys
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
@@ -14,7 +13,7 @@ class DummyDevice:
|
||||
pass
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture
|
||||
def dummy_feature() -> Feature:
|
||||
# create_autospec for device slows tests way too much, so we use a dummy here
|
||||
|
||||
@@ -159,10 +158,6 @@ async def test_precision_hint(dummy_feature, precision_hint):
|
||||
assert f"{round(dummy_value, precision_hint)} dummyunit" in repr(dummy_feature)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
sys.version_info < (3, 11),
|
||||
reason="exceptiongroup requires python3.11+",
|
||||
)
|
||||
async def test_feature_setters(dev: Device, mocker: MockerFixture):
|
||||
"""Test that all feature setters query something."""
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import asyncio
|
||||
import re
|
||||
|
||||
import aiohttp
|
||||
@@ -32,7 +31,7 @@ from kasa.httpclient import HttpClient
|
||||
"Unable to query the device, timed out: ",
|
||||
),
|
||||
(
|
||||
asyncio.TimeoutError(),
|
||||
TimeoutError(),
|
||||
TimeoutError,
|
||||
"Unable to query the device, timed out: ",
|
||||
),
|
||||
|
@@ -89,7 +89,7 @@ async def test_state_info(dev):
|
||||
assert isinstance(dev.state_information, dict)
|
||||
|
||||
|
||||
@pytest.mark.requires_dummy()
|
||||
@pytest.mark.requires_dummy
|
||||
@device_iot
|
||||
async def test_invalid_connection(mocker, dev):
|
||||
mocker.patch.object(FakeIotProtocol, "query", side_effect=KasaException)
|
||||
|
@@ -145,7 +145,7 @@ def test_tutorial_examples(readmes_mock):
|
||||
assert not res["failed"]
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture
|
||||
async def readmes_mock(mocker):
|
||||
fixture_infos = {
|
||||
"127.0.0.1": get_fixture_info("KP303(UK)_1.0_1.0.3.json", "IOT"), # Strip
|
||||
|
@@ -26,7 +26,7 @@ from .conftest import (
|
||||
|
||||
|
||||
@device_smart
|
||||
@pytest.mark.requires_dummy()
|
||||
@pytest.mark.requires_dummy
|
||||
async def test_try_get_response(dev: SmartDevice, caplog):
|
||||
mock_response: dict = {
|
||||
"get_device_info": SmartErrorCode.PARAMS_ERROR,
|
||||
@@ -38,7 +38,7 @@ async def test_try_get_response(dev: SmartDevice, caplog):
|
||||
|
||||
|
||||
@device_smart
|
||||
@pytest.mark.requires_dummy()
|
||||
@pytest.mark.requires_dummy
|
||||
async def test_update_no_device_info(dev: SmartDevice, mocker: MockerFixture):
|
||||
mock_response: dict = {
|
||||
"get_device_usage": {},
|
||||
|
Reference in New Issue
Block a user