2323from inspect import getmembers
2424from itertools import chain
2525from types import MethodType
26- from typing import TYPE_CHECKING , Any , Callable , cast
26+ from typing import TYPE_CHECKING , Any , Callable , Protocol , cast
2727from warnings import warn
2828from weakref import WeakKeyDictionary , WeakValueDictionary
2929
3030from .dbus_common_elements import (
3131 DbusClassMeta ,
3232 DbusInterfaceMetaCommon ,
33+ DbusLocalMemberAsync ,
3334 DbusLocalObjectMeta ,
3435 DbusMemberAsync ,
3536 DbusMemberCommon ,
3940 DbusRemoteObjectMeta ,
4041)
4142from .dbus_common_funcs import get_default_bus
42- from .dbus_proxy_async_method import DbusLocalMethodAsync , DbusMethodAsync
43- from .dbus_proxy_async_property import (
44- DbusLocalPropertyAsync ,
45- DbusPropertyAsync ,
46- )
47- from .dbus_proxy_async_signal import DbusLocalSignalAsync , DbusSignalAsync
43+ from .dbus_proxy_async_method import DbusMethodAsync
44+ from .dbus_proxy_async_property import DbusPropertyAsync
4845from .sd_bus_internals import SdBusInterface
4946
5047if TYPE_CHECKING :
6158 Union ,
6259 )
6360
64- from .dbus_common_elements import DbusBoundAsync
65- from .sd_bus_internals import SdBus , SdBusSlot
61+ from .sd_bus_internals import SdBus
6662
6763 T = TypeVar ('T' )
6864 Self = TypeVar ('Self' , bound = "DbusInterfaceBaseAsync" )
@@ -239,15 +235,9 @@ def _map_dbus_elements(
239235 if attr .interface_name != interface_name :
240236 return
241237
242- if isinstance (attr , DbusMethodAsync ):
243- meta .dbus_member_to_python_attr [attr .method_name ] = attr_name
244- meta .python_attr_to_dbus_member [attr_name ] = attr .method_name
245- elif isinstance (attr , DbusPropertyAsync ):
246- meta .dbus_member_to_python_attr [attr .property_name ] = attr_name
247- meta .python_attr_to_dbus_member [attr_name ] = attr .property_name
248- elif isinstance (attr , DbusSignalAsync ):
249- meta .dbus_member_to_python_attr [attr .signal_name ] = attr_name
250- meta .python_attr_to_dbus_member [attr_name ] = attr .signal_name
238+ if isinstance (attr , DbusMemberAsync ):
239+ meta .dbus_member_to_python_attr [attr .member_name ] = attr_name
240+ meta .python_attr_to_dbus_member [attr_name ] = attr .member_name
251241 else :
252242 raise TypeError (f"Unknown D-Bus element: { attr !r} " )
253243
@@ -344,23 +334,14 @@ def export_to_dbus(
344334 local_object_meta .attached_bus = bus
345335 local_object_meta .serving_object_path = object_path
346336 # TODO: can be optimized with a single loop
347- interface_map : Dict [str , List [DbusBoundAsync ]] = {}
337+ interface_map : Dict [str , List [DbusLocalMemberAsync ]] = {}
348338
349339 for key , value in getmembers (self ):
350340 assert not isinstance (value , DbusMemberAsync )
351341
352- if isinstance (value , DbusLocalMethodAsync ):
353- interface_name = value .dbus_method .interface_name
354- if not value .dbus_method .serving_enabled :
355- continue
356- elif isinstance (value , DbusLocalPropertyAsync ):
357- interface_name = value .dbus_property .interface_name
358- if not value .dbus_property .serving_enabled :
359- continue
360- elif isinstance (value , DbusLocalSignalAsync ):
361- interface_name = value .dbus_signal .interface_name
362- if not value .dbus_signal .serving_enabled :
363- continue
342+ if isinstance (value , DbusLocalMemberAsync ) and \
343+ value .member .serving_enabled :
344+ interface_name = value .member .interface_name
364345 else :
365346 continue
366347
@@ -372,54 +353,21 @@ def export_to_dbus(
372353
373354 interface_member_list .append (value )
374355
356+ export_handle = DbusExportHandle ()
357+
375358 for interface_name , member_list in interface_map .items ():
376359 new_interface = SdBusInterface ()
377360 for dbus_something in member_list :
378- if isinstance (dbus_something , DbusLocalMethodAsync ):
379- new_interface .add_method (
380- dbus_something .dbus_method .method_name ,
381- dbus_something .dbus_method .input_signature ,
382- dbus_something .dbus_method .input_args_names ,
383- dbus_something .dbus_method .result_signature ,
384- dbus_something .dbus_method .result_args_names ,
385- dbus_something .dbus_method .flags ,
386- dbus_something ._dbus_reply_call ,
387- )
388- elif isinstance (dbus_something , DbusLocalPropertyAsync ):
389- getter = dbus_something ._dbus_reply_get
390- dbus_property = dbus_something .dbus_property
391-
392- if (
393- dbus_property .property_setter is not None
394- and
395- dbus_property .property_setter_is_public
396- ):
397- setter = dbus_something ._dbus_reply_set
398- else :
399- setter = None
400-
401- new_interface .add_property (
402- dbus_property .property_name ,
403- dbus_property .property_signature ,
404- getter ,
405- setter ,
406- dbus_property .flags ,
407- )
408- elif isinstance (dbus_something , DbusLocalSignalAsync ):
409- new_interface .add_signal (
410- dbus_something .dbus_signal .signal_name ,
411- dbus_something .dbus_signal .signal_signature ,
412- dbus_something .dbus_signal .args_names ,
413- dbus_something .dbus_signal .flags ,
414- )
415- else :
416- raise TypeError
417-
361+ dbus_something ._append_to_interface (new_interface ,
362+ export_handle )
418363 bus .add_interface (new_interface , object_path ,
419364 interface_name )
420365 local_object_meta .activated_interfaces .append (new_interface )
421366
422- return DbusExportHandle (local_object_meta )
367+ assert new_interface .slot is not None
368+ export_handle .append (new_interface .slot )
369+
370+ return export_handle
423371
424372 def _connect (
425373 self ,
@@ -475,13 +423,23 @@ def new_proxy(
475423 return new_object
476424
477425
426+ class Closeable (Protocol ):
427+ def close (self ) -> None :
428+ ...
429+
430+
478431class DbusExportHandle :
479- def __init__ (self , local_meta : DbusLocalObjectMeta ):
480- self ._dbus_slots : List [SdBusSlot ] = [
481- i .slot
482- for i in local_meta .activated_interfaces
483- if i .slot is not None
484- ]
432+ def __init__ (self , * items : Closeable ) -> None :
433+ self ._items = list (items )
434+
435+ def append (self , item : Closeable ) -> None :
436+ self ._items .append (item )
437+
438+ def close (self ) -> None :
439+ while self ._items :
440+ self ._items .pop ().close ()
441+
442+ stop = close # for backwards compatibility
485443
486444 async def __aenter__ (self ) -> DbusExportHandle :
487445 return self
@@ -495,16 +453,12 @@ def __exit__(
495453 exc_value : Any ,
496454 traceback : Any ,
497455 ) -> None :
498- self .stop ()
456+ self .close ()
499457
500458 async def __aexit__ (
501459 self ,
502460 exc_type : Any ,
503461 exc_value : Any ,
504462 traceback : Any ,
505463 ) -> None :
506- self .stop ()
507-
508- def stop (self ) -> None :
509- for slot in self ._dbus_slots :
510- slot .close ()
464+ self .close ()
0 commit comments