Skip to content

Commit

Permalink
More direct types
Browse files Browse the repository at this point in the history
Replace all imports from typing_extensions with standard typing, move them out of TYPE_CHECKING checks and use defined types directly instead of as strings
  • Loading branch information
cschramm committed Dec 18, 2024
1 parent 657c1dc commit 7d7b03e
Show file tree
Hide file tree
Showing 19 changed files with 163 additions and 201 deletions.
11 changes: 5 additions & 6 deletions blueman/bluemantyping.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
from typing import Union, TYPE_CHECKING, NewType
from typing import NewType, Protocol, Union
from gi.repository import GObject

if TYPE_CHECKING:
from typing_extensions import Protocol

class _HasGType(Protocol):
__gtype__: GObject.GType
class _HasGType(Protocol):
__gtype__: GObject.GType


# Actually supported types are int, bool, str, float, and object but no subclasses, see
# https://github.com/GNOME/pygobject/blob/ac576400ecd554879c906791e6638d64bb8bcc2a/gi/pygi-type.c#L498
# (We shield the possibility to provide a str to avoid errors)
GSignals = dict[str, tuple[GObject.SignalFlags, None, tuple[Union[None, type, GObject.GType, "_HasGType"], ...]]]
GSignals = dict[str, tuple[GObject.SignalFlags, None, tuple[Union[None, type, GObject.GType, _HasGType], ...]]]

ObjectPath = NewType("ObjectPath", str)
BtAddress = NewType("BtAddress", str)
9 changes: 3 additions & 6 deletions blueman/gui/CommonUi.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
from datetime import datetime
from gettext import gettext as _
from typing import overload, TYPE_CHECKING
from typing import overload, Literal

from blueman.Constants import WEBSITE, VERSION

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

if TYPE_CHECKING:
from typing import Literal


class ErrorDialog(Gtk.MessageDialog):
def __init__(self, markup: str, secondary_markup: str | None = None, excp: object | None = None,
Expand Down Expand Up @@ -40,12 +37,12 @@ def __init__(self, markup: str, secondary_markup: str | None = None, excp: objec


@overload
def show_about_dialog(app_name: str, run: "Literal[True]" = True, parent: Gtk.Window | None = None) -> None:
def show_about_dialog(app_name: str, run: Literal[True] = True, parent: Gtk.Window | None = None) -> None:
...


@overload
def show_about_dialog(app_name: str, run: "Literal[False]", parent: Gtk.Window | None = None) -> Gtk.AboutDialog:
def show_about_dialog(app_name: str, run: Literal[False], parent: Gtk.Window | None = None) -> Gtk.AboutDialog:
...


Expand Down
24 changes: 10 additions & 14 deletions blueman/gui/GenericList.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
from typing import TYPE_CHECKING, Any
from typing import Any, TypedDict
from collections.abc import Iterable, Mapping, Callable, Collection

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk


if TYPE_CHECKING:
from typing_extensions import TypedDict
class _ListDataDictBase(TypedDict):
id: str
type: type

class _ListDataDictBase(TypedDict):
id: str
type: type

class ListDataDict(_ListDataDictBase, total=False):
renderer: Gtk.CellRenderer
render_attrs: Mapping[str, int]
view_props: Mapping[str, object]
celldata_func: tuple[Callable[[Gtk.TreeViewColumn, Gtk.CellRenderer, Gtk.TreeModelFilter, Gtk.TreeIter, Any],
None], Any]
else:
ListDataDict = dict
class ListDataDict(_ListDataDictBase, total=False):
renderer: Gtk.CellRenderer
render_attrs: Mapping[str, int]
view_props: Mapping[str, object]
celldata_func: tuple[Callable[[Gtk.TreeViewColumn, Gtk.CellRenderer, Gtk.TreeModelFilter, Gtk.TreeIter, Any],
None], Any]


# noinspection PyAttributeOutsideInit
Expand Down
9 changes: 5 additions & 4 deletions blueman/gui/applet/PluginDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
from blueman.main.Builder import Builder
from blueman.main.PluginManager import PluginManager
from blueman.plugins.AppletPlugin import AppletPlugin
from blueman.plugins.BasePlugin import Option, BasePlugin

import gi
gi.require_version("Gtk", "3.0")
gi.require_version("Gdk", "3.0")
from gi.repository import Gtk, Gdk, Gio, GLib, GObject


if TYPE_CHECKING:
from blueman.plugins.BasePlugin import Option, BasePlugin
from blueman.main.Applet import BluemanApplet


Expand Down Expand Up @@ -69,13 +70,13 @@ def construct_settings(self) -> None:
label = Gtk.Label(label="<i >" + v["desc"] + "</i>", wrap=True, use_markup=True, xalign=0.0)
self.pack_start(label, False, False, 0)

def handle_change(self, widget: Gtk.Widget, opt: str, params: "Option", prop: str) -> None:
def handle_change(self, widget: Gtk.Widget, opt: str, params: Option, prop: str) -> None:
val = params["type"](getattr(widget.props, prop))
logging.debug(f"changed {opt} {val}")

self.inst.set_option(opt, val)

def get_control_widget(self, opt: str, params: "Option") -> Gtk.Widget:
def get_control_widget(self, opt: str, params: Option) -> Gtk.Widget:
if params["type"] == bool:
c = Gtk.CheckButton(label=params["name"])

Expand Down Expand Up @@ -329,7 +330,7 @@ def populate(self) -> None:
self.model.insert_sorted(plugin_item, self._model_sort_func)
self.listbox.select_row(self.listbox.get_row_at_index(0))

_T = TypeVar("_T", bound="BasePlugin")
_T = TypeVar("_T", bound=BasePlugin)

def plugin_state_changed(self, _plugins: PluginManager[_T], name: str, loaded: bool) -> None:
logging.debug(f"{name} {loaded}")
Expand Down
7 changes: 2 additions & 5 deletions blueman/main/DbusService.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import logging
import sys
import traceback
from typing import Any, overload, TYPE_CHECKING
from typing import Any, overload, Literal
from collections.abc import Callable, Collection, Mapping

from gi.repository import Gio, GLib

if TYPE_CHECKING:
from typing import Literal


class DbusError(Exception):
_name = "org.blueman.Error"
Expand Down Expand Up @@ -46,7 +43,7 @@ def add_method(self, name: str, arguments: tuple[str, ...], return_values: str |
@overload
def add_method(self, name: str, arguments: tuple[str, ...], return_values: tuple[str, ...],
method: Callable[..., Any], pass_sender: bool = False,
is_async: "Literal[False]" = False) -> None:
is_async: Literal[False] = False) -> None:
...

def add_method(self, name: str, arguments: tuple[str, ...], return_values: str | tuple[str, ...],
Expand Down
46 changes: 24 additions & 22 deletions blueman/main/PulseAudioUtils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from ctypes import *
from enum import IntEnum
from typing import TYPE_CHECKING, Optional, Any
from typing import TYPE_CHECKING, Any, Optional, TypedDict
from collections.abc import Callable, Mapping

from gi.repository import GObject
Expand All @@ -19,23 +19,25 @@

if TYPE_CHECKING:
from ctypes import _FuncPointer, _NamedFuncPointer, _Pointer
from typing_extensions import TypedDict

class CardProfileInfo(TypedDict):
name: str
description: str
n_sinks: int
n_sources: int
priority: int

class CardInfo(TypedDict):
name: str
proplist: dict[str, str]
owner_module: int
driver: str
index: int
profiles: list[CardProfileInfo]
active_profile: str


class CardProfileInfo(TypedDict):
name: str
description: str
n_sinks: int
n_sources: int
priority: int


class CardInfo(TypedDict):
name: str
proplist: dict[str, str]
owner_module: int
driver: str
index: int
profiles: list[CardProfileInfo]
active_profile: str


pa_glib_mainloop_new = libpulse_glib.pa_glib_mainloop_new
pa_glib_mainloop_new.argtypes = [c_void_p]
Expand Down Expand Up @@ -284,7 +286,7 @@ def wrapper(_context: c_void_p, res: int, data: "_FuncPointer") -> None:
logging.error(func.__name__)
pa_operation_unref(op)

def __card_info(self, card_info: "_Pointer[PaCardInfo]") -> "CardInfo":
def __card_info(self, card_info: "_Pointer[PaCardInfo]") -> CardInfo:
return {
"name": card_info[0].name.decode("UTF-8"),
"proplist": self.__get_proplist(card_info[0].proplist),
Expand All @@ -301,10 +303,10 @@ def __card_info(self, card_info: "_Pointer[PaCardInfo]") -> "CardInfo":
"active_profile": card_info[0].active_profile[0].name.decode("UTF-8")
}

def list_cards(self, callback: Callable[[Mapping[str, "CardInfo"]], None]) -> None:
def list_cards(self, callback: Callable[[Mapping[str, CardInfo]], None]) -> None:
self.check_connected()

data: dict[str, "CardInfo"] = {}
data: dict[str, CardInfo] = {}

def handler(entry_info: Optional["_Pointer[PaCardInfo]"], end: bool) -> None:
if end:
Expand All @@ -319,7 +321,7 @@ def handler(entry_info: Optional["_Pointer[PaCardInfo]"], end: bool) -> None:
self.__init_list_callback(pa_context_get_card_info_list,
pa_card_info_cb_t, handler)

def get_card(self, card: int, callback: Callable[["CardInfo"], None]) -> None:
def get_card(self, card: int, callback: Callable[[CardInfo], None]) -> None:
self.check_connected()

def handler(entry_info: Optional["_Pointer[PaCardInfo]"], end: bool) -> None:
Expand Down
9 changes: 3 additions & 6 deletions blueman/main/applet/BluezAgent.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from gettext import gettext as _
from html import escape
from xml.etree import ElementTree
from typing import overload, TYPE_CHECKING, Any
from typing import overload, Any, Literal
from collections.abc import Callable
from blueman.bluemantyping import ObjectPath

Expand All @@ -20,9 +20,6 @@
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

if TYPE_CHECKING:
from typing import Literal


class BluezErrorCanceled(DbusError):
_name = "org.bluez.Error.Canceled"
Expand Down Expand Up @@ -104,7 +101,7 @@ def get_device_string(self, object_path: ObjectPath) -> str:
def ask_passkey(
self,
dialog_msg: str,
is_numeric: "Literal[True]",
is_numeric: Literal[True],
object_path: ObjectPath,
ok: Callable[[int], None],
err: Callable[[BluezErrorCanceled | BluezErrorRejected], None]
Expand All @@ -115,7 +112,7 @@ def ask_passkey(
def ask_passkey(
self,
dialog_msg: str,
is_numeric: "Literal[False]",
is_numeric: Literal[False],
object_path: ObjectPath,
ok: Callable[[str], None],
err: Callable[[BluezErrorCanceled | BluezErrorRejected], None]
Expand Down
21 changes: 9 additions & 12 deletions blueman/main/indicators/GtkStatusIcon.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TYPE_CHECKING, overload, cast
from typing import overload, cast, Protocol
from collections.abc import Callable, Iterable

import gi
Expand All @@ -9,28 +9,25 @@
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from blueman.Functions import create_menuitem
from blueman.plugins.applet.Menu import MenuItemDict, SubmenuItemDict

if TYPE_CHECKING:
from typing_extensions import Protocol

from blueman.plugins.applet.Menu import MenuItemDict, SubmenuItemDict

class MenuItemActivator(Protocol):
def __call__(self, *idx: int) -> None:
...
class MenuItemActivator(Protocol):
def __call__(self, *idx: int) -> None:
...


@overload
def build_menu(items: Iterable[tuple[int, "MenuItemDict"]], activate: "MenuItemActivator") -> Gtk.Menu:
def build_menu(items: Iterable[tuple[int, MenuItemDict]], activate: MenuItemActivator) -> Gtk.Menu:
...


@overload
def build_menu(items: Iterable[tuple[int, "SubmenuItemDict"]], activate: Callable[[int], None]) -> Gtk.Menu:
def build_menu(items: Iterable[tuple[int, SubmenuItemDict]], activate: Callable[[int], None]) -> Gtk.Menu:
...


def build_menu(items: Iterable[tuple[int, "SubmenuItemDict"]], activate: Callable[..., None]) -> Gtk.Menu:
def build_menu(items: Iterable[tuple[int, SubmenuItemDict]], activate: Callable[..., None]) -> Gtk.Menu:
menu = Gtk.Menu()
for index, item in items:
if 'text' in item and 'icon_name' in item:
Expand Down Expand Up @@ -91,5 +88,5 @@ def _update_tooltip(self) -> None:
def set_visibility(self, visible: bool) -> None:
self.indicator.props.visible = visible

def set_menu(self, menu: Iterable["MenuItemDict"]) -> None:
def set_menu(self, menu: Iterable[MenuItemDict]) -> None:
self._menu = build_menu(((item["id"], item) for item in menu), self._on_activate)
6 changes: 2 additions & 4 deletions blueman/main/indicators/IndicatorInterface.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from abc import abstractmethod, ABCMeta
from typing import TYPE_CHECKING
from collections.abc import Iterable

if TYPE_CHECKING:
from blueman.plugins.applet.Menu import MenuItemDict
from blueman.plugins.applet.Menu import MenuItemDict


class IndicatorNotAvailable(RuntimeError):
Expand All @@ -28,5 +26,5 @@ def set_visibility(self, visible: bool) -> None:
...

@abstractmethod
def set_menu(self, menu: Iterable["MenuItemDict"]) -> None:
def set_menu(self, menu: Iterable[MenuItemDict]) -> None:
...
Loading

0 comments on commit 7d7b03e

Please sign in to comment.