File kvmd-python3.9-compat.patch of Package kvmd
From db5b9ec5c699b1d54ec3a162e30e94c281de5057 Mon Sep 17 00:00:00 2001
From: Oleg Girko <ol@infoserver.lv>
Date: Wed, 12 Mar 2025 14:10:58 +0000
Subject: [PATCH] Fix Python 3.9 compatibility.
The following changes are mafe to preserve Python 3.9 compatibility.
* Do not use match statement.
* Import annotations from __future__ to allow type unions with "|" syntax.
* Pass loop argument to asyncio.Queue() constructor in kvmd/aiogp.py
file, but only if Python version < 3.10 (partially reverts 1d4b39ef1).
* Don't use typing.Self.
This is needed for RHEL 9 that has Python 3.9 by default as well as many
packages built for Python 3.9 that are necessary for KVMD.
Signed-off-by: Oleg Girko <ol@infoserver.lv>
---
genmap.py | 2 +
kvmd/aiogp.py | 6 +-
kvmd/aiomulti.py | 2 +
kvmd/aioproc.py | 2 +
kvmd/aiotools.py | 2 +
kvmd/apps/__init__.py | 2 +
kvmd/apps/edidconf/__init__.py | 2 +
kvmd/apps/htpasswd/__init__.py | 2 +
kvmd/apps/ipmi/__init__.py | 2 +
kvmd/apps/ipmi/server.py | 2 +
kvmd/apps/janus/__init__.py | 2 +
kvmd/apps/janus/runner.py | 2 +
kvmd/apps/janus/stun.py | 2 +
kvmd/apps/kvmd/__init__.py | 2 +
kvmd/apps/kvmd/api/log.py | 2 +
kvmd/apps/kvmd/api/msd.py | 2 +
kvmd/apps/kvmd/auth.py | 2 +
kvmd/apps/kvmd/info/__init__.py | 2 +
kvmd/apps/kvmd/info/auth.py | 2 +
kvmd/apps/kvmd/info/base.py | 2 +
kvmd/apps/kvmd/info/extras.py | 2 +
kvmd/apps/kvmd/info/fan.py | 2 +
kvmd/apps/kvmd/info/hw.py | 2 +
kvmd/apps/kvmd/info/meta.py | 2 +
kvmd/apps/kvmd/info/system.py | 2 +
kvmd/apps/kvmd/ocr.py | 2 +
kvmd/apps/kvmd/server.py | 2 +
kvmd/apps/kvmd/streamer.py | 2 +
kvmd/apps/kvmd/switch/__init__.py | 23 ++++---
kvmd/apps/kvmd/switch/chain.py | 94 +++++++++++++-------------
kvmd/apps/kvmd/switch/device.py | 2 +
kvmd/apps/kvmd/switch/proto.py | 15 ++--
kvmd/apps/kvmd/switch/state.py | 2 +
kvmd/apps/kvmd/switch/types.py | 2 +
kvmd/apps/kvmd/sysunit.py | 2 +
kvmd/apps/kvmd/ugpio.py | 2 +
kvmd/apps/media/__init__.py | 2 +
kvmd/apps/media/server.py | 2 +
kvmd/apps/ngxmkconf/__init__.py | 2 +
kvmd/apps/otg/__init__.py | 2 +
kvmd/apps/otg/hid/keyboard.py | 2 +
kvmd/apps/otg/hid/mouse.py | 2 +
kvmd/apps/otgconf/__init__.py | 2 +
kvmd/apps/otgmsd/__init__.py | 2 +
kvmd/apps/otgnet/__init__.py | 2 +
kvmd/apps/pst/__init__.py | 2 +
kvmd/apps/pstrun/__init__.py | 2 +
kvmd/apps/swctl/__init__.py | 44 ++++++------
kvmd/apps/totp/__init__.py | 2 +
kvmd/apps/vnc/__init__.py | 2 +
kvmd/apps/vnc/rfb/encodings.py | 2 +
kvmd/apps/vnc/rfb/stream.py | 2 +
kvmd/apps/vnc/server.py | 2 +
kvmd/apps/watchdog/__init__.py | 2 +
kvmd/clients/__init__.py | 5 +-
kvmd/clients/kvmd.py | 2 +
kvmd/edid.py | 2 +
kvmd/htclient.py | 2 +
kvmd/htserver.py | 2 +
kvmd/inotify.py | 2 +
kvmd/logging.py | 2 +
kvmd/plugins/atx/gpio.py | 2 +
kvmd/plugins/auth/http.py | 2 +
kvmd/plugins/hid/__init__.py | 2 +
kvmd/plugins/hid/_mcu/__init__.py | 2 +
kvmd/plugins/hid/_mcu/gpio.py | 2 +
kvmd/plugins/hid/bt/__init__.py | 2 +
kvmd/plugins/hid/bt/bluez.py | 2 +
kvmd/plugins/hid/bt/server.py | 2 +
kvmd/plugins/hid/ch9329/__init__.py | 2 +
kvmd/plugins/hid/ch9329/mouse.py | 21 +++---
kvmd/plugins/hid/otg/__init__.py | 2 +
kvmd/plugins/hid/otg/device.py | 2 +
kvmd/plugins/hid/otg/events.py | 2 +
kvmd/plugins/hid/otg/keyboard.py | 2 +
kvmd/plugins/hid/otg/mouse.py | 2 +
kvmd/plugins/hid/spi.py | 2 +
kvmd/plugins/msd/__init__.py | 2 +
kvmd/plugins/msd/disabled.py | 2 +
kvmd/plugins/msd/otg/__init__.py | 2 +
kvmd/plugins/ugpio/__init__.py | 2 +
kvmd/plugins/ugpio/ezcoo.py | 2 +
kvmd/plugins/ugpio/gpio.py | 2 +
kvmd/plugins/ugpio/hidrelay.py | 2 +
kvmd/plugins/ugpio/hue.py | 2 +
kvmd/plugins/ugpio/ipmi.py | 2 +
kvmd/plugins/ugpio/locator.py | 2 +
kvmd/plugins/ugpio/pway.py | 2 +
kvmd/plugins/ugpio/pwm.py | 2 +
kvmd/plugins/ugpio/tesmart.py | 2 +
kvmd/plugins/ugpio/wol.py | 2 +
kvmd/plugins/ugpio/xh_hk4401.py | 2 +
kvmd/tools.py | 2 +
kvmd/validators/__init__.py | 2 +
kvmd/validators/basic.py | 2 +
kvmd/validators/ugpio.py | 2 +
kvmd/yamlconf/__init__.py | 2 +
testenv/linters/mypy.ini | 2 +-
testenv/tests/apps/kvmd/test_auth.py | 2 +
testenv/tests/plugins/auth/test_pam.py | 2 +
100 files changed, 290 insertions(+), 104 deletions(-)
diff --git a/genmap.py b/genmap.py
index 61952c9e..f9af235b 100755
--- a/genmap.py
+++ b/genmap.py
@@ -21,6 +21,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import sys
import csv
import textwrap
diff --git a/kvmd/aiogp.py b/kvmd/aiogp.py
index 3ee0ea2b..2be9a4f7 100644
--- a/kvmd/aiogp.py
+++ b/kvmd/aiogp.py
@@ -20,6 +20,9 @@
# ========================================================================== #
+from __future__ import annotations
+
+import sys
import asyncio
import threading
import dataclasses
@@ -135,7 +138,8 @@ class _DebouncedValue:
self.__notifier = notifier
self.__loop = loop
- self.__queue: "asyncio.Queue[bool]" = asyncio.Queue() # type: ignore
+ queue_kwargs = ({"loop": loop} if sys.version_info < (3, 10) else {})
+ self.__queue: "asyncio.Queue[bool]" = asyncio.Queue(**queue_kwargs) # type: ignore
self.__task = loop.create_task(self.__consumer_task_loop())
def set(self, value: bool) -> None:
diff --git a/kvmd/aiomulti.py b/kvmd/aiomulti.py
index a4537204..b544e741 100644
--- a/kvmd/aiomulti.py
+++ b/kvmd/aiomulti.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import multiprocessing
import queue
diff --git a/kvmd/aioproc.py b/kvmd/aioproc.py
index 376df004..878a490e 100644
--- a/kvmd/aioproc.py
+++ b/kvmd/aioproc.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import signal
import asyncio
diff --git a/kvmd/aiotools.py b/kvmd/aiotools.py
index f400ad3c..847c2dfa 100644
--- a/kvmd/aiotools.py
+++ b/kvmd/aiotools.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import signal
import asyncio
diff --git a/kvmd/apps/__init__.py b/kvmd/apps/__init__.py
index 763c7c79..4a8f7639 100644
--- a/kvmd/apps/__init__.py
+++ b/kvmd/apps/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import sys
import os
import functools
diff --git a/kvmd/apps/edidconf/__init__.py b/kvmd/apps/edidconf/__init__.py
index e21f797b..a6362922 100644
--- a/kvmd/apps/edidconf/__init__.py
+++ b/kvmd/apps/edidconf/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import sys
import os
import subprocess
diff --git a/kvmd/apps/htpasswd/__init__.py b/kvmd/apps/htpasswd/__init__.py
index 9e857abc..007cb87a 100644
--- a/kvmd/apps/htpasswd/__init__.py
+++ b/kvmd/apps/htpasswd/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import sys
import os
import getpass
diff --git a/kvmd/apps/ipmi/__init__.py b/kvmd/apps/ipmi/__init__.py
index 2f6cebd8..1295ca04 100644
--- a/kvmd/apps/ipmi/__init__.py
+++ b/kvmd/apps/ipmi/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from ...clients.kvmd import KvmdClient
from ... import htclient
diff --git a/kvmd/apps/ipmi/server.py b/kvmd/apps/ipmi/server.py
index 2fc897f9..080fbb74 100644
--- a/kvmd/apps/ipmi/server.py
+++ b/kvmd/apps/ipmi/server.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import select
import asyncio
diff --git a/kvmd/apps/janus/__init__.py b/kvmd/apps/janus/__init__.py
index 8489fade..fe96e0a5 100644
--- a/kvmd/apps/janus/__init__.py
+++ b/kvmd/apps/janus/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from .. import init
from .runner import JanusRunner
diff --git a/kvmd/apps/janus/runner.py b/kvmd/apps/janus/runner.py
index 9e426021..8799fc07 100644
--- a/kvmd/apps/janus/runner.py
+++ b/kvmd/apps/janus/runner.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import asyncio
import asyncio.subprocess
import socket
diff --git a/kvmd/apps/janus/stun.py b/kvmd/apps/janus/stun.py
index 41cd86e7..f7e08209 100644
--- a/kvmd/apps/janus/stun.py
+++ b/kvmd/apps/janus/stun.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import asyncio
import socket
import ipaddress
diff --git a/kvmd/apps/kvmd/__init__.py b/kvmd/apps/kvmd/__init__.py
index 088a62ef..01095243 100644
--- a/kvmd/apps/kvmd/__init__.py
+++ b/kvmd/apps/kvmd/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from ...logging import get_logger
from ...plugins.hid import get_hid_class
diff --git a/kvmd/apps/kvmd/api/log.py b/kvmd/apps/kvmd/api/log.py
index c82d6bd9..b3583560 100644
--- a/kvmd/apps/kvmd/api/log.py
+++ b/kvmd/apps/kvmd/api/log.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from aiohttp.web import Request
from aiohttp.web import StreamResponse
diff --git a/kvmd/apps/kvmd/api/msd.py b/kvmd/apps/kvmd/api/msd.py
index 2fa2eb9b..0fb5fce6 100644
--- a/kvmd/apps/kvmd/api/msd.py
+++ b/kvmd/apps/kvmd/api/msd.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import lzma
import time
diff --git a/kvmd/apps/kvmd/auth.py b/kvmd/apps/kvmd/auth.py
index bf979836..6a4a6ad6 100644
--- a/kvmd/apps/kvmd/auth.py
+++ b/kvmd/apps/kvmd/auth.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import secrets
import pyotp
diff --git a/kvmd/apps/kvmd/info/__init__.py b/kvmd/apps/kvmd/info/__init__.py
index 9ede5489..5040c74d 100644
--- a/kvmd/apps/kvmd/info/__init__.py
+++ b/kvmd/apps/kvmd/info/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
from typing import AsyncGenerator
diff --git a/kvmd/apps/kvmd/info/auth.py b/kvmd/apps/kvmd/info/auth.py
index 301cffe3..c07b6042 100644
--- a/kvmd/apps/kvmd/info/auth.py
+++ b/kvmd/apps/kvmd/info/auth.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from typing import AsyncGenerator
from .... import aiotools
diff --git a/kvmd/apps/kvmd/info/base.py b/kvmd/apps/kvmd/info/base.py
index d090ed34..16cd0379 100644
--- a/kvmd/apps/kvmd/info/base.py
+++ b/kvmd/apps/kvmd/info/base.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from typing import AsyncGenerator
diff --git a/kvmd/apps/kvmd/info/extras.py b/kvmd/apps/kvmd/info/extras.py
index a855ad15..02ae2f73 100644
--- a/kvmd/apps/kvmd/info/extras.py
+++ b/kvmd/apps/kvmd/info/extras.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import re
import asyncio
diff --git a/kvmd/apps/kvmd/info/fan.py b/kvmd/apps/kvmd/info/fan.py
index 8f3f69c8..080aa809 100644
--- a/kvmd/apps/kvmd/info/fan.py
+++ b/kvmd/apps/kvmd/info/fan.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import copy
from typing import AsyncGenerator
diff --git a/kvmd/apps/kvmd/info/hw.py b/kvmd/apps/kvmd/info/hw.py
index 81cd1af6..e8a7f8aa 100644
--- a/kvmd/apps/kvmd/info/hw.py
+++ b/kvmd/apps/kvmd/info/hw.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import asyncio
import copy
diff --git a/kvmd/apps/kvmd/info/meta.py b/kvmd/apps/kvmd/info/meta.py
index 996e648a..44154e40 100644
--- a/kvmd/apps/kvmd/info/meta.py
+++ b/kvmd/apps/kvmd/info/meta.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from typing import AsyncGenerator
from ....logging import get_logger
diff --git a/kvmd/apps/kvmd/info/system.py b/kvmd/apps/kvmd/info/system.py
index d4a450de..a541fbfb 100644
--- a/kvmd/apps/kvmd/info/system.py
+++ b/kvmd/apps/kvmd/info/system.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import asyncio
import platform
diff --git a/kvmd/apps/kvmd/ocr.py b/kvmd/apps/kvmd/ocr.py
index 367c0c80..f4e6104a 100644
--- a/kvmd/apps/kvmd/ocr.py
+++ b/kvmd/apps/kvmd/ocr.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import stat
import io
diff --git a/kvmd/apps/kvmd/server.py b/kvmd/apps/kvmd/server.py
index 858ba1b6..1f7fbe56 100644
--- a/kvmd/apps/kvmd/server.py
+++ b/kvmd/apps/kvmd/server.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import dataclasses
from typing import Callable
diff --git a/kvmd/apps/kvmd/streamer.py b/kvmd/apps/kvmd/streamer.py
index 08c48eb1..d1a5b792 100644
--- a/kvmd/apps/kvmd/streamer.py
+++ b/kvmd/apps/kvmd/streamer.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import signal
import asyncio
import asyncio.subprocess
diff --git a/kvmd/apps/kvmd/switch/__init__.py b/kvmd/apps/kvmd/switch/__init__.py
index 49bfbd7d..9d178b3f 100644
--- a/kvmd/apps/kvmd/switch/__init__.py
+++ b/kvmd/apps/kvmd/switch/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import asyncio
@@ -295,17 +297,16 @@ class Switch: # pylint: disable=too-many-public-methods
async def __systask_events(self) -> None:
async for event in self.__chain.poll_events():
- match event:
- case DeviceFoundEvent():
- await self.__load_configs()
- case ChainTruncatedEvent():
- self.__cache.truncate(event.units)
- case PortActivatedEvent():
- self.__cache.update_active_port(event.port)
- case UnitStateEvent():
- self.__cache.update_unit_state(event.unit, event.state)
- case UnitAtxLedsEvent():
- self.__cache.update_unit_atx_leds(event.unit, event.atx_leds)
+ if event == DeviceFoundEvent():
+ await self.__load_configs()
+ elif event == ChainTruncatedEvent():
+ self.__cache.truncate(event.units)
+ elif event == PortActivatedEvent():
+ self.__cache.update_active_port(event.port)
+ elif event == UnitStateEvent():
+ self.__cache.update_unit_state(event.unit, event.state)
+ elif event == UnitAtxLedsEvent():
+ self.__cache.update_unit_atx_leds(event.unit, event.atx_leds)
async def __load_configs(self) -> None:
async with self.__lock:
diff --git a/kvmd/apps/kvmd/switch/chain.py b/kvmd/apps/kvmd/switch/chain.py
index 8e4d94eb..916af547 100644
--- a/kvmd/apps/kvmd/switch/chain.py
+++ b/kvmd/apps/kvmd/switch/chain.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import multiprocessing
import queue
import select
@@ -310,59 +312,57 @@ class Chain: # pylint: disable=too-many-instance-attributes
def __consume_commands(self) -> None:
while not self.__cmd_queue.empty():
cmd = self.__cmd_queue.get()
- match cmd:
- case _CmdSetActual():
- self.__actual = cmd.actual
-
- case _CmdSetActivePort():
- # Может быть вызвано изнутри при синхронизации
- self.__active_port = cmd.port
- self.__queue_event(PortActivatedEvent(self.__active_port))
-
- case _CmdSetPortBeacon():
- (unit, ch) = self.get_real_unit_channel(cmd.port)
- self.__device.request_beacon(unit, ch, cmd.on)
-
- case _CmdSetUnitBeacon():
- ch = (4 if cmd.downlink else 5)
- self.__device.request_beacon(cmd.unit, ch, cmd.on)
-
- case _CmdAtxClick():
- (unit, ch) = self.get_real_unit_channel(cmd.port)
- if unit < len(self.__units):
- (allowed, powered) = self.__units[unit].is_atx_allowed(ch)
- if allowed and (cmd.if_powered is None or cmd.if_powered == powered):
- delay_ms = min(int(cmd.delay * 1000), 0xFFFF)
- if cmd.reset:
- self.__device.request_atx_cr(unit, ch, delay_ms)
- else:
- self.__device.request_atx_cp(unit, ch, delay_ms)
-
- case _CmdSetEdids():
- self.__edids = cmd.edids
-
- case _CmdSetColors():
- self.__colors = cmd.colors
-
- case _CmdRebootUnit():
- self.__device.request_reboot(cmd.unit, cmd.bootloader)
+ if cmd == _CmdSetActual():
+ self.__actual = cmd.actual
+
+ elif cmd == _CmdSetActivePort():
+ # Может быть вызвано изнутри при синхронизации
+ self.__active_port = cmd.port
+ self.__queue_event(PortActivatedEvent(self.__active_port))
+
+ elif cmd == _CmdSetPortBeacon():
+ (unit, ch) = self.get_real_unit_channel(cmd.port)
+ self.__device.request_beacon(unit, ch, cmd.on)
+
+ elif cmd == _CmdSetUnitBeacon():
+ ch = (4 if cmd.downlink else 5)
+ self.__device.request_beacon(cmd.unit, ch, cmd.on)
+
+ elif cmd == _CmdAtxClick():
+ (unit, ch) = self.get_real_unit_channel(cmd.port)
+ if unit < len(self.__units):
+ (allowed, powered) = self.__units[unit].is_atx_allowed(ch)
+ if allowed and (cmd.if_powered is None or cmd.if_powered == powered):
+ delay_ms = min(int(cmd.delay * 1000), 0xFFFF)
+ if cmd.reset:
+ self.__device.request_atx_cr(unit, ch, delay_ms)
+ else:
+ self.__device.request_atx_cp(unit, ch, delay_ms)
+
+ elif cmd == _CmdSetEdids():
+ self.__edids = cmd.edids
+
+ elif cmd == _CmdSetColors():
+ self.__colors = cmd.colors
+
+ elif cmd == _CmdRebootUnit():
+ self.__device.request_reboot(cmd.unit, cmd.bootloader)
def __update_units(self, resp: Response) -> None:
units = resp.header.unit + 1
while len(self.__units) < units:
self.__units.append(_UnitContext())
- match resp.body:
- case UnitState():
- if not resp.body.flags.has_downlink and len(self.__units) > units:
- del self.__units[units:]
- self.__queue_event(ChainTruncatedEvent(units))
- self.__units[resp.header.unit].state = resp.body
- self.__queue_event(UnitStateEvent(resp.header.unit, resp.body))
-
- case UnitAtxLeds():
- self.__units[resp.header.unit].atx_leds = resp.body
- self.__queue_event(UnitAtxLedsEvent(resp.header.unit, resp.body))
+ if resp.body == UnitState():
+ if not resp.body.flags.has_downlink and len(self.__units) > units:
+ del self.__units[units:]
+ self.__queue_event(ChainTruncatedEvent(units))
+ self.__units[resp.header.unit].state = resp.body
+ self.__queue_event(UnitStateEvent(resp.header.unit, resp.body))
+
+ elif resp.body == UnitAtxLeds():
+ self.__units[resp.header.unit].atx_leds = resp.body
+ self.__queue_event(UnitAtxLedsEvent(resp.header.unit, resp.body))
def __adjust_start_port(self) -> None:
if self.__active_port < 0:
diff --git a/kvmd/apps/kvmd/switch/device.py b/kvmd/apps/kvmd/switch/device.py
index b56cc406..44548e0a 100644
--- a/kvmd/apps/kvmd/switch/device.py
+++ b/kvmd/apps/kvmd/switch/device.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import random
import types
diff --git a/kvmd/apps/kvmd/switch/proto.py b/kvmd/apps/kvmd/switch/proto.py
index d4f43f84..13a3af80 100644
--- a/kvmd/apps/kvmd/switch/proto.py
+++ b/kvmd/apps/kvmd/switch/proto.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import struct
import dataclasses
@@ -284,12 +286,11 @@ class Response:
@classmethod
def unpack(cls, msg: bytes) -> Optional["Response"]:
header = Header.unpack(msg)
- match header.op:
- case Header.NAK:
- return Response(header, Nak.unpack(msg, Header.SIZE))
- case Header.STATE:
- return Response(header, UnitState.unpack(msg, Header.SIZE))
- case Header.ATX_LEDS:
- return Response(header, UnitAtxLeds.unpack(msg, Header.SIZE))
+ if header.op == Header.NAK:
+ return Response(header, Nak.unpack(msg, Header.SIZE))
+ elif header.op == Header.STATE:
+ return Response(header, UnitState.unpack(msg, Header.SIZE))
+ elif header.op == Header.ATX_LEDS:
+ return Response(header, UnitAtxLeds.unpack(msg, Header.SIZE))
# raise RuntimeError(f"Unknown OP in the header: {header!r}")
return None
diff --git a/kvmd/apps/kvmd/switch/state.py b/kvmd/apps/kvmd/switch/state.py
index e49d0062..5d0b7ac5 100644
--- a/kvmd/apps/kvmd/switch/state.py
+++ b/kvmd/apps/kvmd/switch/state.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import dataclasses
import time
diff --git a/kvmd/apps/kvmd/switch/types.py b/kvmd/apps/kvmd/switch/types.py
index 32225f06..5f47edef 100644
--- a/kvmd/apps/kvmd/switch/types.py
+++ b/kvmd/apps/kvmd/switch/types.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import re
import struct
import uuid
diff --git a/kvmd/apps/kvmd/sysunit.py b/kvmd/apps/kvmd/sysunit.py
index bcb41c34..f9f02f55 100644
--- a/kvmd/apps/kvmd/sysunit.py
+++ b/kvmd/apps/kvmd/sysunit.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import types
import dbus_next
diff --git a/kvmd/apps/kvmd/ugpio.py b/kvmd/apps/kvmd/ugpio.py
index a3c453f5..31eb3060 100644
--- a/kvmd/apps/kvmd/ugpio.py
+++ b/kvmd/apps/kvmd/ugpio.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import copy
diff --git a/kvmd/apps/media/__init__.py b/kvmd/apps/media/__init__.py
index 325a817c..baa4ce69 100644
--- a/kvmd/apps/media/__init__.py
+++ b/kvmd/apps/media/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from ...clients.streamer import StreamerFormats
from ...clients.streamer import MemsinkStreamerClient
diff --git a/kvmd/apps/media/server.py b/kvmd/apps/media/server.py
index 1f96b353..954f93f5 100644
--- a/kvmd/apps/media/server.py
+++ b/kvmd/apps/media/server.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import dataclasses
diff --git a/kvmd/apps/ngxmkconf/__init__.py b/kvmd/apps/ngxmkconf/__init__.py
index 67c25bcb..954dade3 100644
--- a/kvmd/apps/ngxmkconf/__init__.py
+++ b/kvmd/apps/ngxmkconf/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import argparse
diff --git a/kvmd/apps/otg/__init__.py b/kvmd/apps/otg/__init__.py
index e1e886cb..8c50e55d 100644
--- a/kvmd/apps/otg/__init__.py
+++ b/kvmd/apps/otg/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import re
import shutil
diff --git a/kvmd/apps/otg/hid/keyboard.py b/kvmd/apps/otg/hid/keyboard.py
index e3232afa..bc0c0a4a 100644
--- a/kvmd/apps/otg/hid/keyboard.py
+++ b/kvmd/apps/otg/hid/keyboard.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from . import Hid
diff --git a/kvmd/apps/otg/hid/mouse.py b/kvmd/apps/otg/hid/mouse.py
index 2fcb578c..85134426 100644
--- a/kvmd/apps/otg/hid/mouse.py
+++ b/kvmd/apps/otg/hid/mouse.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from . import Hid
diff --git a/kvmd/apps/otgconf/__init__.py b/kvmd/apps/otgconf/__init__.py
index b57f0df1..f58334a6 100644
--- a/kvmd/apps/otgconf/__init__.py
+++ b/kvmd/apps/otgconf/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import json
import contextlib
diff --git a/kvmd/apps/otgmsd/__init__.py b/kvmd/apps/otgmsd/__init__.py
index a289307f..b0761c83 100644
--- a/kvmd/apps/otgmsd/__init__.py
+++ b/kvmd/apps/otgmsd/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import errno
import argparse
diff --git a/kvmd/apps/otgnet/__init__.py b/kvmd/apps/otgnet/__init__.py
index 35c0bc45..313bce2d 100644
--- a/kvmd/apps/otgnet/__init__.py
+++ b/kvmd/apps/otgnet/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import ipaddress
import dataclasses
diff --git a/kvmd/apps/pst/__init__.py b/kvmd/apps/pst/__init__.py
index d6ff2896..6327cd9d 100644
--- a/kvmd/apps/pst/__init__.py
+++ b/kvmd/apps/pst/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from ...logging import get_logger
from .. import init
diff --git a/kvmd/apps/pstrun/__init__.py b/kvmd/apps/pstrun/__init__.py
index d55835fd..385f6060 100644
--- a/kvmd/apps/pstrun/__init__.py
+++ b/kvmd/apps/pstrun/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import sys
import os
import signal
diff --git a/kvmd/apps/swctl/__init__.py b/kvmd/apps/swctl/__init__.py
index d5915d74..831650a4 100644
--- a/kvmd/apps/swctl/__init__.py
+++ b/kvmd/apps/swctl/__init__.py
@@ -132,29 +132,27 @@ def main() -> None: # pylint: disable=too-many-statements
with Device(opts.device) as device:
wait_rid: (int | None) = None
- match opts.cmd:
- case "poll":
- device.request_state()
- device.request_atx_leds()
- case "state":
- wait_rid = device.request_state()
- case "bootloader" | "reboot":
- device.request_reboot(opts.unit, (opts.cmd == "bootloader"))
- raise SystemExit()
- case "switch":
- wait_rid = device.request_switch(opts.unit, opts.port)
- case "leds":
- wait_rid = device.request_atx_leds()
- case "click":
- match opts.button:
- case "power":
- wait_rid = device.request_atx_cp(opts.unit, opts.port, opts.delay_ms)
- case "reset":
- wait_rid = device.request_atx_cr(opts.unit, opts.port, opts.delay_ms)
- case "beacon":
- wait_rid = device.request_beacon(opts.unit, opts.port, (opts.on == "on"))
- case "set-edid":
- wait_rid = device.request_set_edid(opts.unit, opts.port, opts.edid)
+ if opts.cmd == "poll":
+ device.request_state()
+ device.request_atx_leds()
+ elif opts.cmd == "state":
+ wait_rid = device.request_state()
+ elif opts.cmd == "bootloader" | "reboot":
+ device.request_reboot(opts.unit, (opts.cmd == "bootloader"))
+ raise SystemExit()
+ elif opts.cmd == "switch":
+ wait_rid = device.request_switch(opts.unit, opts.port)
+ elif opts.cmd == "leds":
+ wait_rid = device.request_atx_leds()
+ elif opts.cmd == "click":
+ if opts.button == "power":
+ wait_rid = device.request_atx_cp(opts.unit, opts.port, opts.delay_ms)
+ elif opts.button == "reset":
+ wait_rid = device.request_atx_cr(opts.unit, opts.port, opts.delay_ms)
+ elif opts.cmd == "beacon":
+ wait_rid = device.request_beacon(opts.unit, opts.port, (opts.on == "on"))
+ elif opts.cmd == "set-edid":
+ wait_rid = device.request_set_edid(opts.unit, opts.port, opts.edid)
error_ts = time.monotonic() + 1
while True:
diff --git a/kvmd/apps/totp/__init__.py b/kvmd/apps/totp/__init__.py
index e61a79b5..4fd9650c 100644
--- a/kvmd/apps/totp/__init__.py
+++ b/kvmd/apps/totp/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import socket
import argparse
diff --git a/kvmd/apps/vnc/__init__.py b/kvmd/apps/vnc/__init__.py
index 1e2c486a..d972d806 100644
--- a/kvmd/apps/vnc/__init__.py
+++ b/kvmd/apps/vnc/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from ...clients.kvmd import KvmdClient
from ...clients.streamer import StreamerFormats
from ...clients.streamer import BaseStreamerClient
diff --git a/kvmd/apps/vnc/rfb/encodings.py b/kvmd/apps/vnc/rfb/encodings.py
index 940a383f..44c1f808 100644
--- a/kvmd/apps/vnc/rfb/encodings.py
+++ b/kvmd/apps/vnc/rfb/encodings.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import dataclasses
from typing import Any
diff --git a/kvmd/apps/vnc/rfb/stream.py b/kvmd/apps/vnc/rfb/stream.py
index dc3ceb1b..53add06f 100644
--- a/kvmd/apps/vnc/rfb/stream.py
+++ b/kvmd/apps/vnc/rfb/stream.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import ssl
import struct
diff --git a/kvmd/apps/vnc/server.py b/kvmd/apps/vnc/server.py
index b2ae71fa..a182a2fb 100644
--- a/kvmd/apps/vnc/server.py
+++ b/kvmd/apps/vnc/server.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import asyncio
import socket
diff --git a/kvmd/apps/watchdog/__init__.py b/kvmd/apps/watchdog/__init__.py
index c2b03730..71f0f058 100644
--- a/kvmd/apps/watchdog/__init__.py
+++ b/kvmd/apps/watchdog/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import argparse
import errno
import time
diff --git a/kvmd/clients/__init__.py b/kvmd/clients/__init__.py
index e917c9f6..06f871aa 100644
--- a/kvmd/clients/__init__.py
+++ b/kvmd/clients/__init__.py
@@ -20,10 +20,11 @@
# ========================================================================== #
+from __future__ import annotations
+
import types
from typing import Callable
-from typing import Self
import aiohttp
@@ -44,7 +45,7 @@ class BaseHttpClientSession:
await self.__http_session.close()
self.__http_session = None
- async def __aenter__(self) -> Self:
+ async def __aenter__(self):
return self
async def __aexit__(
diff --git a/kvmd/clients/kvmd.py b/kvmd/clients/kvmd.py
index d9b38339..439f62b2 100644
--- a/kvmd/clients/kvmd.py
+++ b/kvmd/clients/kvmd.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import contextlib
import struct
diff --git a/kvmd/edid.py b/kvmd/edid.py
index bfa62e3c..0d563a8c 100644
--- a/kvmd/edid.py
+++ b/kvmd/edid.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import re
import dataclasses
diff --git a/kvmd/htclient.py b/kvmd/htclient.py
index 5978b189..2fa795b3 100644
--- a/kvmd/htclient.py
+++ b/kvmd/htclient.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import contextlib
diff --git a/kvmd/htserver.py b/kvmd/htserver.py
index 1ef3cc48..62eeab5f 100644
--- a/kvmd/htserver.py
+++ b/kvmd/htserver.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import socket
import asyncio
diff --git a/kvmd/inotify.py b/kvmd/inotify.py
index e2cc6251..7d282d96 100644
--- a/kvmd/inotify.py
+++ b/kvmd/inotify.py
@@ -22,6 +22,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import sys
import os
import asyncio
diff --git a/kvmd/logging.py b/kvmd/logging.py
index a31dc24d..673ff233 100644
--- a/kvmd/logging.py
+++ b/kvmd/logging.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import sys
import types
import logging
diff --git a/kvmd/plugins/atx/gpio.py b/kvmd/plugins/atx/gpio.py
index 578d2717..e441e655 100644
--- a/kvmd/plugins/atx/gpio.py
+++ b/kvmd/plugins/atx/gpio.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import copy
diff --git a/kvmd/plugins/auth/http.py b/kvmd/plugins/auth/http.py
index b59218aa..4869737c 100644
--- a/kvmd/plugins/auth/http.py
+++ b/kvmd/plugins/auth/http.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import aiohttp
import aiohttp.web
diff --git a/kvmd/plugins/hid/__init__.py b/kvmd/plugins/hid/__init__.py
index a385023a..240bc51b 100644
--- a/kvmd/plugins/hid/__init__.py
+++ b/kvmd/plugins/hid/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import functools
import time
diff --git a/kvmd/plugins/hid/_mcu/__init__.py b/kvmd/plugins/hid/_mcu/__init__.py
index d6f04f76..124f98f0 100644
--- a/kvmd/plugins/hid/_mcu/__init__.py
+++ b/kvmd/plugins/hid/_mcu/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import multiprocessing
import contextlib
import queue
diff --git a/kvmd/plugins/hid/_mcu/gpio.py b/kvmd/plugins/hid/_mcu/gpio.py
index ce1d678b..678edc3c 100644
--- a/kvmd/plugins/hid/_mcu/gpio.py
+++ b/kvmd/plugins/hid/_mcu/gpio.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import types
import time
diff --git a/kvmd/plugins/hid/bt/__init__.py b/kvmd/plugins/hid/bt/__init__.py
index 0c95a6d5..534e7896 100644
--- a/kvmd/plugins/hid/bt/__init__.py
+++ b/kvmd/plugins/hid/bt/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import multiprocessing
import copy
import time
diff --git a/kvmd/plugins/hid/bt/bluez.py b/kvmd/plugins/hid/bt/bluez.py
index 3e6e3f43..41076141 100644
--- a/kvmd/plugins/hid/bt/bluez.py
+++ b/kvmd/plugins/hid/bt/bluez.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import types
from typing import Any
diff --git a/kvmd/plugins/hid/bt/server.py b/kvmd/plugins/hid/bt/server.py
index ad2b6982..0679d99b 100644
--- a/kvmd/plugins/hid/bt/server.py
+++ b/kvmd/plugins/hid/bt/server.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import socket
import select
import multiprocessing
diff --git a/kvmd/plugins/hid/ch9329/__init__.py b/kvmd/plugins/hid/ch9329/__init__.py
index 1b235090..d92fadd9 100644
--- a/kvmd/plugins/hid/ch9329/__init__.py
+++ b/kvmd/plugins/hid/ch9329/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import multiprocessing
import queue
import copy
diff --git a/kvmd/plugins/hid/ch9329/mouse.py b/kvmd/plugins/hid/ch9329/mouse.py
index d61bab4e..5372434f 100644
--- a/kvmd/plugins/hid/ch9329/mouse.py
+++ b/kvmd/plugins/hid/ch9329/mouse.py
@@ -43,19 +43,16 @@ class Mouse: # pylint: disable=too-many-instance-attributes
def is_absolute(self) -> bool:
return self.__absolute
+ button_code = {
+ "left": 0x01,
+ "right": 0x02,
+ "middle": 0x04,
+ "up": 0x08,
+ "down": 0x10,
+ }
+
def process_button(self, button: str, state: bool) -> bytes:
- code = 0x00
- match button:
- case "left":
- code = 0x01
- case "right":
- code = 0x02
- case "middle":
- code = 0x04
- case "up":
- code = 0x08
- case "down":
- code = 0x10
+ code = button_code.get(button, 0x00)
if code:
if state:
self.__buttons |= code
diff --git a/kvmd/plugins/hid/otg/__init__.py b/kvmd/plugins/hid/otg/__init__.py
index 25424257..f87bc0c8 100644
--- a/kvmd/plugins/hid/otg/__init__.py
+++ b/kvmd/plugins/hid/otg/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import copy
from typing import AsyncGenerator
diff --git a/kvmd/plugins/hid/otg/device.py b/kvmd/plugins/hid/otg/device.py
index a3bc2739..8b3479f0 100644
--- a/kvmd/plugins/hid/otg/device.py
+++ b/kvmd/plugins/hid/otg/device.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import select
import multiprocessing
diff --git a/kvmd/plugins/hid/otg/events.py b/kvmd/plugins/hid/otg/events.py
index 44f5e373..f094bb2d 100644
--- a/kvmd/plugins/hid/otg/events.py
+++ b/kvmd/plugins/hid/otg/events.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import struct
import dataclasses
diff --git a/kvmd/plugins/hid/otg/keyboard.py b/kvmd/plugins/hid/otg/keyboard.py
index e82d95a3..3ac199d1 100644
--- a/kvmd/plugins/hid/otg/keyboard.py
+++ b/kvmd/plugins/hid/otg/keyboard.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from typing import Generator
from typing import Any
diff --git a/kvmd/plugins/hid/otg/mouse.py b/kvmd/plugins/hid/otg/mouse.py
index ae8d53b0..beef0c33 100644
--- a/kvmd/plugins/hid/otg/mouse.py
+++ b/kvmd/plugins/hid/otg/mouse.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from typing import Generator
from typing import Any
diff --git a/kvmd/plugins/hid/spi.py b/kvmd/plugins/hid/spi.py
index cf58b5de..570f226d 100644
--- a/kvmd/plugins/hid/spi.py
+++ b/kvmd/plugins/hid/spi.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import contextlib
import time
diff --git a/kvmd/plugins/msd/__init__.py b/kvmd/plugins/msd/__init__.py
index b2f9d50e..0e8c5b0b 100644
--- a/kvmd/plugins/msd/__init__.py
+++ b/kvmd/plugins/msd/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import contextlib
import time
diff --git a/kvmd/plugins/msd/disabled.py b/kvmd/plugins/msd/disabled.py
index b9f14f6e..1f6b7df3 100644
--- a/kvmd/plugins/msd/disabled.py
+++ b/kvmd/plugins/msd/disabled.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import contextlib
from typing import AsyncGenerator
diff --git a/kvmd/plugins/msd/otg/__init__.py b/kvmd/plugins/msd/otg/__init__.py
index 6d0dd776..6fb43f02 100644
--- a/kvmd/plugins/msd/otg/__init__.py
+++ b/kvmd/plugins/msd/otg/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import contextlib
import dataclasses
diff --git a/kvmd/plugins/ugpio/__init__.py b/kvmd/plugins/ugpio/__init__.py
index 6f9dfaec..d4f9b3a2 100644
--- a/kvmd/plugins/ugpio/__init__.py
+++ b/kvmd/plugins/ugpio/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from typing import Callable
from typing import Any
diff --git a/kvmd/plugins/ugpio/ezcoo.py b/kvmd/plugins/ugpio/ezcoo.py
index d5bd8ef8..b0aa96d8 100644
--- a/kvmd/plugins/ugpio/ezcoo.py
+++ b/kvmd/plugins/ugpio/ezcoo.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import re
import multiprocessing
import functools
diff --git a/kvmd/plugins/ugpio/gpio.py b/kvmd/plugins/ugpio/gpio.py
index 6cda826b..e2720af9 100644
--- a/kvmd/plugins/ugpio/gpio.py
+++ b/kvmd/plugins/ugpio/gpio.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from typing import Callable
from typing import Any
diff --git a/kvmd/plugins/ugpio/hidrelay.py b/kvmd/plugins/ugpio/hidrelay.py
index 17f41e27..c4e44ca6 100644
--- a/kvmd/plugins/ugpio/hidrelay.py
+++ b/kvmd/plugins/ugpio/hidrelay.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import contextlib
import functools
diff --git a/kvmd/plugins/ugpio/hue.py b/kvmd/plugins/ugpio/hue.py
index 9ed9e206..581cd759 100644
--- a/kvmd/plugins/ugpio/hue.py
+++ b/kvmd/plugins/ugpio/hue.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
from typing import Callable
diff --git a/kvmd/plugins/ugpio/ipmi.py b/kvmd/plugins/ugpio/ipmi.py
index 37a7a16f..7c364115 100644
--- a/kvmd/plugins/ugpio/ipmi.py
+++ b/kvmd/plugins/ugpio/ipmi.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import functools
diff --git a/kvmd/plugins/ugpio/locator.py b/kvmd/plugins/ugpio/locator.py
index d5cba719..26d3c277 100644
--- a/kvmd/plugins/ugpio/locator.py
+++ b/kvmd/plugins/ugpio/locator.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
from typing import Callable
diff --git a/kvmd/plugins/ugpio/pway.py b/kvmd/plugins/ugpio/pway.py
index 140cf02a..ba69a90a 100644
--- a/kvmd/plugins/ugpio/pway.py
+++ b/kvmd/plugins/ugpio/pway.py
@@ -22,6 +22,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import re
import multiprocessing
import functools
diff --git a/kvmd/plugins/ugpio/pwm.py b/kvmd/plugins/ugpio/pwm.py
index f202836e..6fa0092d 100644
--- a/kvmd/plugins/ugpio/pwm.py
+++ b/kvmd/plugins/ugpio/pwm.py
@@ -21,6 +21,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from typing import Callable
from typing import Any
diff --git a/kvmd/plugins/ugpio/tesmart.py b/kvmd/plugins/ugpio/tesmart.py
index bb1d39e1..4be48844 100644
--- a/kvmd/plugins/ugpio/tesmart.py
+++ b/kvmd/plugins/ugpio/tesmart.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import functools
diff --git a/kvmd/plugins/ugpio/wol.py b/kvmd/plugins/ugpio/wol.py
index e3a93be7..14f35fe8 100644
--- a/kvmd/plugins/ugpio/wol.py
+++ b/kvmd/plugins/ugpio/wol.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import socket
import functools
diff --git a/kvmd/plugins/ugpio/xh_hk4401.py b/kvmd/plugins/ugpio/xh_hk4401.py
index d7a47679..1004db39 100644
--- a/kvmd/plugins/ugpio/xh_hk4401.py
+++ b/kvmd/plugins/ugpio/xh_hk4401.py
@@ -21,6 +21,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import re
import multiprocessing
import functools
diff --git a/kvmd/tools.py b/kvmd/tools.py
index 6dd7d2f9..63845e72 100644
--- a/kvmd/tools.py
+++ b/kvmd/tools.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import asyncio
import operator
import functools
diff --git a/kvmd/validators/__init__.py b/kvmd/validators/__init__.py
index aa997ab9..d571b6a4 100644
--- a/kvmd/validators/__init__.py
+++ b/kvmd/validators/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import re
from typing import Mapping
diff --git a/kvmd/validators/basic.py b/kvmd/validators/basic.py
index eae844d9..27d39615 100644
--- a/kvmd/validators/basic.py
+++ b/kvmd/validators/basic.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import re
from typing import Type
diff --git a/kvmd/validators/ugpio.py b/kvmd/validators/ugpio.py
index 1cb0e3e4..6aadbccf 100644
--- a/kvmd/validators/ugpio.py
+++ b/kvmd/validators/ugpio.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
from typing import Any
from . import raise_error
diff --git a/kvmd/yamlconf/__init__.py b/kvmd/yamlconf/__init__.py
index 7cd3808d..7c86ef27 100644
--- a/kvmd/yamlconf/__init__.py
+++ b/kvmd/yamlconf/__init__.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import contextlib
import json
diff --git a/testenv/linters/mypy.ini b/testenv/linters/mypy.ini
index d436fd2c..00dd6881 100644
--- a/testenv/linters/mypy.ini
+++ b/testenv/linters/mypy.ini
@@ -1,5 +1,5 @@
[mypy]
-python_version = 3.11
+python_version = 3.9
ignore_missing_imports = true
disallow_untyped_defs = true
strict_optional = true
diff --git a/testenv/tests/apps/kvmd/test_auth.py b/testenv/tests/apps/kvmd/test_auth.py
index 4fa1c8ae..40df3168 100644
--- a/testenv/tests/apps/kvmd/test_auth.py
+++ b/testenv/tests/apps/kvmd/test_auth.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import contextlib
diff --git a/testenv/tests/plugins/auth/test_pam.py b/testenv/tests/plugins/auth/test_pam.py
index 26bf11be..b1d57c16 100644
--- a/testenv/tests/plugins/auth/test_pam.py
+++ b/testenv/tests/plugins/auth/test_pam.py
@@ -20,6 +20,8 @@
# ========================================================================== #
+from __future__ import annotations
+
import os
import asyncio
import pwd
--
2.51.1