Skip to content

Commit

Permalink
Drop python3.8 support (#1979)
Browse files Browse the repository at this point in the history
  • Loading branch information
rytilahti authored Oct 26, 2024
1 parent e88159f commit 2dc6faf
Show file tree
Hide file tree
Showing 88 changed files with 484 additions and 590 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "pypy3.8"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.9"]
os: [ubuntu-latest, macos-latest, windows-latest]
# Exclude example, in case needed again in the future:
# exclude:
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ repos:
rev: v3.15.0
hooks:
- id: pyupgrade
args: ['--py38-plus']
args: ['--py39-plus']
24 changes: 12 additions & 12 deletions devtools/containers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from dataclasses import dataclass, field
from operator import attrgetter
from typing import Any, Dict, List, Optional
from typing import Any, Optional

from dataclasses_json import DataClassJsonMixin, config

Expand Down Expand Up @@ -45,7 +45,7 @@ def filename(self) -> str:

@dataclass
class ModelMapping(DataClassJsonMixin):
instances: List[InstanceInfo]
instances: list[InstanceInfo]

def info_for_model(self, model: str, *, status_filter="released") -> InstanceInfo:
matches = [inst for inst in self.instances if inst.model == model]
Expand Down Expand Up @@ -76,12 +76,12 @@ class Property(DataClassJsonMixin):
type: str
description: str
format: str
access: List[str]
access: list[str]

value_list: Optional[List[Dict[str, Any]]] = field(
value_list: Optional[list[dict[str, Any]]] = field(
default_factory=list, metadata=config(field_name="value-list")
) # type: ignore
value_range: Optional[List[int]] = field(
value_range: Optional[list[int]] = field(
default=None, metadata=config(field_name="value-range")
)

Expand Down Expand Up @@ -156,8 +156,8 @@ class Action(DataClassJsonMixin):
iid: int
type: str
description: str
out: List[Any] = field(default_factory=list)
in_: List[Any] = field(default_factory=list, metadata=config(field_name="in"))
out: list[Any] = field(default_factory=list)
in_: list[Any] = field(default_factory=list, metadata=config(field_name="in"))

def __repr__(self):
return f"aiid {self.iid} {self.description}: in: {self.in_} -> out: {self.out}"
Expand All @@ -178,7 +178,7 @@ class Event(DataClassJsonMixin):
iid: int
type: str
description: str
arguments: List[int]
arguments: list[int]

def __repr__(self):
return f"eiid {self.iid} ({self.description}): (args: {self.arguments})"
Expand All @@ -189,9 +189,9 @@ class Service(DataClassJsonMixin):
iid: int
type: str
description: str
properties: List[Property] = field(default_factory=list)
actions: List[Action] = field(default_factory=list)
events: List[Event] = field(default_factory=list)
properties: list[Property] = field(default_factory=list)
actions: list[Action] = field(default_factory=list)
events: list[Event] = field(default_factory=list)

def __repr__(self):
return f"siid {self.iid}: ({self.description}): {len(self.properties)} props, {len(self.actions)} actions"
Expand Down Expand Up @@ -220,7 +220,7 @@ def as_code(self):
class Device(DataClassJsonMixin):
type: str
description: str
services: List[Service] = field(default_factory=list)
services: list[Service] = field(default_factory=list)

def as_code(self):
s = ""
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@
)
]

intersphinx_mapping = {"python": ("https://docs.python.org/3.8", None)}
intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}

apidoc_module_dir = "../miio"
apidoc_output_dir = "api"
Expand Down
6 changes: 3 additions & 3 deletions miio/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from typing import Any, Dict
from typing import Any

import click

Expand Down Expand Up @@ -30,7 +30,7 @@
@click.version_option(package_name="python-miio")
@click.pass_context
def cli(ctx, debug: int, output: str):
logging_config: Dict[str, Any] = {
logging_config: dict[str, Any] = {
"level": logging.DEBUG if debug > 0 else logging.INFO
}
try:
Expand All @@ -56,7 +56,7 @@ def cli(ctx, debug: int, output: str):


for device_class in DeviceGroupMeta._device_classes:
cli.add_command(device_class.get_device_group())
cli.add_command(device_class.get_device_group()) # type: ignore[attr-defined]


@click.command()
Expand Down
10 changes: 5 additions & 5 deletions miio/click_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import logging
import re
from functools import partial, wraps
from typing import Any, Callable, ClassVar, Dict, List, Optional, Set, Type, Union
from typing import Any, Callable, ClassVar, Optional, Union

import click

Expand Down Expand Up @@ -111,9 +111,9 @@ def __init__(self, debug: int = 0, output: Optional[Callable] = None):


class DeviceGroupMeta(type):
_device_classes: Set[Type] = set()
_supported_models: ClassVar[List[str]]
_mappings: ClassVar[Dict[str, Any]]
_device_classes: set[type] = set()
_supported_models: ClassVar[list[str]]
_mappings: ClassVar[dict[str, Any]]

def __new__(mcs, name, bases, namespace):
commands = {}
Expand Down Expand Up @@ -150,7 +150,7 @@ def get_device_group(dcls):
return cls

@property
def supported_models(cls) -> List[str]:
def supported_models(cls) -> list[str]:
"""Return list of supported models."""
return list(cls._mappings.keys()) or cls._supported_models

Expand Down
8 changes: 4 additions & 4 deletions miio/cloud.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
import logging
from typing import TYPE_CHECKING, Dict, Optional
from typing import TYPE_CHECKING, Optional

import click

Expand Down Expand Up @@ -127,14 +127,14 @@ def _parse_device_list(self, data, locale):
return devs

@classmethod
def available_locales(cls) -> Dict[str, str]:
def available_locales(cls) -> dict[str, str]:
"""Return available locales.
The value is the human-readable name of the locale.
"""
return AVAILABLE_LOCALES

def get_devices(self, locale: Optional[str] = None) -> Dict[str, CloudDeviceInfo]:
def get_devices(self, locale: Optional[str] = None) -> dict[str, CloudDeviceInfo]:
"""Return a list of available devices keyed with a device id.
If no locale is given, all known locales are browsed. If a device id is already
Expand All @@ -147,7 +147,7 @@ def get_devices(self, locale: Optional[str] = None) -> Dict[str, CloudDeviceInfo
self._micloud.get_devices(country=locale), locale=locale
)

all_devices: Dict[str, CloudDeviceInfo] = {}
all_devices: dict[str, CloudDeviceInfo] = {}
for loc in AVAILABLE_LOCALES:
if loc == "all":
continue
Expand Down
8 changes: 4 additions & 4 deletions miio/descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"""

from enum import Enum, Flag, auto
from typing import Any, Callable, Dict, List, Optional, Type
from typing import Any, Callable, Optional

import attr

Expand Down Expand Up @@ -55,7 +55,7 @@ class Descriptor:
#: Name of the attribute in the status container that contains the value, if applicable.
status_attribute: Optional[str] = None
#: Additional data related to this descriptor.
extras: Dict = attr.ib(factory=dict, repr=False)
extras: dict = attr.ib(factory=dict, repr=False)
#: Access flags (read, write, execute) for the described item.
access: AccessFlags = attr.ib(default=AccessFlags(0))

Expand Down Expand Up @@ -84,7 +84,7 @@ class ActionDescriptor(Descriptor):
method: Optional[Callable] = attr.ib(default=None, repr=False)
#: Name of the method in the device class that can be used to execute the action.
method_name: Optional[str] = attr.ib(default=None, repr=False)
inputs: Optional[List[Any]] = attr.ib(default=None, repr=True)
inputs: Optional[list[Any]] = attr.ib(default=None, repr=True)

access: AccessFlags = attr.ib(default=AccessFlags.Execute)

Expand Down Expand Up @@ -153,7 +153,7 @@ class EnumDescriptor(PropertyDescriptor):
#: Name of the attribute in the device class that returns the choices.
choices_attribute: Optional[str] = attr.ib(default=None, repr=False)
#: Enum class containing the available choices.
choices: Optional[Type[Enum]] = attr.ib(default=None, repr=False)
choices: Optional[type[Enum]] = attr.ib(default=None, repr=False)

@property
def __cli_output__(self) -> str:
Expand Down
6 changes: 3 additions & 3 deletions miio/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ class Device(metaclass=DeviceGroupMeta):

retry_count = 3
timeout = 5
_mappings: Dict[str, Any] = {}
_supported_models: List[str] = []
_mappings: dict[str, Any] = {}
_supported_models: list[str] = []

def __init_subclass__(cls, **kwargs):
"""Overridden to register all integrations to the factory."""
Expand Down Expand Up @@ -182,7 +182,7 @@ def raw_id(self) -> int:
return self._protocol.raw_id

@property
def supported_models(self) -> List[str]:
def supported_models(self) -> list[str]:
"""Return a list of supported models."""
return list(self._mappings.keys()) or self._supported_models

Expand Down
12 changes: 6 additions & 6 deletions miio/devicefactory.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from typing import Dict, List, Optional, Type
from typing import Optional

import click

Expand All @@ -22,11 +22,11 @@ class DeviceFactory:
dev = DeviceFactory.create("127.0.0.1", 32*"0")
"""

_integration_classes: List[Type[Device]] = []
_supported_models: Dict[str, Type[Device]] = {}
_integration_classes: list[type[Device]] = []
_supported_models: dict[str, type[Device]] = {}

@classmethod
def register(cls, integration_cls: Type[Device]):
def register(cls, integration_cls: type[Device]):
"""Register class for to the registry."""
cls._integration_classes.append(integration_cls)
_LOGGER.debug("Registering %s", integration_cls.__name__)
Expand All @@ -44,13 +44,13 @@ def register(cls, integration_cls: Type[Device]):
cls._supported_models[model] = integration_cls

@classmethod
def supported_models(cls) -> Dict[str, Type[Device]]:
def supported_models(cls) -> dict[str, type[Device]]:
"""Return a dictionary of models and their corresponding implementation
classes."""
return cls._supported_models

@classmethod
def integrations(cls) -> List[Type[Device]]:
def integrations(cls) -> list[type[Device]]:
"""Return the list of integration classes."""
return cls._integration_classes

Expand Down
4 changes: 2 additions & 2 deletions miio/deviceinfo.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, Optional
from typing import Optional


class DeviceInfo:
Expand Down Expand Up @@ -40,7 +40,7 @@ def __repr__(self):
)

@property
def network_interface(self) -> Dict:
def network_interface(self) -> dict:
"""Information about network configuration.
If unavailable, returns an empty dictionary.
Expand Down
17 changes: 4 additions & 13 deletions miio/devicestatus.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
import inspect
import logging
import warnings
from collections.abc import Iterable
from enum import Enum
from typing import (
Callable,
Dict,
Iterable,
Optional,
Type,
Union,
get_args,
get_origin,
get_type_hints,
)
from typing import Callable, Optional, Union, get_args, get_origin, get_type_hints

import attr

Expand All @@ -37,7 +28,7 @@ def __new__(metacls, name, bases, namespace, **kwargs):

cls._descriptors: DescriptorCollection[PropertyDescriptor] = {}
cls._parent: Optional["DeviceStatus"] = None
cls._embedded: Dict[str, "DeviceStatus"] = {}
cls._embedded: dict[str, "DeviceStatus"] = {}

for n in namespace:
prop = getattr(namespace[n], "fget", None)
Expand Down Expand Up @@ -222,7 +213,7 @@ def setting(
max_value: Optional[int] = None,
step: Optional[int] = None,
range_attribute: Optional[str] = None,
choices: Optional[Type[Enum]] = None,
choices: Optional[type[Enum]] = None,
choices_attribute: Optional[str] = None,
**kwargs,
):
Expand Down
5 changes: 2 additions & 3 deletions miio/devtools/pcapparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from collections import Counter, defaultdict
from ipaddress import ip_address
from pprint import pformat as pf
from typing import List

import click

Expand All @@ -16,7 +15,7 @@
from miio import Message


def read_payloads_from_file(file, tokens: List[str]):
def read_payloads_from_file(file, tokens: list[str]):
"""Read the given pcap file and yield src, dst, and result."""
try:
import dpkt
Expand Down Expand Up @@ -86,7 +85,7 @@ def read_payloads_from_file(file, tokens: List[str]):
@click.command()
@click.argument("file", type=click.File("rb"))
@click.argument("token", nargs=-1)
def parse_pcap(file, token: List[str]):
def parse_pcap(file, token: list[str]):
"""Read PCAP file and output decrypted miio communication."""
for src_addr, dst_addr, payload in read_payloads_from_file(file, token):
echo(f"{src_addr:<15} -> {dst_addr:<15} {pf(payload)}")
Loading

0 comments on commit 2dc6faf

Please sign in to comment.