+
    icV  c                   s    ^ RI t ^ RIt^ RI Ht ^ RIHt ^ RIHt ^ RIHt ^ RI	H
t
Ht ^ RIHtHtHtHt ^ RIHt . ROtR
tRtRtR tR tR t ! R R	]4      tRR ltR tR t ! R R]4      tR# )i    N)	Parameter)get_type_hints)get_dbus_name)Signal)DBusSpecificationErrorDBusSpecification)get_dbus_typeis_base_typeget_type_argumentsTuple)XMLGeneratordbus_signalZ__dbus_xml__Z*__dbus_method_returns_multiple_arguments__Z-__dbus_handler_accepts_additional_arguments__c                (    \        V \        R4       V # )aP  Decorator for returning multiple arguments from a DBus method.

The decorator allows to generate multiple output arguments in the
XML specification of the decorated DBus method. Otherwise, there
will be only one output argument in the specification.

Define a DBus method with multiple output arguments:

.. code-block:: python

    @returns_multiple_arguments
    def Method(self) -> Tuple[Int, Bool]:
        return 0, False

The generated XML specification of the example:

.. code-block:: xml

    <method name="Method">
        <arg direction="out" name="return_0" type="i"/>
        <arg direction="out" name="return_1" type="b"/>
    </method>

If the XML specification is not generated by the dbus_interface
decorator, the returns_multiple_arguments decorator has no effect.

:param method: a DBus method
:return: a DBus method with a flag
T)setattr$RETURNS_MULTIPLE_ARGUMENTS_ATTRIBUTEmethod   &</usr/lib/python3.14/site-packages/dasbus/server/interface.pyreturns_multiple_argumentsr   :   s    < F8$?M    c                r   )a  Decorator for accepting extra arguments in a DBus method.

The decorator allows the server object handler to propagate
additional information about the DBus call into the decorated
method.

Use a dictionary of keyword arguments:

.. code-block:: python

    @accepts_additional_arguments
    def Method(x: Int, y: Str, **info):
        pass

Or use keyword only parameters:

.. code-block:: python

    @accepts_additional_arguments
    def Method(x: Int, y: Str, *, call_info):
        pass

At this moment, the library provides only the call_info argument
generated by GLibServer.get_call_info, but the additional arguments
can be customized in the _get_additional_arguments method of the
server object handler.

:param method: a DBus method
:return: a DBus method with a flag
T)r   &ACCEPTS_ADDITIONAL_ARGUMENTS_ATTRIBUTEr   r   r   accepts_additional_argumentsr   \   s    > F:DAMr   c                s$    \        V \        R4      # )zmDoes the given DBus method accept additional arguments?

:param method: a DBus method
:return: True or False
F)getattrr   r   r   r   "are_additional_arguments_supportedr      s     6A5IIr   c                   sD   a  ] tR t^t o RtR]3R ltR tR tR t	Rt
V tR# )r   a  DBus signal.

Can be used as:

.. code-block:: python

    Signal = dbus_signal()

Or as a method decorator:

.. code-block:: python

    @dbus_signal
    def Signal(x: Int, y: Double):
        pass

Signal is defined by the type hints of a decorated method.
This method is accessible as: signal.definition

If the signal is not defined by a method, it is expected to
have no arguments and signal.definition is equal to None.
Nc                s,    Wn         W n        RV n        R# )zsCreate a signal descriptor.

:param definition: a definition of the emit function
:param factory: a signal factory
N
definitionfactoryname)selfr   r      &&&r   __init__Zdbus_signal.__init__   s     %	r   c                s    V P                   e   R# RP                  \        V 4      P                  P	                  4       VP	                  4       4      V n         R# )a  Set a name of the descriptor

The descriptor has been assigned to the specified name.
Generate a name of a private attribute that will be set
to a signal in the ``__get__`` method.

For example: ``__dbus_signal_my_name``

:param owner: the owning class
:param name: the descriptor name
Nz__{}_{})r   formatZtype__name__Zlower)r   ownerr   r   r   __set_name__Zdbus_signal.__set_name__   sB     99 $$J%%'JJL
	r   c                s    Vf   V # \        WP                  R4      pVf'   V P                  4       p\        WP                  V4       V# )aE  Get a value of the descriptor.

If the descriptor is accessed as a class attribute,
return the descriptor.

If the descriptor is accessed as an instance attribute,
return a signal created by the signal factory.

:param instance: an instance of the owning class
:param owner: an owning class
:return: a value of the attribute
N)r   r   r   r   )r   instancer"   Zsignals   &&& r   __get__Zdbus_signal.__get__   sB     K99d3>\\^FHii0r   c                s    \        R4      h)zSet a value of the descriptor.zCan't set DBus signal.)ZAttributeError)r   r$   Zvaluer   r   __set__Zdbus_signal.__set__   s    566r   r   )r!   
__module____qualname____firstlineno____doc__r   r   r#   r%   r&   __static_attributes____classdictcell__Z__classdict__   @r   r   r      s*     , #' 
(07 7r   c                s   a a V V3R lpV# )a  DBus interface.

A new DBus interface can be defined as:

.. code-block:: python

    @dbus_interface
    class Interface():
        ...

The interface will be generated from the given class cls
with a name interface_name and added to the DBus XML
specification of the class.

The XML specification is accessible as:
.. code-block:: python

    Interface.__dbus_xml__

It is conventional for member names on DBus to consist
of capitalized words with no punctuation. The generator
of the XML specification enforces this convention to
prevent unintended changes in the specification. You can
provide the XML specification yourself, or override the
generator class to work around these constraints.

:param interface_name: a DBus name of the interface
:param namespace: a sequence of strings
c                 sp   < \        . SOSN5!  p\        P                  W4      p\        V \        V4       V # N)r   DBusSpecificationGeneratorgenerate_specificationr   DBUS_XML_ATTRIBUTE)clsr   xmlinterface_name	namespaces   &  r   	decoratedZ!dbus_interface.<locals>.decorated   s7    8i88(??J'-
r    )r5   r6   r7   s   ff r   dbus_interfacer9      s    < r   c                sR    \         P                  V 4      p\        V \        V4       V # )ax  DBus class.

A new DBus class can be defined as:

.. code-block:: python

    @dbus_class
    class Class(Interface):
        ...

DBus class can implement DBus interfaces, but it cannot
define a new interface.

The DBus XML specification will be generated from
implemented interfaces (inherited) and it will be
accessible as:

.. code-block:: python

    Class.__dbus_xml__

)r0   r1   r   r2   )r3   r4      & r   
dbus_classr;     s&    . %
;
;C
@CC#S)Jr   c                sl    \        V \        R4      pVf   \        RP                  \        4      4      hV# )zReturn XML specification of an object.

:param obj: an object decorated with @dbus_interface or @dbus_class
:return: a string with XML specification
Nz)XML specification is not defined at '{}'.)r   r2   r   r    )ZobjZxml_specificationr:   r   get_xmlr<     s@      %7> $7>>"
 	
 r   c                   sP  a  ] tR tRt o Rt]t]P                  ! R4      t	]
RR l4       t]
R 4       t]
R 4       t]
R 4       t]
R	 4       t]
R
 4       t]
R 4       t]
R 4       t]
R 4       t]
R 4       t]
R 4       t]
R 4       t]
R 4       t]
R 4       t]
R 4       t]
R 4       tRtV tR# )r0   i/  z,Class for generating DBus XML specification.z[A-Z][A-Za-z0-9]*Nc                s    V P                  V4      pV'       d9   V P                  4       pVP                  V4       V P                  VVV4      pWSV&   V P	                  W4      pV P
                  P                  V4      # )a  Generates DBus XML specification for given class.

If class defines a new interface, it will be added to
the specification.

:param interface_cls: class object to decorate
:param str interface_name: name of the interface defined by class
:return str: DBus specification in XML
)_collect_interfaces_collect_standard_interfacesupdate_generate_interface_generate_nodexml_generatorZelement_to_xml)r3   interface_clsr5   
interfacesZall_interfaces	interfacenode   &&&    r   r1   Z1DBusSpecificationGenerator.generate_specification8  s     ,,];
  ==?N!!*-//I
 *3~& !!-<  //55r   c                s    V P                   P                  \        P                  4      pV P                   P	                  V4      # )z|Collect standard interfaces.

Standard interfaces are implemented by default.

:return: a dictionary of standard interfaces
)rB   xml_to_elementr   ZSTANDARD_INTERFACESget_interfaces_from_node)r3   rF   r:   r   r>   Z7DBusSpecificationGenerator._collect_standard_interfacesU  s<       //11
   99$??r   c                s   / p\        \        P                  ! V4      4       Fe  p\        V\        R4      pV'       g   K  V P
                  P                  V4      pV P
                  P                  V4      pVP                  V4       Kg  	  V# )zCollect interfaces implemented by the class.

Returns a dictionary that maps interface names
to interface elements.

:param interface_cls: a class object
:return: a dictionary of implemented interfaces
N)	ZreversedinspectZgetmror   r2   rB   rH   rI   r?   )r3   rC   rD   memberZ
member_xmlrF   Znode_interfacess   &&     r   r=   Z.DBusSpecificationGenerator._collect_interfacesb  s|     
 w~~m<=F );TBJ $$33J?D!//HHNOo. > r   c                s>   V P                   P                  V4      p\        P                  ! V4       F  w  rVV P	                  V4      '       g   K  V P                  W%4      '       d   K7  V P                  V4      '       d   V P                  We4      pMlV P                  V4      '       d   V P                  We4      pMCV P                  V4      '       d   V P                  We4      pM\        RP                  V4      4      hV P                   P                  WG4       K  	  V# )a@  Generate interface defined by given class.

:param interface_cls: a class object that defines the interface
:param interfaces: a dictionary of implemented interfaces
:param interface_name: a name of the new interface
:return: a new interface element

:raises DBusSpecificationError: if a class member cannot be exported
z+Unsupported definition of DBus member '{}'.)rB   Zcreate_interfacerJ   Z
getmembers_is_exportable_is_defined
_is_signal_generate_signal_is_property_generate_property
_is_method_generate_methodr   r    	add_child)r3   rC   rD   r5   rE   member_namerK   elements   &&&&    r   r@   Z.DBusSpecificationGenerator._generate_interface|  s     %%66~F	 $+#5#5m#DK%%k22 z77 ~~f%%..vC!!&))00E''..vC,AHH#  ''	;1 $E4 r   c                sJ    \        V P                  P                  V4      4      # )zIs the name of a class member exportable?

The name is exportable if it follows the DBus specification.
Only CamelCase names are allowed.
)ZboolNAME_PATTERNZ	fullmatch)r3   rU      &&r   rL   Z)DBusSpecificationGenerator._is_exportable  s      C$$..{;<<r   c                s    VP                  4        FT  pV FK  pV P                  P                  V4      '       g   K&  V P                  P                  WB4      '       g   KI    R# 	  KV  	  R# )zIs the member name defined in given interfaces?

:param interfaces: a dictionary of interfaces
:param member_name: a name of the class member
:return: True if the name is defined, otherwise False
TF)ZvaluesrB   Z	is_memberZhas_name)r3   rD   rU   rE   rK      &&&  r   rM   Z&DBusSpecificationGenerator._is_defined  s]     $**,I#((226::((11&FF $ - r   c                "    \        V\        4      # )z"Is the class member a DBus signal?)
isinstancer   r3   rK   rX   r   rN   Z%DBusSpecificationGenerator._is_signal  s     &+..r   c                s   V P                   P                  V4      pVP                  pV'       g   V# V P                  V4       F  w  rVpV\        P
                  8X  d   \        RP                  V4      4      h\        P
                  pV P                   P                  V\        V4      V4      pV P                   P                  W84       K  	  V# )zGenerate signal defined by a class member.

:param member: a dbus_signal object.
:param member_name: a name of the signal
:return: a signal element

raises DBusSpecificationError: if signal has defined return type
z(Invalid return type of DBus signal '{}'.)rB   Zcreate_signalr   _iterate_parametersr   DIRECTION_OUTr   r    create_parameterr   rT   )	r3   rK   rU   rV   r   r   	type_hint	direction	parameter	   &&&      r   rO   Z+DBusSpecificationGenerator._generate_signal  s     ##11+>""N*-*A*A&*I&DY-;;;,"F;/  *77I))::i(I
 '';! +J$ r   c              #  s   "   \         P                  ! V4      pV P                  W4       Rj  xL
  V P                  W4       Rj  xL
  R#  L L5i)zIterate over method parameters.

For every parameter returns its name, a type hint and a direction.

:param member: a method object
:return: an iterator

raises DBusSpecificationError: if parameters are invalid
N)rJ   	signature_iterate_in_parameters_iterate_out_parameters)r3   rK   rd   s   && r   r]   Z.DBusSpecificationGenerator._iterate_parameters  sH      %%f-	--f@@@..vAAA 	AAs!   +AAAAAAc              #  s  "   \         P                  p\        V4      p\        VP                  4      R,           F  pVP                  V,          P
                  pV\        P                  \        P                  39   d   \        V4      '       d   KX  V\        P                  8w  d   \        R4      hWT9  d   \        RP                  V4      4      hWTV,          V3x  K  	  R# 5i)zIterate over input parameters.:i   NNz1Only positional or keyword arguments are allowed.z!Undefined type of parameter '{}'.N)r   ZDIRECTION_INr   ZlistZ
parameterskindr    ZVAR_KEYWORDZKEYWORD_ONLYr   ZPOSITIONAL_OR_KEYWORDr   r    )r3   rK   rd   ra   Z
type_hintsr   rg   rG   r   re   Z1DBusSpecificationGenerator._iterate_in_parameters  s      &22	#F+
 --.r22D''-22D 	--y/E/EFF:6BBy666,G 
 %,7>>tD  4()33+ 3s   C#C%c              #  s  "   \         P                  p\         P                  pVP                  pWRP                  J d   R# Vf   R# \        V\        R4      '       ds   \        V\        4      '       g   \        R4      h\        V4      p\        V4      ^8  d   \        R4      h\        V4       F  w  rxRP                  W74      W3x  K  	  R# W5V3x  R# 5i)zIterate over output parameters.NFz'Expected a tuple of multiple arguments.z+Expected a tuple of more than one argument.z{}_{})r   ZRETURN_PARAMETERr^   Zreturn_annotationZemptyr   r   r   r	   r   r   ZlenZ	enumerater    )	r3   rK   rd   r   ra   r`   Z	type_argsZiZtype_argrc   r   rf   Z2DBusSpecificationGenerator._iterate_out_parameters  s      !11%33	//	 '  6?GG	511,= 
 +95I9~!,A 
  )3nnT-xBB  4  y((s   CCc                rZ   )z$Is the class member a DBus property?)r[   Zpropertyr\   rX   r   rP   Z'DBusSpecificationGenerator._is_propertyC  s     &(++r   c                sX   RpRp VP                   '       d1   V P                  VP                   4      w  w  rTp\        P                  pVP                  '       d1   V P                  VP                  4      w  w  rTp\        P
                  pTP                  '       d#   TP                   '       d   \        P                  pTf   \        RP                  T4      4      hT P                  P                  T\        T4      T4      #   \         d    \        RP                  T4      4      Rhi ; i)zGenerate DBus property defined by class member.

:param member: a property object
:param member_name: a property name
:return: a property element

raises DBusSpecificationError: if the property is invalid
Nz%Undefined type of DBus property '{}'.z%DBus property '{}' is not accessible.)Zfsetr]   r   ZACCESS_WRITEZfgetZACCESS_READZ
ValueErrorr   r    ZACCESS_READWRITErB   Zcreate_propertyr   )r3   rK   rU   Zaccessr`   Z_s   &&&   r   rQ   Z-DBusSpecificationGenerator._generate_propertyH  s    		{{{&)&=&=fkk&J#"!*77 {{{&)&=&=fkk&J#"!*66 ;;;6;;;&77F>(7>>{K    00)$
 	
  	(7>>{K	s   D AD 0D 'D)c                sj    \         P                  ! V4      ;'       g    \         P                  ! V4      # )a  Is the class member a DBus method?

Ignore the difference between instance method and class method.

For example:

.. code-block:: python

    class Foo(object):
        def bar(cls, x):
            pass

    inspect.isfunction(Foo.bar) # True
    inspect.isfunction(Foo().bar) # False

    inspect.ismethod(Foo.bar) # False
    inspect.ismethod(Foo().bar) # True

    _is_method(Foo.bar) # True
    _is_method(Foo().bar) # True

)rJ   ZismethodZ
isfunctionr\   rX   r   rR   Z%DBusSpecificationGenerator._is_methodt  s(    0 'EE7+=+=f+EEr   c                s    V P                   P                  V4      pV P                  V4       FG  w  rEpV P                   P                  V\	        V4      V4      pV P                   P                  W74       KI  	  V# )zGenerate method defined by given class member.

:param member: a method object
:param member_name: a name of the method
:return: a method element
)rB   Zcreate_methodr]   r_   r   rT   )r3   rK   rU   r   r   r`   ra   rb   s   &&&     r   rS   Z+DBusSpecificationGenerator._generate_method  sv     ""00= +.*A*A&*I&DY))::mI.	I '': +J r   c                s(   V P                   P                  4       pV P                   P                  VRP                  VP                  4      4       \        VP                  4       4       F%  pV P                   P                  W2V,          4       K'  	  V# )zGenerate node element that specifies the given class.

:param interface_cls: a class object
:param interfaces: a dictionary of interfaces
:return: a node element
zSpecifies {})rB   Zcreate_nodeZadd_commentr    r!   ZsortedZkeysrT   )r3   rC   rD   rF   r5   rY   r   rA   Z)DBusSpecificationGenerator._generate_node  s|       ,,. 	%%.''(>(>?	

 %Z__%67N''.HI 8 r   r8   r/   )r!   r'   r(   r)   r*   r
   rB   reZcompilerW   Zclassmethodr1   r>   r=   r@   rL   rM   rN   rO   r]   re   rf   rP   rQ   rR   rS   rA   r+   r,   r-   r.   r   r0   r0   /  sh    6 !M ::23L6 68 
@ 
@  2 ' 'R = =  ( / / ! !F B B 4 4< %) %)N , , )
 )
V F F2  (  r   r0   )r;   r9   r   r<   r   r   )r8   ) rJ   rh   r    Ztypingr   Zdasbus.namespacer   Zdasbus.signalr   Zdasbus.specificationr   r   Zdasbus.typingr   r   r   r	   Z
dasbus.xmlr
   Z__all__r2   r   r   r   r   r   Zobjectr   r9   r;   r<   r0   r8   r   r   <module>ri      s   0  	  ! *   J
 
 # $  1 %
 4 'D FJO7& O7d$N8$G Gr   