Skip to content

Commit 2b162f3

Browse files
committed
Add pydbus stubs
1 parent a46eea7 commit 2b162f3

18 files changed

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

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

stubs/pydbus/pydbus/proxy.pyi

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

stubs/pydbus/pydbus/proxy_method.pyi

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from _typeshed import Unused
2+
from inspect import Signature
3+
from typing import Generic, TypeVar
4+
5+
from .proxy import ProxyObject
6+
7+
_CT = TypeVar("_CT") # __call__ return type
8+
_GT = TypeVar("_GT") # __get__ return type
9+
_PT = TypeVar("_PT") # ProxyObject type
10+
put_signature_in_doc: bool = False
11+
12+
class DBUSSignature(Signature): ...
13+
14+
class ProxyMethod(Generic[_GT, _CT, _PT]):
15+
__signature__: DBUSSignature
16+
17+
def __init__(self, iface_name: str, method: str) -> None: ...
18+
def __call__(self, instance: ProxyObject[_PT], *args: object, timeout: int | None = None) -> _CT: ...
19+
def __get__(self, instance: ProxyObject[_PT], owner: Unused) -> _GT: ...

0 commit comments

Comments
 (0)