Skip to content

Commit

Permalink
Merge pull request #107 from robberwick/usb-device-type-hinting
Browse files Browse the repository at this point in the history
chore: Refactor type hinting in BaseBackend and its subclasses
  • Loading branch information
robberwick authored Nov 17, 2024
2 parents ac20b41 + 2420a4a commit 3a47472
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 14 deletions.
10 changes: 7 additions & 3 deletions src/blinkstick/backends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

from abc import ABC, abstractmethod

from typing import TypeVar, Generic

class BaseBackend(ABC):
T = TypeVar("T")


class BaseBackend(ABC, Generic[T]):

serial: str | None

Expand All @@ -16,12 +20,12 @@ def _refresh_device(self):

@staticmethod
@abstractmethod
def find_blinksticks(find_all: bool = True):
def find_blinksticks(find_all: bool = True) -> list[T] | None:
raise NotImplementedError

@staticmethod
@abstractmethod
def find_by_serial(serial: str) -> BaseBackend | None:
def find_by_serial(serial: str) -> list[T] | None:
raise NotImplementedError

@abstractmethod
Expand Down
13 changes: 8 additions & 5 deletions src/blinkstick/backends/unix_like.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
from __future__ import annotations

import usb.core
import usb.util
import usb.core # type: ignore
import usb.util # type: ignore

from blinkstick.constants import VENDOR_ID, PRODUCT_ID
from blinkstick.backends.base import BaseBackend
from blinkstick.exceptions import BlinkStickException


class UnixLikeBackend(BaseBackend):
class UnixLikeBackend(BaseBackend[usb.core.Device]):

serial: str
device: usb.core.Device

def __init__(self, device=None):
self.device = device
Expand Down Expand Up @@ -38,13 +39,13 @@ def _refresh_device(self):
return True

@staticmethod
def find_blinksticks(find_all: bool = True):
def find_blinksticks(find_all: bool = True) -> list[usb.core.Device] | None:
return usb.core.find(
find_all=find_all, idVendor=VENDOR_ID, idProduct=PRODUCT_ID
)

@staticmethod
def find_by_serial(serial: str) -> list | None:
def find_by_serial(serial: str) -> list[usb.core.Device] | None:
for d in UnixLikeBackend.find_blinksticks():
try:
if usb.util.get_string(d, 3, 1033) == serial:
Expand All @@ -53,6 +54,8 @@ def find_by_serial(serial: str) -> list | None:
except Exception as e:
print("{0}".format(e))

return None

def control_transfer(
self,
bmRequestType: int,
Expand Down
14 changes: 10 additions & 4 deletions src/blinkstick/backends/win32.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
import sys
from ctypes import *

from pywinusb import hid
from pywinusb import hid # type: ignore

from blinkstick.constants import VENDOR_ID, PRODUCT_ID
from blinkstick.backends.base import BaseBackend
from blinkstick.exceptions import BlinkStickException


class Win32Backend(BaseBackend):
class Win32Backend(BaseBackend[hid.HidDevice]):
serial: str
device: hid.HidDevice
reports: list[hid.core.HidReport]

def __init__(self, device=None):
super().__init__()
self.device = device
Expand All @@ -20,14 +24,16 @@ def __init__(self, device=None):
self.serial = self.get_serial()

@staticmethod
def find_by_serial(serial: str) -> list | None:
def find_by_serial(serial: str) -> list[hid.HidDevice] | None:
devices = [
d for d in Win32Backend.find_blinksticks() if d.serial_number == serial
]

if len(devices) > 0:
return devices

return None

def _refresh_device(self):
# TODO This is weird semantics. fix up return values to be more sensible
if not self.serial:
Expand All @@ -39,7 +45,7 @@ def _refresh_device(self):
return True

@staticmethod
def find_blinksticks(find_all: bool = True):
def find_blinksticks(find_all: bool = True) -> list[hid.HidDevice] | None:
devices = hid.HidDeviceFilter(
vendor_id=VENDOR_ID, product_id=PRODUCT_ID
).get_devices()
Expand Down
6 changes: 4 additions & 2 deletions src/blinkstick/blinkstick.py
Original file line number Diff line number Diff line change
Expand Up @@ -1412,8 +1412,10 @@ def find_all() -> list[BlinkStick]:
@rtype: BlinkStick[]
@return: a list of BlinkStick objects or None if no devices found
"""
result = []
for d in USBBackend.find_blinksticks():
result: list[BlinkStick] = []
if (found_devices := USBBackend.find_blinksticks()) is None:
return result
for d in found_devices:
result.extend([BlinkStick(device=d)])

return result
Expand Down

0 comments on commit 3a47472

Please sign in to comment.