Skip to content

Commit

Permalink
Python 3.8, 3.10, and 3.12 support (#404)
Browse files Browse the repository at this point in the history
support python 3.8, 3.10 and 3.12 support
  • Loading branch information
mahnunchik authored Sep 25, 2024
1 parent e4af383 commit 4191b17
Show file tree
Hide file tree
Showing 18 changed files with 46 additions and 44 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ on:
- release
jobs:
test:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: [3.8]
python-version: ['3.8', '3.10', '3.12']

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand Down Expand Up @@ -97,7 +97,7 @@ jobs:
if: steps.branch-names.outputs.is_tag == 'false'
run: |
git checkout gh-pages
git checkout ${{ steps.branch-names.outputs.current_branch }}
git checkout ${{ steps.branch-names.outputs.current_branch }}
- name: Setup Python 3.8
uses: actions/setup-python@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion docs_src/generate_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from typing import Any, Dict, Iterator, List, Optional, Set, Tuple

import semver
import yaml
import yaml # type: ignore
from ast_to_xml import module_source
from git import Repo
from jinja2 import Template
Expand Down
2 changes: 1 addition & 1 deletion mqtt_io/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from hashlib import sha256
from typing import Any, Optional

import yaml
import yaml # type: ignore

from confp import render # type: ignore

Expand Down
2 changes: 1 addition & 1 deletion mqtt_io/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from typing import TYPE_CHECKING, Any, Dict, List, cast

import cerberus # type: ignore
import yaml
import yaml # type: ignore

from ..exceptions import ConfigValidationFailed
from ..types import ConfigType
Expand Down
7 changes: 4 additions & 3 deletions mqtt_io/modules/gpio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import logging
from concurrent.futures import ThreadPoolExecutor
from enum import Enum, Flag, IntFlag, auto
from typing import Any, Callable, Dict, Iterable, List, Optional
from typing import Any, Callable, Dict, Iterable, List, Optional, cast

from ...types import ConfigType, PinType

Expand Down Expand Up @@ -173,7 +173,7 @@ def setup_interrupt_internal(
pin: PinType,
edge: InterruptEdge,
in_conf: ConfigType,
callback: Optional[Callable[[List[Any], Dict[Any, Any]], None]] = None,
callback: Optional[Callable[..., None]] = None,
) -> None:
"""
Used internally to ensure that `self.interrupt_edges` is updated for this pin.
Expand Down Expand Up @@ -213,7 +213,7 @@ def remote_interrupt_for(self, pin: PinType) -> List[str]:
"""
Return the list of pin names that this pin is a remote interrupt for.
"""
return self.pin_configs[pin].get("interrupt_for", [])
return cast(List[str], self.pin_configs[pin].get("interrupt_for", []))

def get_int_pins(self) -> List[PinType]:
"""
Expand Down Expand Up @@ -274,6 +274,7 @@ def get_interrupt_value(self, pin: PinType, *args: Any, **kwargs: Any) -> bool:
for the value, or looking it up in a register that captures the value at time of
interrupt.
"""
return False

async def get_interrupt_values_remote(
self, pins: List[PinType]
Expand Down
4 changes: 2 additions & 2 deletions mqtt_io/modules/gpio/gpiozero.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
import logging
from functools import partial
from typing import Optional, Any, Callable, List, Dict, TYPE_CHECKING, cast
from typing import Optional, Any, Callable, Dict, TYPE_CHECKING, cast

from mqtt_io.modules.gpio import (
GenericGPIO,
Expand Down Expand Up @@ -89,7 +89,7 @@ def setup_interrupt_callback(
pin: PinType,
edge: InterruptEdge,
in_conf: ConfigType,
callback: Callable[[List[Any], Dict[Any, Any]], None],
callback: Callable[..., None],
) -> None:
_LOG.debug(
"Added interrupt to gpiozero Pi pin '%s' with callback '%s'", pin, callback
Expand Down
15 changes: 8 additions & 7 deletions mqtt_io/modules/gpio/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Mock GPIO module for using with the tests.
"""

from typing import Any, Callable, Dict, Iterable, List, Optional
from typing import Callable, Dict, Iterable, List, Optional
from unittest.mock import Mock

from ...types import ConfigType, PinType
Expand Down Expand Up @@ -39,20 +39,20 @@ def __init__(self, config: ConfigType):

super().__init__(config)
self.interrupt_callbacks: Dict[
PinType, Callable[[List[Any], Dict[Any, Any]], None]
PinType, Callable[..., None]
] = {}

def setup_interrupt_callback(
self,
pin: PinType,
edge: InterruptEdge,
in_conf: ConfigType,
callback: Callable[[List[Any], Dict[Any, Any]], None],
callback: Callable[..., None],
) -> None:
self.interrupt_callbacks[pin] = callback

def setup_module(self) -> None:
return super().setup_module()
return super().setup_module() # type: ignore[safe-super]

def setup_pin(
self,
Expand All @@ -62,18 +62,19 @@ def setup_pin(
pin_config: ConfigType,
initial: Optional[str] = None,
) -> None:
return super().setup_pin(pin, direction, pullup, pin_config, initial=initial)
return super().setup_pin( # type: ignore[safe-super]
pin, direction, pullup, pin_config, initial=initial)

def setup_interrupt(
self, pin: PinType, edge: InterruptEdge, in_conf: ConfigType
) -> None:
return super().setup_interrupt(pin, edge, in_conf)

def set_pin(self, pin: PinType, value: bool) -> None:
return super().set_pin(pin, value)
return super().set_pin(pin, value) # type: ignore[safe-super]

def get_pin(self, pin: PinType) -> bool:
return super().get_pin(pin)
return super().get_pin(pin) # type: ignore[safe-super]

def get_int_pins(self) -> List[PinType]:
return super().get_int_pins()
Expand Down
4 changes: 2 additions & 2 deletions mqtt_io/modules/gpio/raspberrypi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""

import logging
from typing import Any, Callable, Dict, List, Optional
from typing import Any, Callable, Optional

from ...types import ConfigType, PinType
from . import GenericGPIO, InterruptEdge, InterruptSupport, PinDirection, PinPUD
Expand Down Expand Up @@ -60,7 +60,7 @@ def setup_interrupt_callback(
pin: PinType,
edge: InterruptEdge,
in_conf: ConfigType,
callback: Callable[[List[Any], Dict[Any, Any]], None],
callback: Callable[..., None],
) -> None:
gpio_edge = self.interrupt_edge_map[edge]
_LOG.debug(
Expand Down
2 changes: 1 addition & 1 deletion mqtt_io/modules/sensor/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ def setup_sensor(self, sens_conf: ConfigType) -> None:
return super().setup_sensor(sens_conf)

def get_value(self, sens_conf: ConfigType) -> SensorValueType:
return super().get_value(sens_conf)
return super().get_value(sens_conf) # type: ignore[safe-super]
2 changes: 1 addition & 1 deletion mqtt_io/mqtt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class MQTTTLSOptions:
ca_certs: Optional[str] = None
certfile: Optional[str] = None
keyfile: Optional[str] = None
cert_reqs: int = ssl.CERT_REQUIRED
cert_reqs: ssl.VerifyMode = ssl.CERT_REQUIRED
tls_version: int = ssl.PROTOCOL_TLS
ciphers: Optional[str] = None

Expand Down
4 changes: 2 additions & 2 deletions mqtt_io/mqtt/aiomqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from functools import wraps
from typing import Any, Callable, List, Optional, Tuple, TypeVar, cast

from aiomqtt.client import Client, MqttError, Will, ProtocolVersion # type: ignore
from paho.mqtt import client as paho # type: ignore
from aiomqtt import Client, MqttError, Will, ProtocolVersion
from paho.mqtt import client as paho

from . import (
AbstractMQTTClient,
Expand Down
10 changes: 5 additions & 5 deletions mqtt_io/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
from hashlib import sha1
from importlib import import_module
from typing import Any, Dict, List, Optional, Tuple, Type, Union, overload
from aiomqtt.exceptions import MqttCodeError # type: ignore
from aiomqtt import MqttCodeError

import backoff # type: ignore
import backoff
from typing_extensions import Literal

from .config import (
Expand Down Expand Up @@ -648,10 +648,10 @@ async def poll_sensor(
None
"""
@backoff.on_exception( # type: ignore
@backoff.on_exception(
backoff.expo, Exception, max_time=sens_conf["interval"]
)
@backoff.on_predicate( # type: ignore
@backoff.on_predicate(
backoff.expo, lambda x: x is None, max_time=sens_conf["interval"]
)
async def get_sensor_value(
Expand Down Expand Up @@ -808,7 +808,7 @@ async def _mqtt_publish(self, msg: MQTTMessageSend, wait: bool = True) -> None:
)
else:
_LOG.debug(
"Publishing MQTT message on topic %r: %r", msg.topic, payload
"Publishing MQTT message on topic %r: %r", msg.topic, msg.payload
)

await self.mqtt.publish(msg)
Expand Down
2 changes: 1 addition & 1 deletion mqtt_io/tests/features/steps/config_main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Any
import yaml
import yaml # type: ignore
from behave import given, then, when # type: ignore
from mqtt_io.config import validate_and_normalise_main_config
from mqtt_io.exceptions import ConfigValidationFailed
Expand Down
6 changes: 3 additions & 3 deletions mqtt_io/tests/features/steps/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
import concurrent.futures
from typing import Any, Dict, Type

import yaml
import yaml # type: ignore
from behave import given, then, when # type: ignore
from behave.api.async_step import async_run_until_complete # type: ignore
from mqtt_io import events
from mqtt_io.server import MqttIo

try:
from unittest.mock import AsyncMock # type: ignore[attr-defined]
from unittest.mock import AsyncMock # type: ignore
except ImportError:
from mock import AsyncMock # type: ignore[attr-defined]
from mock import AsyncMock # type: ignore

# pylint: disable=function-redefined,protected-access

Expand Down
4 changes: 2 additions & 2 deletions mqtt_io/tests/features/steps/module_gpio.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def step(context: Any, is_isnt: str, pin_name: str):

poller_task_pin_names = {
get_coro(task).cr_frame.f_locals["in_conf"]["name"]
for task in asyncio.Task.all_tasks(loop=mqttio.loop)
for task in asyncio.all_tasks(loop=mqttio.loop)
if get_coro(task).__name__ == "digital_input_poller"
}
if is_isnt == "is":
Expand Down Expand Up @@ -137,7 +137,7 @@ def step(context: Any, is_isnt: str, module_name: str):

task_modules = {
get_coro(task).cr_frame.f_locals["module"]
for task in asyncio.Task.all_tasks(loop=mqttio.loop)
for task in asyncio.all_tasks(loop=mqttio.loop)
if get_coro(task).__name__ == "digital_output_loop"
}
if is_isnt == "is":
Expand Down
6 changes: 3 additions & 3 deletions mqtt_io/tests/features/steps/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
from typing import Any, Union
from unittest.mock import Mock

import yaml
import yaml # type: ignore
from behave import given, then, when # type: ignore
from behave.api.async_step import async_run_until_complete # type: ignore
from mqtt_io.exceptions import ConfigValidationFailed
from mqtt_io.mqtt import MQTTMessage, MQTTMessageSend
from mqtt_io.server import MqttIo

try:
from unittest.mock import AsyncMock # type: ignore[attr-defined]
from unittest.mock import AsyncMock # type: ignore
except ImportError:
from mock import AsyncMock # type: ignore[attr-defined]
from mock import AsyncMock # type: ignore

# pylint: disable=function-redefined

Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Cerberus = "^1.3.2"
typing-extensions = "^4.4.0"
dataclasses = { version = "^0.8", python = ">=3.6,<3.7" }
aiomqtt = "^2.1.0"
backoff = "^1.10.0"
backoff = "^2.2.1"
confp = "^0.4.0"
# Fix for poetry/docutils related bug
docutils = "0.18.1"
Expand All @@ -23,8 +23,8 @@ docutils = "0.18.1"
mock = { version = "^4.0.3", python = ">=3.6,<3.8" }
pytest = "^6.2.2"
tox = "^3.22.0"
pylint = "^2.6.2"
mypy = "^0.812"
pylint = "^3.2.7"
mypy = "^1.11.2"
behave = "^1.2.6"
coverage = "^5.4"
md-toc = "^8.0.0"
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tox]
isolated_build = true
envlist = py3{6,7,8}
envlist = py3{8,10,12}

[testenv]
whitelist_externals = poetry
Expand Down

0 comments on commit 4191b17

Please sign in to comment.