diff --git a/lib/hidapi/hidconsole.py b/lib/hidapi/hidconsole.py
index 11b9ff9ce..3aa0cd154 100644
--- a/lib/hidapi/hidconsole.py
+++ b/lib/hidapi/hidconsole.py
@@ -50,7 +50,7 @@ def strhex(d):
def _print(marker, data, scroll=False):
t = time.time() - start_time
if isinstance(data, str):
- s = marker + " " + data
+ s = f"{marker} {data}"
else:
hexs = strhex(data)
s = "%s (% 8.3f) [%s %s %s %s] %s" % (marker, t, hexs[0:2], hexs[2:4], hexs[4:8], hexs[8:], repr(data))
@@ -90,7 +90,7 @@ def _continuous_read(handle, timeout=2000):
try:
reply = hidapi.read(handle, 128, timeout)
except OSError as e:
- _error("Read failed, aborting: " + str(e), True)
+ _error(f"Read failed, aborting: {str(e)}", True)
break
assert reply is not None
if reply:
@@ -101,7 +101,7 @@ def _validate_input(line, hidpp=False):
try:
data = unhexlify(line.encode("ascii"))
except Exception as e:
- _error("Invalid input: " + str(e))
+ _error(f"Invalid input: {str(e)}")
return None
if hidpp:
diff --git a/lib/logitech_receiver/common.py b/lib/logitech_receiver/common.py
index 50f4147bd..3d00a0156 100644
--- a/lib/logitech_receiver/common.py
+++ b/lib/logitech_receiver/common.py
@@ -333,7 +333,7 @@ def __eq__(self, other):
return self.name.lower() == other.lower()
# this should catch comparisons with bytes in Py3
if other is not None:
- raise TypeError("Unsupported type " + str(type(other)))
+ raise TypeError(f"Unsupported type {str(type(other))}")
def __ne__(self, other):
return not self.__eq__(other)
@@ -467,7 +467,7 @@ def __getitem__(self, index):
def __setitem__(self, index, name):
assert isinstance(index, int), type(index)
if isinstance(name, NamedInt):
- assert int(index) == int(name), repr(index) + " " + repr(name)
+ assert int(index) == int(name), f"{repr(index)} {repr(name)}"
value = name
elif isinstance(name, str):
value = NamedInt(index, name)
diff --git a/lib/logitech_receiver/device.py b/lib/logitech_receiver/device.py
index eb06e04dc..eee773bd5 100644
--- a/lib/logitech_receiver/device.py
+++ b/lib/logitech_receiver/device.py
@@ -231,14 +231,14 @@ def codename(self):
self._codename = codename
elif self.protocol < 2.0:
self._codename = "? (%s)" % (self.wpid or self.product_id)
- return self._codename or "?? (%s)" % (self.wpid or self.product_id)
+ return self._codename or f"?? ({self.wpid or self.product_id})"
@property
def name(self):
if not self._name:
if self.online and self.protocol >= 2.0:
self._name = _hidpp20.get_name(self)
- return self._name or self._codename or "Unknown device %s" % (self.wpid or self.product_id)
+ return self._name or self._codename or f"Unknown device {self.wpid or self.product_id}"
def get_ids(self):
ids = _hidpp20.get_ids(self)
diff --git a/lib/logitech_receiver/diversion.py b/lib/logitech_receiver/diversion.py
index 5ac595dca..98f53d2f5 100644
--- a/lib/logitech_receiver/diversion.py
+++ b/lib/logitech_receiver/diversion.py
@@ -543,7 +543,7 @@ def __init__(self, args, source=None, warn=True):
self.source = source
def __str__(self):
- source = "(" + self.source + ")" if self.source else ""
+ source = f"({self.source})" if self.source else ""
return f"Rule{source}[{', '.join([c.__str__() for c in self.components])}]"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
@@ -580,7 +580,7 @@ def __init__(self, op, warn=True):
self.component = self.compile(op)
def __str__(self):
- return "Not: " + str(self.component)
+ return f"Not: {str(self.component)}"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -693,7 +693,7 @@ def __init__(self, process, warn=True):
self.process = str(process)
def __str__(self):
- return "Process: " + str(self.process)
+ return f"Process: {str(self.process)}"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -724,7 +724,7 @@ def __init__(self, process, warn=True):
self.process = str(process)
def __str__(self):
- return "MouseProcess: " + str(self.process)
+ return f"MouseProcess: {str(self.process)}"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -749,7 +749,7 @@ def __init__(self, feature: str, warn: bool = True):
logger.warning("rule Feature argument not name of a feature: %s", feature)
def __str__(self):
- return "Feature: " + str(self.feature)
+ return f"Feature: {str(self.feature)}"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -770,7 +770,7 @@ def __init__(self, report, warn=True):
self.report = report
def __str__(self):
- return "Report: " + str(self.report)
+ return f"Report: {str(self.report)}"
def evaluate(self, report, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -843,7 +843,7 @@ def __init__(self, modifiers, warn=True):
logger.warning("unknown rule Modifier value: %s", k)
def __str__(self):
- return "Modifiers: " + str(self.desired)
+ return f"Modifiers: {str(self.desired)}"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -989,7 +989,7 @@ def __init__(self, test, warn=True):
logger.warning("rule Test argument not valid %s", test)
def __str__(self):
- return "Test: " + str(self.test)
+ return f"Test: {str(self.test)}"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -1017,7 +1017,7 @@ def __init__(self, test, warn=True):
logger.warning("rule TestBytes argument not valid %s", test)
def __str__(self):
- return "TestBytes: " + str(self.test)
+ return f"TestBytes: {str(self.test)}"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -1092,7 +1092,7 @@ def __init__(self, devID, warn=True):
self.devID = devID
def __str__(self):
- return "Active: " + str(self.devID)
+ return f"Active: {str(self.devID)}"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -1113,7 +1113,7 @@ def __init__(self, devID, warn=True):
self.devID = devID
def __str__(self):
- return "Device: " + str(self.devID)
+ return f"Device: {str(self.devID)}"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -1133,7 +1133,7 @@ def __init__(self, host, warn=True):
self.host = host
def __str__(self):
- return "Host: " + str(self.host)
+ return f"Host: {str(self.host)}"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if logger.isEnabledFor(logging.DEBUG):
@@ -1425,7 +1425,7 @@ def __init__(self, args, warn=True):
self.components = self.rule.components
def __str__(self):
- return "Later: [" + str(self.delay) + ", " + ", ".join(str(c) for c in self.components) + "]"
+ return f"Later: [{str(self.delay)}, " + ", ".join(str(c) for c in self.components) + "]"
def evaluate(self, feature, notification: HIDPPNotification, device, last_result):
if self.delay and self.rule:
diff --git a/lib/logitech_receiver/hidpp20.py b/lib/logitech_receiver/hidpp20.py
index 6bd45688a..49a1c76f7 100644
--- a/lib/logitech_receiver/hidpp20.py
+++ b/lib/logitech_receiver/hidpp20.py
@@ -452,23 +452,23 @@ def action(self):
if self.actionId == special_keys.ACTIONID.Empty:
return None
elif self.actionId == special_keys.ACTIONID.Key:
- return "Key: " + str(self.modifiers) + str(self.remapped)
+ return f"Key: {str(self.modifiers)}{str(self.remapped)}"
elif self.actionId == special_keys.ACTIONID.Mouse:
- return "Mouse Button: " + str(self.remapped)
+ return f"Mouse Button: {str(self.remapped)}"
elif self.actionId == special_keys.ACTIONID.Xdisp:
- return "X Displacement " + str(self.remapped)
+ return f"X Displacement {str(self.remapped)}"
elif self.actionId == special_keys.ACTIONID.Ydisp:
- return "Y Displacement " + str(self.remapped)
+ return f"Y Displacement {str(self.remapped)}"
elif self.actionId == special_keys.ACTIONID.Vscroll:
- return "Vertical Scroll " + str(self.remapped)
+ return f"Vertical Scroll {str(self.remapped)}"
elif self.actionId == special_keys.ACTIONID.Hscroll:
- return "Horizontal Scroll: " + str(self.remapped)
+ return f"Horizontal Scroll: {str(self.remapped)}"
elif self.actionId == special_keys.ACTIONID.Consumer:
- return "Consumer: " + str(self.remapped)
+ return f"Consumer: {str(self.remapped)}"
elif self.actionId == special_keys.ACTIONID.Internal:
- return "Internal Action " + str(self.remapped)
+ return f"Internal Action {str(self.remapped)}"
elif self.actionId == special_keys.ACTIONID.Internal:
- return "Power " + str(self.remapped)
+ return f"Power {str(self.remapped)}"
else:
return "Unknown"
@@ -1279,7 +1279,7 @@ def to_bytes(self):
def __repr__(self):
return "%s{%s}" % (
self.__class__.__name__,
- ", ".join([str(key) + ":" + str(val) for key, val in self.__dict__.items()]),
+ ", ".join([f"{str(key)}:{str(val)}" for key, val in self.__dict__.items()]),
)
@@ -1842,7 +1842,7 @@ def get_polling_rate(self, device: Device):
state = device.feature_request(SupportedFeature.REPORT_RATE, 0x10)
if state:
rate = struct.unpack("!B", state[:1])[0]
- return str(rate) + "ms"
+ return f"{str(rate)}ms"
else:
rates = ["8ms", "4ms", "2ms", "1ms", "500us", "250us", "125us"]
state = device.feature_request(SupportedFeature.EXTENDED_ADJUSTABLE_REPORT_RATE, 0x20)
diff --git a/lib/logitech_receiver/listener.py b/lib/logitech_receiver/listener.py
index 44c7487e4..7de6bb525 100644
--- a/lib/logitech_receiver/listener.py
+++ b/lib/logitech_receiver/listener.py
@@ -117,7 +117,7 @@ def __init__(self, receiver, notifications_callback):
path_name = receiver.path.split("/")[2]
except IndexError:
path_name = receiver.path
- super().__init__(name=self.__class__.__name__ + ":" + path_name)
+ super().__init__(name=f"{self.__class__.__name__}:{path_name}")
self.daemon = True
self._active = False
self.receiver = receiver
diff --git a/lib/logitech_receiver/settings_templates.py b/lib/logitech_receiver/settings_templates.py
index 0800b435e..b9c06adef 100644
--- a/lib/logitech_receiver/settings_templates.py
+++ b/lib/logitech_receiver/settings_templates.py
@@ -1167,11 +1167,11 @@ def _str_os_version(version):
if version == 0:
return ""
elif version & 0xFF:
- return str(version >> 8) + "." + str(version & 0xFF)
+ return f"{str(version >> 8)}.{str(version & 0xFF)}"
else:
return str(version >> 8)
- return "" if low == 0 and high == 0 else " " + _str_os_version(low) + "-" + _str_os_version(high)
+ return "" if low == 0 and high == 0 else f" {_str_os_version(low)}-{_str_os_version(high)}"
infos = device.feature_request(_F.MULTIPLATFORM)
assert infos, "Oops, multiplatform count cannot be retrieved!"
@@ -1227,7 +1227,7 @@ def build(cls, setting_class, device):
choices = common.NamedInts()
for host in range(0, numHosts):
paired, hostName = hostNames.get(host, (True, ""))
- choices[host] = str(host + 1) + ":" + hostName if hostName else str(host + 1)
+ choices[host] = f"{str(host + 1)}:{hostName}" if hostName else str(host + 1)
return cls(choices=choices, read_skip_byte_count=1) if choices and len(choices) > 1 else None
@@ -1735,7 +1735,7 @@ def build(cls, setting_class, device):
key = (
setting_class.keys_universe[i]
if i in setting_class.keys_universe
- else common.NamedInt(i, "KEY " + str(i))
+ else common.NamedInt(i, f"KEY {str(i)}")
)
choices_map[key] = setting_class.choices_universe
result = cls(choices_map) if choices_map else None
diff --git a/lib/logitech_receiver/special_keys.py b/lib/logitech_receiver/special_keys.py
index 09ac97cb0..4b65909ef 100644
--- a/lib/logitech_receiver/special_keys.py
+++ b/lib/logitech_receiver/special_keys.py
@@ -316,9 +316,9 @@
)
for i in range(1, 33): # add in G keys - these are not really Logitech Controls
- CONTROL[0x1000 + i] = "G" + str(i)
+ CONTROL[0x1000 + i] = f"G{str(i)}"
for i in range(1, 9): # add in M keys - these are not really Logitech Controls
- CONTROL[0x1100 + i] = "M" + str(i)
+ CONTROL[0x1100 + i] = f"M{str(i)}"
CONTROL[0x1200] = "MR" # add in MR key - this is not really a Logitech Control
CONTROL._fallback = lambda x: f"unknown:{x:04X}"
diff --git a/lib/solaar/cli/probe.py b/lib/solaar/cli/probe.py
index 9a4a7b51f..bcf40b374 100644
--- a/lib/solaar/cli/probe.py
+++ b/lib/solaar/cli/probe.py
@@ -45,29 +45,29 @@ def run(receivers, args, find_receiver, _ignore):
print("")
print(" Register Dump")
rgst = receiver.read_register(Registers.NOTIFICATIONS)
- print(" Notifications %#04x: %s" % (Registers.NOTIFICATIONS % 0x100, "0x" + strhex(rgst) if rgst else "None"))
+ print(" Notifications %#04x: %s" % (Registers.NOTIFICATIONS % 0x100, f"0x{strhex(rgst)}" if rgst else "None"))
rgst = receiver.read_register(Registers.RECEIVER_CONNECTION)
print(
" Connection State %#04x: %s"
- % (Registers.RECEIVER_CONNECTION % 0x100, "0x" + strhex(rgst) if rgst else "None")
+ % (Registers.RECEIVER_CONNECTION % 0x100, f"0x{strhex(rgst)}" if rgst else "None")
)
rgst = receiver.read_register(Registers.DEVICES_ACTIVITY)
print(
- " Device Activity %#04x: %s" % (Registers.DEVICES_ACTIVITY % 0x100, "0x" + strhex(rgst) if rgst else "None")
+ " Device Activity %#04x: %s" % (Registers.DEVICES_ACTIVITY % 0x100, f"0x{strhex(rgst)}" if rgst else "None")
)
for sub_reg in range(0, 16):
rgst = receiver.read_register(Registers.RECEIVER_INFO, sub_reg)
print(
" Pairing Register %#04x %#04x: %s"
- % (Registers.RECEIVER_INFO % 0x100, sub_reg, "0x" + strhex(rgst) if rgst else "None")
+ % (Registers.RECEIVER_INFO % 0x100, sub_reg, f"0x{strhex(rgst)}" if rgst else "None")
)
for device in range(0, 7):
for sub_reg in [0x10, 0x20, 0x30, 0x50]:
rgst = receiver.read_register(Registers.RECEIVER_INFO, sub_reg + device)
print(
" Pairing Register %#04x %#04x: %s"
- % (Registers.RECEIVER_INFO % 0x100, sub_reg + device, "0x" + strhex(rgst) if rgst else "None")
+ % (Registers.RECEIVER_INFO % 0x100, sub_reg + device, f"0x{strhex(rgst)}" if rgst else "None")
)
rgst = receiver.read_register(Registers.RECEIVER_INFO, 0x40 + device)
print(
@@ -90,7 +90,7 @@ def run(receivers, args, find_receiver, _ignore):
rgst = receiver.read_register(Registers.FIRMWARE, sub_reg)
print(
" Firmware %#04x %#04x: %s"
- % (Registers.FIRMWARE % 0x100, sub_reg, "0x" + strhex(rgst) if rgst is not None else "None")
+ % (Registers.FIRMWARE % 0x100, sub_reg, f"0x{strhex(rgst)}" if rgst is not None else "None")
)
print("")
diff --git a/lib/solaar/cli/show.py b/lib/solaar/cli/show.py
index 78a14ede8..f13b9c5c7 100644
--- a/lib/solaar/cli/show.py
+++ b/lib/solaar/cli/show.py
@@ -82,8 +82,8 @@ def _battery_line(dev):
level, nextLevel, status, voltage = battery.level, battery.next_level, battery.status, battery.voltage
text = _battery_text(level)
if voltage is not None:
- text = text + f" {voltage}mV "
- nextText = "" if nextLevel is None else ", next level " + _battery_text(nextLevel)
+ text = f"{text} {voltage}mV "
+ nextText = "" if nextLevel is None else f", next level {_battery_text(nextLevel)}"
print(f" Battery: {text}, {status}{nextText}.")
else:
print(" Battery status unavailable.")
diff --git a/lib/solaar/cli/unpair.py b/lib/solaar/cli/unpair.py
index 03785be4e..5a84a9fb5 100644
--- a/lib/solaar/cli/unpair.py
+++ b/lib/solaar/cli/unpair.py
@@ -26,8 +26,8 @@ def run(receivers, args, find_receiver, find_device):
if not dev.receiver.may_unpair:
print(
- "Receiver with USB id %s for %s [%s:%s] does not unpair, but attempting anyway."
- % (dev.receiver.product_id, dev.name, dev.wpid, dev.serial)
+ f"Receiver with USB id {dev.receiver.product_id} for {dev.name} [{dev.wpid}:{dev.serial}] does not unpair,",
+ "but attempting anyway.",
)
try:
# query these now, it's last chance to get them
diff --git a/lib/solaar/i18n.py b/lib/solaar/i18n.py
index 1d4976ca3..be9865137 100644
--- a/lib/solaar/i18n.py
+++ b/lib/solaar/i18n.py
@@ -31,7 +31,7 @@ def _find_locale_path(locale_domain: str) -> str:
src_share = os.path.normpath(os.path.join(os.path.realpath(sys.path[0]), "..", "share"))
for location in prefix_share, src_share:
- mo_files = glob(os.path.join(location, "locale", "*", "LC_MESSAGES", locale_domain + ".mo"))
+ mo_files = glob(os.path.join(location, "locale", "*", "LC_MESSAGES", f"{locale_domain}.mo"))
if mo_files:
return os.path.join(location, "locale")
raise FileNotFoundError(f"Could not find locale path for {locale_domain}")
diff --git a/lib/solaar/ui/config_panel.py b/lib/solaar/ui/config_panel.py
index 3f8397e54..5eed08110 100644
--- a/lib/solaar/ui/config_panel.py
+++ b/lib/solaar/ui/config_panel.py
@@ -386,7 +386,7 @@ def set_value(self, value):
elem.set_state(v)
if elem.get_state():
active += 1
- to_join.append(lbl.get_text() + ": " + str(elem.get_state()))
+ to_join.append(f"{lbl.get_text()}: {str(elem.get_state())}")
b = ", ".join(to_join)
self._button.set_label(f"{active} / {total}")
self._button.set_tooltip_text(b)
@@ -470,7 +470,7 @@ def set_value(self, value):
item = ch._setting_item
v = value.get(int(item), None)
if v is not None:
- b += str(item) + ": ("
+ b += f"{str(item)}: ("
to_join = []
for c in ch._sub_items:
sub_item = c._setting_sub_item
@@ -480,7 +480,7 @@ def set_value(self, value):
sub_item_value = c._control.get_value()
c._control.set_value(sub_item_value)
n += 1
- to_join.append(str(sub_item) + f"={sub_item_value}")
+ to_join.append(f"{str(sub_item)}={sub_item_value}")
b += ", ".join(to_join) + ") "
lbl_text = ngettext("%d value", "%d values", n) % n
self._button.set_label(lbl_text)
@@ -533,7 +533,7 @@ def set_value(self, value):
h.control.set_value(v)
else:
v = self.sbox.setting._value[int(item)]
- b += str(item) + ": (" + str(v) + ") "
+ b += f"{str(item)}: ({str(v)}) "
lbl_text = ngettext("%d value", "%d values", n) % n
self._button.set_label(lbl_text)
self._button.set_tooltip_text(b)
diff --git a/lib/solaar/ui/icons.py b/lib/solaar/ui/icons.py
index 3497317cc..ed25a4713 100644
--- a/lib/solaar/ui/icons.py
+++ b/lib/solaar/ui/icons.py
@@ -103,7 +103,7 @@ def device_icon_set(name="_", kind=None):
icon_set += ("input-mouse",)
elif str(kind) == "headset":
icon_set += ("audio-headphones", "audio-headset")
- icon_set += ("input-" + str(kind),)
+ icon_set += (f"input-{str(kind)}",)
# icon_set += (name.replace(' ', '-'),)
_ICON_SETS[name] = icon_set
return icon_set
diff --git a/lib/solaar/ui/rule_actions.py b/lib/solaar/ui/rule_actions.py
index 0a738a678..22ca0a024 100644
--- a/lib/solaar/ui/rule_actions.py
+++ b/lib/solaar/ui/rule_actions.py
@@ -138,7 +138,7 @@ def left_label(cls, component):
@classmethod
def right_label(cls, component):
- return " + ".join(component.key_names) + (" (" + component.action + ")" if component.action != CLICK else "")
+ return " + ".join(component.key_names) + (f" ({component.action})" if component.action != CLICK else "")
class MouseScrollUI(ActionUI):
diff --git a/lib/solaar/ui/rule_conditions.py b/lib/solaar/ui/rule_conditions.py
index 5ef513351..600dcb3a3 100644
--- a/lib/solaar/ui/rule_conditions.py
+++ b/lib/solaar/ui/rule_conditions.py
@@ -383,7 +383,7 @@ def left_label(cls, component):
@classmethod
def right_label(cls, component):
- return component.test + (" " + repr(component.parameter) if component.parameter is not None else "")
+ return component.test + (f" {repr(component.parameter)}" if component.parameter is not None else "")
@dataclass
diff --git a/lib/solaar/ui/window.py b/lib/solaar/ui/window.py
index 62d2a4799..8afd34e23 100644
--- a/lib/solaar/ui/window.py
+++ b/lib/solaar/ui/window.py
@@ -564,7 +564,7 @@ def _set_details(text):
def _make_text(items):
text = "\n".join("%-13s: %s" % (name, value) for name, value in items)
- return "" + text + ""
+ return f"{text}"
def _displayable_items(items):
for name, value in items:
@@ -866,7 +866,7 @@ def update(device, need_popup=False, refresh=False):
else:
path = device.receiver.path if device.receiver is not None else device.path
- assert device.number is not None and device.number >= 0, "invalid device number" + str(device.number)
+ assert device.number is not None and device.number >= 0, f"invalid device number{str(device.number)}"
item = _device_row(path, device.number, device if bool(device) else None)
if bool(device) and item: