Skip to content

Commit 5bdc845

Browse files
committed
Add pydbus stubs
1 parent a46eea7 commit 5bdc845

18 files changed

+577
-0
lines changed

stubs/pydbus/METADATA.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version = "0.6.*"
2+
requires = ["pygobject-stubs"]
3+
upstream_repository = "https://github.com/LEW21/pydbus"

stubs/pydbus/pydbus/__init__.pyi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from gi.repository.GLib import Variant
2+
3+
from .bus import SessionBus, SystemBus, connect
4+
5+
__all__ = ["SessionBus", "SystemBus", "Variant", "connect"]

stubs/pydbus/pydbus/auto_names.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def auto_bus_name(bus_name: str) -> str: ...
2+
def auto_object_path(bus_name: str, object_path: str | None = None) -> str: ...

stubs/pydbus/pydbus/bus.pyi

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
import types
2+
from typing import Any, Generic, Literal, TypedDict, TypeVar, overload, type_check_only
3+
from typing_extensions import Self
4+
5+
from gi.repository import Gio
6+
7+
from .bus_names import OwnMixin, WatchMixin
8+
from .generic import bound_signal
9+
from .proxy import ProxyMixin, _CompositeObject
10+
from .publication import PublicationMixin
11+
from .registration import RegistrationMixin
12+
from .request_name import RequestNameMixin
13+
from .subscription import SubscriptionMixin
14+
15+
_T = TypeVar("_T")
16+
_ST = TypeVar("_ST") # signal type
17+
18+
def bus_get(type: Gio.BusType) -> Bus[object]: ...
19+
def connect(address: str) -> Bus[object]: ...
20+
@type_check_only
21+
class _DBusOrgFreedesktopDBus:
22+
# Incomplete interface to org.freedesktop.DBus
23+
Features: list[str]
24+
25+
def GetId(self) -> str: ...
26+
27+
@type_check_only
28+
class _DBusOrgFreedesktopPolicyKit1Authority:
29+
# Incomplete interface to org.freedesktop.PolicyKit1.Authority
30+
BackendFeatures: int # flags
31+
BackendName: str
32+
BackendVersion: str
33+
34+
@type_check_only
35+
class OrgBluezAdapter1Dict(TypedDict, total=False):
36+
Address: str
37+
AddressType: Literal["public", "random"]
38+
Alias: str
39+
Class: int
40+
Connectable: bool
41+
Discoverable: bool
42+
DiscoverableTimeout: int
43+
Discovering: bool
44+
Manufacturer: int
45+
Modalias: str
46+
Name: str
47+
Pairable: bool
48+
PairableTimeout: int
49+
Powered: bool
50+
Roles: list[str]
51+
UUIDs: list[str]
52+
Version: int
53+
54+
@type_check_only
55+
class OrgBluezDevice1Dict(TypedDict, total=False):
56+
Adapter: str
57+
Address: str
58+
AddressType: Literal["public", "random"]
59+
Alias: str
60+
Appearance: int
61+
Blocked: bool
62+
Bonded: bool
63+
Class: int
64+
Connected: bool
65+
Icon: str
66+
LegacyPairing: bool
67+
Modalias: str
68+
Name: str
69+
Paired: bool
70+
ServicesResolved: bool
71+
Trusted: bool
72+
UUIDs: list[str]
73+
WakeAllowed: bool
74+
75+
@type_check_only
76+
class OrgBluezInput1Dict(TypedDict, total=False):
77+
ReconnectMode: str
78+
79+
@type_check_only
80+
class OrgBluezMedia1Dict(TypedDict, total=False):
81+
SupportedUUIDs: list[str]
82+
83+
@type_check_only
84+
class OrgBluezMediaControl1Dict(TypedDict, total=False):
85+
Connected: bool
86+
87+
@type_check_only
88+
class OrgBluezBattery1Dict(TypedDict, total=False):
89+
Percentage: int
90+
Source: str
91+
92+
@type_check_only
93+
class OrgBluezGattService1Dict(TypedDict, total=False):
94+
Device: str
95+
Handle: int
96+
Includes: list[str]
97+
Primary: bool
98+
UUID: str
99+
100+
@type_check_only
101+
class OrgBluezGattCharacteristic1Dict(TypedDict, total=False):
102+
Flags: list[str]
103+
Handle: int
104+
MTU: int
105+
Service: str
106+
UUID: str
107+
Value: list[int]
108+
109+
@type_check_only
110+
class OrgBluezGattDescriptor1Dict(TypedDict, total=False):
111+
Characteristic: str
112+
Handle: int
113+
UUID: str
114+
Value: list[int]
115+
116+
@type_check_only
117+
class OrgBluezLEAdvertisingManager1Dict(TypedDict, total=False):
118+
ActiveInstances: int
119+
SupportedCapabilities: dict[str, int] # e.g. MaxTxPower: 7
120+
SupportedFeatures: list[str]
121+
SupportedIncludes: list[str]
122+
SupportedInstances: int
123+
SupportedSecondaryChannels: list[str]
124+
125+
# This is for keys under /org/bluez/hci0/*
126+
_OrgBluezDict = TypedDict(
127+
"_OrgBluezDict",
128+
{
129+
"org.bluez.Adapter1": OrgBluezAdapter1Dict,
130+
"org.bluez.Battery1": OrgBluezBattery1Dict,
131+
"org.bluez.Device1": OrgBluezDevice1Dict,
132+
"org.bluez.GattCharacteristic1": OrgBluezGattCharacteristic1Dict,
133+
"org.bluez.GattDescriptor1": OrgBluezGattDescriptor1Dict,
134+
"org.bluez.GattService1": OrgBluezGattService1Dict,
135+
"org.bluez.Input1": OrgBluezInput1Dict,
136+
"org.bluez.LEAdvertisingManager1": OrgBluezLEAdvertisingManager1Dict,
137+
"org.bluez.Media1": OrgBluezMedia1Dict,
138+
"org.bluez.MediaControl1": OrgBluezMediaControl1Dict,
139+
# The following always appear as empty dictionaries on my system.
140+
"org.bluez.AgentManager1": dict[str, Any],
141+
"org.bluez.BatteryProviderManager1": dict[str, Any],
142+
"org.bluez.NetworkServer1": dict[str, Any],
143+
"org.bluez.ProfileManager1": dict[str, Any],
144+
"org.freedesktop.DBus.Introspectable": dict[str, Any],
145+
"org.freedesktop.DBus.Properties": dict[str, Any],
146+
},
147+
total=False,
148+
)
149+
150+
@type_check_only
151+
class _OrgFreedesktopDBusObjectManager:
152+
@staticmethod
153+
def GetManagedObjects() -> dict[str, _OrgBluezDict]: ...
154+
155+
@type_check_only
156+
class _OrgBluez(_CompositeObject[_T]):
157+
def __getitem__( # type: ignore[override]
158+
self, key: Literal["org.freedesktop.DBus.ObjectManager"]
159+
) -> _OrgFreedesktopDBusObjectManager: ...
160+
161+
@type_check_only
162+
class _OrgFreedesktopNotifications(_CompositeObject[_T], Generic[_T, _ST]):
163+
Inhibited: bool
164+
ActivationToken: bound_signal[_ST]
165+
ActionInvoked: bound_signal[_ST]
166+
NotificationClosed: bound_signal[_ST]
167+
168+
def CloseNotification(self, id: int) -> None: ...
169+
def GetCapabilities(self) -> list[str]: ... # We could use Literal[] here but KDE also returns its own not in the spec.
170+
def GetServerInformation(self) -> tuple[str, str, str, str]: ...
171+
def Inhibit(self, name: str, reason: str, hints: dict[str, bool | bytes | int | str]) -> int | None: ...
172+
def Notify(
173+
self,
174+
app_name: str,
175+
replaces_id: int,
176+
app_icon: str,
177+
summary: str,
178+
body: str,
179+
actions: list[str],
180+
hints: dict[str, bool | bytes | int | str], # See https://specifications.freedesktop.org/notification-spec/1.3/hints.html
181+
expire_timeout: int,
182+
) -> int: ...
183+
def UnInhibit(self, key: int) -> int | None: ...
184+
185+
class Bus(ProxyMixin[_T], RequestNameMixin[_T], OwnMixin, WatchMixin, SubscriptionMixin, RegistrationMixin[_T], PublicationMixin):
186+
Type: type[Gio.BusType] = ...
187+
autoclose: bool
188+
con: Gio.DBusConnection
189+
190+
def __init__(self, gio_con: Gio.DBusConnection) -> None: ...
191+
def __enter__(self) -> Self: ...
192+
def __exit__(
193+
self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: types.TracebackType | None
194+
) -> None: ...
195+
@property
196+
def dbus(self) -> _DBusOrgFreedesktopDBus: ...
197+
@property
198+
def polkit_authority(self) -> _DBusOrgFreedesktopPolicyKit1Authority: ...
199+
@overload # type: ignore[override]
200+
def get(self, bus_name: Literal[".Notifications"]) -> _OrgFreedesktopNotifications[_T, object]: ...
201+
@overload
202+
def get(self, bus_name: Literal["org.freedesktop.Notifications"]) -> _OrgFreedesktopNotifications[_T, object]: ...
203+
@overload
204+
def get(self, bus_name: Literal["org.bluez"], object_path: Literal["/"]) -> _OrgBluez[_T]: ...
205+
@overload
206+
def get(self, bus_name: str, object_path: str) -> Any: ...
207+
208+
def SystemBus() -> Bus[object]: ...
209+
def SessionBus() -> Bus[object]: ...

stubs/pydbus/pydbus/bus_names.pyi

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from collections.abc import Callable
2+
3+
from gi.repository import Gio
4+
5+
from .exitable import Exitable
6+
7+
class NameOwner(Exitable):
8+
Flags: Gio.BusNameOwnerFlags
9+
10+
def __init__(
11+
self,
12+
con: Gio.DBusConnection,
13+
name: str,
14+
flags: Gio.BusNameOwnerFlags,
15+
name_aquired_handler: Callable[[str], None],
16+
name_lost_handler: Callable[[str], None],
17+
) -> None: ...
18+
def unown(self) -> None: ... # added by ExitableWithAliases('unown')
19+
20+
class NameWatcher(Exitable):
21+
Flags: Gio.BusNameWatcherFlags
22+
23+
def __init__(
24+
self,
25+
con: Gio.DBusConnection,
26+
name: str,
27+
flags: Gio.BusNameWatcherFlags,
28+
name_appeared_handler: Callable[[str], None],
29+
name_vanished_handler: Callable[[str], None],
30+
) -> None: ...
31+
def unwatch(self) -> None: ... # added by ExitableWithAliases('unwatch')
32+
33+
class OwnMixin:
34+
NameOwnerFlags: Gio.BusNameOwnerFlags
35+
36+
def own_name(
37+
self,
38+
name: str,
39+
flags: Gio.BusNameOwnerFlags = ...,
40+
name_aquired: Callable[[str], None] | None = ...,
41+
name_lost: Callable[[str], None] | None = ...,
42+
) -> NameOwner: ...
43+
44+
class WatchMixin:
45+
NameWatcherFlags: Gio.BusNameWatcherFlags
46+
47+
def watch_name(
48+
self,
49+
name: str,
50+
flags: Gio.BusNameWatcherFlags = ...,
51+
name_appeared: Callable[[str], None] | None = ...,
52+
name_vanished: Callable[[str], None] | None = ...,
53+
) -> NameWatcher: ...

stubs/pydbus/pydbus/exitable.pyi

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import types
2+
from collections.abc import Iterable
3+
from typing_extensions import Self
4+
5+
class Exitable:
6+
def __enter__(self) -> Self: ...
7+
def __exit__(
8+
self,
9+
exc_type: type[BaseException] | None = None,
10+
exc_value: BaseException | None = None,
11+
traceback: types.TracebackType | None = None,
12+
) -> None: ...
13+
14+
def ExitableWithAliases(*exit_methods: Iterable[str]) -> Exitable: ...

stubs/pydbus/pydbus/generic.pyi

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import types
2+
from _typeshed import Unused
3+
from collections.abc import Callable
4+
from typing import Generic, TypeVar, overload
5+
from typing_extensions import Self
6+
7+
class subscription:
8+
callback_list: list[Callable[..., object]]
9+
callback: Callable[..., object]
10+
11+
def __init__(self, callback_list: list[Callable[..., object]], callback: Callable[..., object]) -> None: ...
12+
def unsubscribe(self) -> None: ...
13+
def disconnect(self) -> None: ...
14+
def __enter__(self) -> Self: ...
15+
def __exit__(
16+
self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: types.TracebackType | None
17+
) -> None: ...
18+
19+
_T = TypeVar("_T")
20+
21+
class bound_signal(Generic[_T]):
22+
__signal__: signal[_T]
23+
24+
def __init__(self, signal: signal[_T], instance: _T) -> None: ...
25+
@property
26+
def callbacks(self) -> list[Callable[..., object]]: ...
27+
def connect(self, callback: Callable[..., object]) -> subscription: ...
28+
def emit(self, *args: object) -> None: ...
29+
def __call__(self, *args: object) -> None: ...
30+
31+
class signal(Generic[_T]):
32+
map: dict[object, Callable[..., object]]
33+
34+
def __init__(self) -> None: ...
35+
def connect(self, object: str, callback: Callable[..., object]) -> subscription: ...
36+
def emit(self, object: str, *args: object) -> None: ...
37+
@overload
38+
def __get__(self, instance: None, owner: Unused) -> Self: ...
39+
@overload
40+
def __get__(self, instance: _T, owner: Unused) -> bound_signal[_T]: ...
41+
def __set__(self, instance: Unused, value: Unused) -> None: ... # Always raises
42+
43+
bound_method: Callable[..., None] # type(signal().emit)

stubs/pydbus/pydbus/identifier.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def isident(s: str) -> bool: ...
2+
def filter_identifier(name: str) -> str: ...
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from typing import Generic, NamedTuple, TypeVar
2+
3+
from gi.repository import Gio
4+
5+
from .bus import Bus
6+
7+
_T = TypeVar("_T")
8+
9+
class AuthorizationResult(NamedTuple):
10+
is_authorized: bool
11+
is_challenge: bool
12+
details: dict[str, str]
13+
14+
class MethodCallContext(Generic[_T]):
15+
def __init__(self, gdbus_method_invocation: Gio.DBusMethodInvocation) -> None: ...
16+
@property
17+
def bus(self) -> Bus[_T]: ...
18+
@property
19+
def sender(self) -> str: ...
20+
@property
21+
def object_path(self) -> str: ...
22+
@property
23+
def interface_name(self) -> str: ...
24+
@property
25+
def method_name(self) -> str: ...
26+
def check_authorization(self, action_id: str, details: dict[str, str], interactive: bool = False) -> AuthorizationResult: ...
27+
def is_authorized(self, action_id: str, details: dict[str, str], interactive: bool = False) -> bool: ...

stubs/pydbus/pydbus/proxy.pyi

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from typing import Generic, TypeVar, type_check_only
2+
from typing_extensions import Self
3+
from xml.etree.ElementTree import Element
4+
5+
from .bus import Bus
6+
7+
_T = TypeVar("_T")
8+
9+
class ProxyMixin(Generic[_T]):
10+
def get(self, bus_name: str, object_path: str | None = None, *, timeout: int | None = None) -> _CompositeObject[_T]: ...
11+
12+
class ProxyObject(Generic[_T]):
13+
def __init__(self, bus: Bus[_T], bus_name: str, path: str, object: Self | None = None) -> None: ...
14+
def __getattr__(self, name: str) -> _T: ...
15+
def __setattr__(self, name: str, value: _T) -> None: ...
16+
17+
@type_check_only
18+
class _CompositeObject(ProxyObject[_T]): # Inside CompositeInterface
19+
def __getitem__(self, iface: str) -> ProxyObject[_T]: ...
20+
21+
@type_check_only
22+
class _interface(ProxyObject[_T]): # inside Interface
23+
@staticmethod
24+
def _Introspect() -> None: ...
25+
26+
def Interface(iface: Element) -> _interface[object]: ...
27+
def CompositeInterface(introspection: Element) -> _CompositeObject[object]: ...

0 commit comments

Comments
 (0)