mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-20 05:40:05 +01:00
test: drop the use of attr
All our uses can be done with dataclasses so we don't need an external package. Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/319>
This commit is contained in:
parent
f2811418dd
commit
504afdea4a
6 changed files with 76 additions and 74 deletions
|
|
@ -296,7 +296,7 @@ abicheck@fedora:40:
|
||||||
meson compile -C _build
|
meson compile -C _build
|
||||||
meson install -C _build
|
meson install -C _build
|
||||||
popd
|
popd
|
||||||
- pip install attrs
|
- pip install attrs # required by libei 1.0.0
|
||||||
script:
|
script:
|
||||||
- git remote add upstream$CI_JOB_ID https://gitlab.freedesktop.org/$FDO_UPSTREAM_REPO
|
- git remote add upstream$CI_JOB_ID https://gitlab.freedesktop.org/$FDO_UPSTREAM_REPO
|
||||||
- git fetch --tags upstream$CI_JOB_ID
|
- git fetch --tags upstream$CI_JOB_ID
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ abicheck@{{distro.name}}:{{version}}:
|
||||||
meson compile -C _build
|
meson compile -C _build
|
||||||
meson install -C _build
|
meson install -C _build
|
||||||
popd
|
popd
|
||||||
- pip install attrs
|
- pip install attrs # required by libei 1.0.0
|
||||||
script:
|
script:
|
||||||
- git remote add upstream$CI_JOB_ID https://gitlab.freedesktop.org/$FDO_UPSTREAM_REPO
|
- git remote add upstream$CI_JOB_ID https://gitlab.freedesktop.org/$FDO_UPSTREAM_REPO
|
||||||
- git fetch --tags upstream$CI_JOB_ID
|
- git fetch --tags upstream$CI_JOB_ID
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,12 @@
|
||||||
|
|
||||||
from typing import Any, Callable, Generator, Tuple
|
from typing import Any, Callable, Generator, Tuple
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
from dataclasses import dataclass, field
|
||||||
try:
|
try:
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from strenum import StrEnum
|
from strenum import StrEnum
|
||||||
|
|
||||||
import attr
|
|
||||||
import binascii
|
import binascii
|
||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -51,19 +51,24 @@ def hexlify(data):
|
||||||
return binascii.hexlify(data, sep=" ", bytes_per_sep=4)
|
return binascii.hexlify(data, sep=" ", bytes_per_sep=4)
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
class ObjectId(int):
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"{self:#x}"
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
class MethodCall:
|
class MethodCall:
|
||||||
name: str = attr.ib()
|
name: str
|
||||||
args: dict[str, Any] = attr.ib()
|
args: dict[str, Any]
|
||||||
objects: dict[str, "Interface"] = attr.ib(default=attr.Factory(dict))
|
objects: dict[str, "Interface"] = field(default_factory=dict)
|
||||||
timestamp: float = attr.ib(default=attr.Factory(time.time))
|
timestamp: float = field(default_factory=time.time)
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class MessageHeader:
|
class MessageHeader:
|
||||||
object_id: int = attr.ib(repr=lambda id: f"{id:#x}")
|
object_id: ObjectId
|
||||||
msglen: int = attr.ib()
|
msglen: int
|
||||||
opcode: int = attr.ib()
|
opcode: int
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def size(cls) -> int:
|
def size(cls) -> int:
|
||||||
|
|
@ -72,22 +77,21 @@ class MessageHeader:
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_data(cls, data: bytes) -> "MessageHeader":
|
def from_data(cls, data: bytes) -> "MessageHeader":
|
||||||
object_id, msglen, opcode = struct.unpack("=QII", data[:cls.size()])
|
object_id, msglen, opcode = struct.unpack("=QII", data[:cls.size()])
|
||||||
return cls(object_id, msglen, opcode)
|
return cls(ObjectId(object_id), msglen, opcode)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def as_tuple(self) -> Tuple[int, int, int]:
|
def as_tuple(self) -> Tuple[int, int, int]:
|
||||||
return self.object_id, self.msglen, self.opcode
|
return self.object_id, self.msglen, self.opcode
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class Context:
|
class Context:
|
||||||
objects: dict[str, "Interface"] = attr.ib(default=attr.Factory(dict))
|
objects: dict[str, "Interface"] = field(default_factory=dict)
|
||||||
_callbacks: dict[str, dict[int, Callable]] = attr.ib(init=False)
|
_callbacks: dict[str, dict[int, Callable]] = field(
|
||||||
_ids: Generator = attr.ib(init=False, default=attr.Factory(itertools.count))
|
init=False,
|
||||||
|
default_factory=lambda: { "register": {}, "unregister": {}}
|
||||||
@_callbacks.default # type: ignore
|
)
|
||||||
def _default_callbacks(self) -> dict[str, dict[int, Callable]]:
|
_ids: Generator = field(init=False, default_factory=itertools.count)
|
||||||
return { "register": {}, "unregister": {}}
|
|
||||||
|
|
||||||
def register(self, object: "Interface") -> None:
|
def register(self, object: "Interface") -> None:
|
||||||
assert object.object_id not in self.objects
|
assert object.object_id not in self.objects
|
||||||
|
|
@ -147,15 +151,15 @@ class InterfaceName(StrEnum):
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
@attr.s(eq=False)
|
@dataclass(eq=False)
|
||||||
class Interface:
|
class Interface:
|
||||||
object_id: int = attr.ib(repr=lambda id: f"{id:#x}")
|
object_id: int
|
||||||
version: int = attr.ib()
|
version: int
|
||||||
callbacks: dict[str, Callable] = attr.ib(init=False, default=attr.Factory(dict), repr=False)
|
callbacks: dict[str, Callable] = field(init=False, default_factory=dict, repr=False)
|
||||||
calllog: list[MethodCall] = attr.ib(init=False, default=attr.Factory(list), repr=False)
|
calllog: list[MethodCall] = field(init=False, default_factory=list, repr=False)
|
||||||
name: str = attr.ib(default="<overridden by subclass>")
|
name: str = field(default="<overridden by subclass>")
|
||||||
incoming: dict[int, str] = attr.ib(default=attr.Factory(list), repr=False)
|
incoming: dict[int, str] = field(default_factory=list, repr=False)
|
||||||
outgoing: dict[int, str] = attr.ib(default=attr.Factory(list), repr=False)
|
outgoing: dict[int, str] = field(default_factory=list, repr=False)
|
||||||
|
|
||||||
def format(self, *args, opcode: int, signature: str) -> bytes:
|
def format(self, *args, opcode: int, signature: str) -> bytes:
|
||||||
encoding = ["=QII"]
|
encoding = ["=QII"]
|
||||||
|
|
@ -252,7 +256,7 @@ class Interface:
|
||||||
|
|
||||||
|
|
||||||
{% for interface in interfaces %}
|
{% for interface in interfaces %}
|
||||||
@attr.s
|
@dataclass
|
||||||
class {{interface.camel_name}}(Interface):
|
class {{interface.camel_name}}(Interface):
|
||||||
{% for enum in interface.enums %}
|
{% for enum in interface.enums %}
|
||||||
class {{component.capitalize()}}{{enum.camel_name}}(IntEnum):
|
class {{component.capitalize()}}{{enum.camel_name}}(IntEnum):
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ endif
|
||||||
# Python-based tests
|
# Python-based tests
|
||||||
|
|
||||||
pymod = import('python')
|
pymod = import('python')
|
||||||
required_python_modules = ['pytest', 'attr', 'structlog']
|
required_python_modules = ['pytest', 'structlog']
|
||||||
python = pymod.find_installation('python3', required: get_option('tests'))
|
python = pymod.find_installation('python3', required: get_option('tests'))
|
||||||
if python.found() and python.language_version().version_compare('< 3.11')
|
if python.found() and python.language_version().version_compare('< 3.11')
|
||||||
required_python_modules += ['strenum']
|
required_python_modules += ['strenum']
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ from ctypes import c_char_p, c_int, c_uint32, c_void_p
|
||||||
from typing import Iterator, List, Tuple, Type, Optional, TextIO
|
from typing import Iterator, List, Tuple, Type, Optional, TextIO
|
||||||
from gi.repository import GLib # type: ignore
|
from gi.repository import GLib # type: ignore
|
||||||
from dbus.mainloop.glib import DBusGMainLoop
|
from dbus.mainloop.glib import DBusGMainLoop
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import attr
|
|
||||||
import ctypes
|
import ctypes
|
||||||
import dbus
|
import dbus
|
||||||
import dbus.proxies
|
import dbus.proxies
|
||||||
|
|
@ -82,21 +82,21 @@ def version_at_least(have, required) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class _Api:
|
class _Api:
|
||||||
name: str = attr.ib()
|
name: str
|
||||||
args: Tuple[Type[ctypes._SimpleCData], ...] = attr.ib()
|
args: Tuple[Type[ctypes._SimpleCData], ...]
|
||||||
return_type: Optional[Type[ctypes._SimpleCData]] = attr.ib()
|
return_type: Optional[Type[ctypes._SimpleCData]]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def basename(self) -> str:
|
def basename(self) -> str:
|
||||||
return self.name[len(PREFIX) :]
|
return self.name[len(PREFIX) :]
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class _Enum:
|
class _Enum:
|
||||||
name: str = attr.ib()
|
name: str
|
||||||
value: int = attr.ib()
|
value: int
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def basename(self) -> str:
|
def basename(self) -> str:
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from typing import Generator, Optional
|
from typing import Generator, Optional
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
import attr
|
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
|
|
@ -121,17 +121,17 @@ def eis(socketpath, eis_executable) -> Generator["Eis", None, None]:
|
||||||
eis.terminate()
|
eis.terminate()
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class Ei:
|
class Ei:
|
||||||
sock: socket.socket = attr.ib()
|
sock: socket.socket
|
||||||
context: Context = attr.ib()
|
context: Context
|
||||||
connection: Optional[EiConnection] = attr.ib(default=None)
|
connection: Optional[EiConnection] = None
|
||||||
interface_versions: dict[str, int] = attr.ib(init=False, default=attr.Factory(dict))
|
interface_versions: dict[str, int] = field(init=False, default_factory=dict)
|
||||||
seats: list[EiSeat] = attr.ib(init=False, default=attr.Factory(list))
|
seats: list[EiSeat] = field(init=False, default_factory=list)
|
||||||
object_ids: Generator[int, None, None] = attr.ib(
|
object_ids: Generator[int, None, None] = field(
|
||||||
init=False, default=attr.Factory(lambda: itertools.count(3))
|
init=False, default_factory=lambda: itertools.count(3)
|
||||||
)
|
)
|
||||||
_data: bytes = attr.ib(init=False, default=attr.Factory(bytes)) # type: ignore
|
_data: bytes = field(init=False, default_factory=bytes)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def data(self) -> bytes:
|
def data(self) -> bytes:
|
||||||
|
|
@ -314,12 +314,12 @@ class Ei:
|
||||||
return ei
|
return ei
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class Eis:
|
class Eis:
|
||||||
process: Optional[subprocess.Popen] = attr.ib()
|
process: Optional[subprocess.Popen]
|
||||||
ei: Ei = attr.ib()
|
ei: Ei
|
||||||
_stdout: Optional[str] = attr.ib(init=False, default=None)
|
_stdout: Optional[str] = field(init=False, default=None)
|
||||||
_stderr: Optional[str] = attr.ib(init=False, default=None)
|
_stderr: Optional[str] = field(init=False, default=None)
|
||||||
|
|
||||||
def terminate(self) -> None:
|
def terminate(self) -> None:
|
||||||
if self.process is None:
|
if self.process is None:
|
||||||
|
|
@ -829,12 +829,12 @@ class TestEiProtocol:
|
||||||
if iname != missing_interface:
|
if iname != missing_interface:
|
||||||
ei.send(setup.InterfaceVersion(iname, VERSION_V(1)))
|
ei.send(setup.InterfaceVersion(iname, VERSION_V(1)))
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class Status:
|
class Status:
|
||||||
connected: bool = attr.ib(default=False)
|
connected: bool = False
|
||||||
disconnected: bool = attr.ib(default=False)
|
disconnected: bool = False
|
||||||
seats: bool = attr.ib(default=False)
|
seats: bool = False
|
||||||
devices: bool = attr.ib(default=False)
|
devices: bool = False
|
||||||
|
|
||||||
status = Status()
|
status = Status()
|
||||||
|
|
||||||
|
|
@ -943,11 +943,11 @@ class TestEiProtocol:
|
||||||
ei.dispatch()
|
ei.dispatch()
|
||||||
ei.wait_for_connection()
|
ei.wait_for_connection()
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class Status:
|
class Status:
|
||||||
disconnected: bool = attr.ib(default=False)
|
disconnected: bool = False
|
||||||
reason: int = attr.ib(default=0)
|
reason: int = 0
|
||||||
explanation: Optional[str] = attr.ib(default=None)
|
explanation: Optional[str] = None
|
||||||
|
|
||||||
status = Status()
|
status = Status()
|
||||||
|
|
||||||
|
|
@ -999,11 +999,11 @@ class TestEiProtocol:
|
||||||
ei.dispatch()
|
ei.dispatch()
|
||||||
ei.wait_for_connection()
|
ei.wait_for_connection()
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class Status:
|
class Status:
|
||||||
disconnected: bool = attr.ib(default=False)
|
disconnected: bool = False
|
||||||
reason: int = attr.ib(default=0)
|
reason: int = 0
|
||||||
explanation: Optional[str] = attr.ib(default=None)
|
explanation: Optional[str] = None
|
||||||
|
|
||||||
status = Status()
|
status = Status()
|
||||||
|
|
||||||
|
|
@ -1039,9 +1039,9 @@ class TestEiProtocol:
|
||||||
"""
|
"""
|
||||||
ei = eis.ei
|
ei = eis.ei
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class Status:
|
class Status:
|
||||||
capability: Optional[Interface] = attr.ib(default=None) # type: ignore
|
capability: Optional[Interface] = None # type: ignore
|
||||||
|
|
||||||
status = Status()
|
status = Status()
|
||||||
|
|
||||||
|
|
@ -1101,12 +1101,10 @@ class TestEiProtocol:
|
||||||
"""
|
"""
|
||||||
ei = eis.ei
|
ei = eis.ei
|
||||||
|
|
||||||
@attr.s
|
@dataclass
|
||||||
class Status:
|
class Status:
|
||||||
pointers: dict[InterfaceName, Interface] = attr.ib(
|
pointers: dict[InterfaceName, Interface] = field(default_factory=dict)
|
||||||
default=attr.Factory(dict)
|
all_caps: int = 0
|
||||||
) # type: ignore
|
|
||||||
all_caps: int = attr.ib(default=0)
|
|
||||||
|
|
||||||
status = Status()
|
status = Status()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue