Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 39 additions & 43 deletions test/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python3
#
# This file is formatted with ruff format
#
# Run with pytest:
Expand All @@ -20,16 +18,14 @@
# - WacomDevice, WacomDatabase, ...: pythonic wrappers around the
# underlying C object.

from ctypes import c_char_p, c_char, c_int, c_uint32, c_void_p
from typing import Optional, Tuple, Type, List
from dataclasses import dataclass
from pathlib import Path

import ctypes
import enum
import itertools
import logging

from ctypes import c_char, c_char_p, c_int, c_uint32, c_void_p
from dataclasses import dataclass
from pathlib import Path
from typing import ClassVar

logger = logging.getLogger(__name__)

Expand All @@ -40,8 +36,8 @@
@dataclass
class _Api:
name: str
args: Tuple[Type[ctypes._SimpleCData], ...]
return_type: Optional[Type[ctypes._SimpleCData]]
args: tuple[type[ctypes._SimpleCData], ...]
return_type: type[ctypes._SimpleCData] | None

@property
def basename(self) -> str:
Expand All @@ -61,7 +57,7 @@ def basename(self) -> str:
class GlibC:
_lib = None

_api_prototypes: List[_Api] = [
_api_prototypes: ClassVar[list[_Api]] = [
_Api(name="free", args=(c_void_p,), return_type=None),
]

Expand Down Expand Up @@ -127,7 +123,7 @@ def instance(cls):
cls._load()
return cls

_api_prototypes: List[_Api] = [
_api_prototypes: ClassVar[list[_Api]] = [
_Api(name="libwacom_error_new", args=(c_void_p,), return_type=c_void_p),
_Api(name="libwacom_error_free", args=(c_void_p,), return_type=None),
_Api(name="libwacom_error_get_code", args=(c_void_p,), return_type=c_int),
Expand Down Expand Up @@ -329,7 +325,7 @@ def instance(cls):
),
]

_enums: List[_Enum] = [
_enums: ClassVar[list[_Enum]] = [
_Enum(name="WERROR_NONE", value=0),
_Enum(name="WERROR_BAD_ALLOC", value=1),
_Enum(name="WERROR_INVALID_PATH", value=2),
Expand Down Expand Up @@ -439,12 +435,12 @@ def wrapper(func):
setattr(self, api.basename.removeprefix("match_"), wrapper(func))

@property
def name(self) -> Optional[str]:
def name(self) -> str | None:
name = self.get_name()
return name.decode("utf-8") if name else None

@property
def uniq(self) -> Optional[str]:
def uniq(self) -> str | None:
uniq = self.get_uniq()
return uniq.decode("utf-8") if uniq else None

Expand Down Expand Up @@ -482,23 +478,23 @@ def wrapper(func):
setattr(self, api.basename.removeprefix("builder_"), wrapper(func))

@property
def device_name(self) -> Optional[str]:
def device_name(self) -> str | None:
return self._device_name

@property
def match_name(self) -> Optional[str]:
def match_name(self) -> str | None:
return self._match_name

@property
def uniq(self) -> Optional[str]:
def uniq(self) -> str | None:
return self._uniq

@property
def bustype(self) -> Optional[WacomBustype]:
def bustype(self) -> WacomBustype | None:
return self._bustype

@property
def usbid(self) -> Optional[Tuple[int, int]]:
def usbid(self) -> tuple[int, int] | None:
return self._usbid

@bustype.setter
Expand All @@ -507,7 +503,7 @@ def bustype(self, bus: WacomBustype):
self.set_bustype(bus.value)

@usbid.setter
def usbid(self, usbid: Tuple[int, int]):
def usbid(self, usbid: tuple[int, int]):
self._usbid = usbid
self.set_usbid(usbid[0], usbid[1])

Expand All @@ -529,11 +525,11 @@ def uniq(self, uniq: str):
@classmethod
def create(
cls,
device_name: Optional[str] = None,
match_name: Optional[str] = None,
uniq: Optional[str] = None,
usbid: Optional[Tuple[int, int]] = None,
bus: Optional[WacomBustype] = None,
device_name: str | None = None,
match_name: str | None = None,
uniq: str | None = None,
usbid: tuple[int, int] | None = None,
bus: WacomBustype | None = None,
) -> "WacomBuilder":
lib = LibWacom.instance()
builder = WacomBuilder(lib.builder_new())
Expand Down Expand Up @@ -660,7 +656,7 @@ def stylus_type(self) -> WacomStylusType:
def eraser_type(self) -> WacomEraserType:
return WacomEraserType(self.get_eraser_type())

def get_paired_styli(self) -> List["WacomStylus"]:
def get_paired_styli(self) -> list["WacomStylus"]:
lib = LibWacom.instance()
paired = lib.stylus_get_paired_styli(self.stylus, None)
styli = [
Expand Down Expand Up @@ -705,7 +701,7 @@ class ButtonFlags(enum.IntEnum):
DIAL2_MODESWITCH = 1 << 11

@staticmethod
def modeswitch_flags() -> List["WacomDevice.ButtonFlags"]:
def modeswitch_flags() -> list["WacomDevice.ButtonFlags"]:
return [
WacomDevice.ButtonFlags.RING_MODESWITCH,
WacomDevice.ButtonFlags.RING2_MODESWITCH,
Expand Down Expand Up @@ -745,12 +741,12 @@ def wrapper(func):
val = getattr(lib, e.basename)
setattr(self, e.basename, val)

def get_paired_device(self) -> Optional[WacomMatch]:
def get_paired_device(self) -> WacomMatch | None:
lib = LibWacom.instance()
match = lib.get_paired_device(self.device)
return WacomMatch(match) if match else None

def get_matches(self) -> List[WacomMatch]:
def get_matches(self) -> list[WacomMatch]:
lib = LibWacom.instance()
matches = lib.get_matches(self.device)

Expand All @@ -759,7 +755,7 @@ def get_matches(self) -> List[WacomMatch]:
for m in itertools.takewhile(lambda ptr: ptr is not None, matches)
]

def get_styli(self) -> List[WacomStylus]:
def get_styli(self) -> list[WacomStylus]:
lib = LibWacom.instance()
styli = lib.get_styli(self.device, None)

Expand All @@ -774,7 +770,7 @@ def __del__(self):
lib.destroy(self.device)

@property
def paired_device(self) -> Optional[WacomMatch]:
def paired_device(self) -> WacomMatch | None:
return self.get_paired_device()

@property
Expand Down Expand Up @@ -864,11 +860,11 @@ def matches(self):
return self.get_matches()

@property
def integration_flags(self) -> List[IntegrationFlags]:
def integration_flags(self) -> list[IntegrationFlags]:
flags = self.get_integration_flags()
return [f for f in WacomDevice.IntegrationFlags if f & flags != 0]

def button_flags(self, button: str) -> List[ButtonFlags]:
def button_flags(self, button: str) -> list[ButtonFlags]:
flags = self.get_button_flag(button.encode("utf-8"))
return [f for f in WacomDevice.ButtonFlags if f & flags != 0]

Expand All @@ -879,11 +875,11 @@ def button_modeswitch_mode(self, button: str) -> ModeSwitch:
mode = self.get_button_modeswitch_mode(button.encode("utf-8"))
return WacomDevice.ModeSwitch(mode)

def button_led_group(self, button: str) -> List[ButtonFlags]:
def button_led_group(self, button: str) -> list[ButtonFlags]:
return self.get_button_led_group(button.encode("utf-8"))

@property
def status_leds(self) -> List["WacomStatusLed"]:
def status_leds(self) -> list["WacomStatusLed"]:
nleds = c_int()
leds = self.get_status_leds(ctypes.byref(nleds))

Expand All @@ -899,7 +895,7 @@ class Fallback(enum.IntEnum):
NONE = 0x0
GENERIC = 0x1

def __init__(self, path: Optional[Path] = None):
def __init__(self, path: Path | None = None):
lib = LibWacom.instance()
if path is None:
self.db = lib.database_new() # type: ignore
Expand All @@ -926,27 +922,27 @@ def __del__(self):
lib = LibWacom.instance()
lib.database_destroy(db)

def new_from_name(self, name: str) -> Optional[WacomDevice]:
def new_from_name(self, name: str) -> WacomDevice | None:
device = self.libwacom_new_from_name(name.encode("utf-8"), 0)
return WacomDevice(device) if device else None

def new_from_path(
self, path: str, fallback: Fallback = Fallback.NONE
) -> Optional[WacomDevice]:
) -> WacomDevice | None:
device = self.libwacom_new_from_path(path.encode("utf-8"), fallback, 0)
return WacomDevice(device) if device else None

def new_from_usbid(self, vid: int, pid: int) -> Optional[WacomDevice]:
def new_from_usbid(self, vid: int, pid: int) -> WacomDevice | None:
device = self.libwacom_new_from_usbid(vid, pid, 0)
return WacomDevice(device) if device else None

def new_from_builder(
self, builder: WacomBuilder, fallback: Fallback = Fallback.NONE
) -> Optional[WacomDevice]:
) -> WacomDevice | None:
device = self.libwacom_new_from_builder(builder.builder, fallback.value, 0)
return WacomDevice(device) if device else None

def list_devices(self) -> List[WacomDevice]:
def list_devices(self) -> list[WacomDevice]:
devices = self.libwacom_list_devices_from_database(self.db, 0)
devs = [
WacomDevice(d, destroy=False)
Expand All @@ -955,7 +951,7 @@ def list_devices(self) -> List[WacomDevice]:
GlibC.instance().free(devices)
return devs

def list_styli(self) -> List[WacomStylus]:
def list_styli(self) -> list[WacomStylus]:
styli = self.libwacom_list_styli_from_database(self.db, 0)
result = [
WacomStylus(s)
Expand Down
6 changes: 2 additions & 4 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#!/usr/bin/env python3
#
# This file is formatted with ruff format
#

from pathlib import Path
import logging
import os
from pathlib import Path

import pytest

from . import WacomDatabase
Expand Down
1 change: 0 additions & 1 deletion test/test_data_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import re
from pathlib import Path


WACOM_RECEIVER_USBIDS = [
(0x56A, 0x84),
]
Expand Down
18 changes: 9 additions & 9 deletions test/test_libwacom.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
#!/usr/bin/env python3
#
# This file is formatted with ruff format

import ctypes
import logging
import string
from configparser import ConfigParser
from dataclasses import dataclass, field

import ctypes
import logging
import pytest
import string

from . import (
WacomAxisType,
Expand Down Expand Up @@ -97,8 +95,9 @@ def write_to_dir(self, dir, filename="libwacom.stylus"):

if logger.getEffectiveLevel() == logging.DEBUG:
logger.debug(f"{dir}/{filename}:")
for line in open(dir / filename).readlines():
logger.debug(f" {line.rstrip()}")
with open(dir / filename) as f:
for line in f:
logger.debug(f" {line.rstrip()}")


@dataclass
Expand Down Expand Up @@ -148,8 +147,9 @@ def write_to(self, filename):

if logger.getEffectiveLevel() == logging.DEBUG:
logger.debug(f"{filename}:")
for line in open(filename).readlines():
logger.debug(f" {line.rstrip()}")
with open(filename) as f:
for line in f:
logger.debug(f" {line.rstrip()}")


@pytest.fixture()
Expand Down
23 changes: 10 additions & 13 deletions test/test_svg.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
#!/usr/bin/env python3
#
# Run with pytest

from typing import Optional, List
from pathlib import Path
from dataclasses import dataclass
import xml.etree

import os
import logging
import os
import string
import xml.etree
from dataclasses import dataclass
from pathlib import Path

import pytest

from . import WacomDatabase, WacomDevice
Expand Down Expand Up @@ -45,7 +42,7 @@ class SvgDevice:
svg: xml.etree.ElementTree
is_autogenerated: bool

def has_item(self, id: str, classes: Optional[List[str]] = None):
def has_item(self, id: str, classes: list[str] | None = None):
root = self.svg.getroot()
nodes = root.findall(f".//*[@id='{id}']")
assert nodes, f"Failed to find required element with id {id}"
Expand Down Expand Up @@ -87,7 +84,7 @@ def pytest_generate_tests(metafunc):
]
devices = sorted(devices, key=lambda d: d.name)

def filenames(devices: List[SvgDevice]) -> List[str]:
def filenames(devices: list[SvgDevice]) -> list[str]:
return [Path(d.device.layout_filename).name for d in devices]

if "svgdevice" in metafunc.fixturenames:
Expand Down Expand Up @@ -130,7 +127,7 @@ def test_svg_maybe_not_needed(svgdevice):
)


def has_item(root, id: str, classes: Optional[List[str]] = None):
def has_item(root, id: str, classes: list[str] | None = None):
nodes = root.findall(f".//*[@id='{id}']")
assert nodes, f"Failed to find required element with id {id}"
assert len(nodes) == 1, f"Expected on element with id {id}, have {len(nodes)}"
Expand Down Expand Up @@ -193,7 +190,7 @@ def test_svg_strips(stripdevice):
except AssertionError as e:
if stripdevice.is_autogenerated:
pytest.skip(f"Autogenerated device has errors in SVG: {e}")
raise e
raise


def test_svg_dials(dialdevice):
Expand Down Expand Up @@ -224,7 +221,7 @@ def test_svg_dials(dialdevice):
except AssertionError as e:
if dialdevice.is_autogenerated:
pytest.skip(f"Autogenerated device has errors in SVG: {e}")
raise e
raise


def test_svg_button(buttondevice):
Expand Down
Loading
Loading