a
    ߙfb                     @   s   d Z ddlZddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	 Zd
gZdgZdd ZG dd dZG dd dZG dd
 d
ZG dd dZG dd dZdd ZdS )z
Utility functions and classes
    N)StringIO)urlopen   )SAMP_STATUS_ERROR)SAMPProxyErrorc                  C   sB   ddl m}  | jsdS ztddd W dS  ty<   Y dS 0 d S )Nr   confFzhttp://google.comg      ?)ZtimeoutT) r   Zuse_internetr   	Exceptionr    r   1lib/python3.9/site-packages/astropy/samp/utils.pyinternet_on   s    r   SAMPMsgReplierWrapper.c                 C   s6   d|v r(| dd\}}tt| ||S t| |S dS )z%
    Get attributes recursively.
    r   r   N)splitgetattr_recursivegetattr)ZvariableZ	attributetopZ	remainingr   r   r   r   #   s    r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )_ServerProxyPoolMethodc                 C   s   || _ || _d S N)_ServerProxyPoolMethod__proxies_ServerProxyPoolMethod__name)selfZproxiesnamer   r   r   __init__3   s    z_ServerProxyPoolMethod.__init__c                 C   s   t | j| j d| S Nr   )r   r   r   r   r   r   r   r   __getattr__7   s    z"_ServerProxyPoolMethod.__getattr__c              
   O   s   | j  }t|| j}zXz||i |}W n4 tjy^ } zt|j|jW Y d }~n
d }~0 0 W | j 	| n| j 	| 0 |S r   )
r   getr   r   xmlrpcZFaultr   Z	faultCodeZfaultStringput)r   argsZkwrdsproxyZfunctionZresponseexcr   r   r   __call__:   s    
&z_ServerProxyPoolMethod.__call__N__name__
__module____qualname__r   r   r$   r   r   r   r   r   .   s   r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ServerProxyPoolz=
    A thread-safe pool of `xmlrpc.ServerProxy` objects.
    c                 O   s4   t || _t|D ]}| j||i | qd S r   )queueZQueue_proxiesranger    )r   sizeZproxy_classr!   keywordsir   r   r   r   K   s    zServerProxyPool.__init__c                 C   s   t | j|S r   )r   r+   r   r   r   r   r   Q   s    zServerProxyPool.__getattr__c                 C   s6   z| j  }W n tjy&   Y q2Y n0 |d q dS )z;Shut down the proxy pool by closing all active connections.closeN)r+   Z
get_nowaitr*   ZEmpty)r   r"   r   r   r   shutdownU   s
    
zServerProxyPool.shutdownN)r&   r'   r(   __doc__r   r   r1   r   r   r   r   r)   F   s   r)   c                   @   s    e Zd ZdZdd Zdd ZdS )r   a  
    Function decorator that allows to automatically grab errors and returned
    maps (if any) from a function bound to a SAMP call (or notify).

    Parameters
    ----------
    cli : :class:`~astropy.samp.SAMPIntegratedClient` or :class:`~astropy.samp.SAMPClient`
        SAMP client instance. Decorator initialization, accepting the instance
        of the client that receives the call or notification.
    c                 C   s
   || _ d S r   )cli)r   r3   r   r   r   r   n   s    zSAMPMsgReplierWrapper.__init__c                    s    fdd}|S )Nc               
      s   t  dks| d d u r" |   nz2 |  }|rRjjj | d t|d W nR ty   t }tj	|d |
 }jjj | d td|id Y n0 d S )N      )zsamp.statuszsamp.result)filetxt)get_num_argsr3   ZhubZreplyZget_private_keyr   r
   r   	traceback	print_excgetvalue)r!   resulterrr7   fr   r   r   	wrapped_fs   s&    
z1SAMPMsgReplierWrapper.__call__.<locals>.wrapped_fr   )r   r?   r@   r   r>   r   r$   q   s    zSAMPMsgReplierWrapper.__call__N)r&   r'   r(   r2   r   r$   r   r   r   r   r   b   s   c                   @   s   e Zd Zdd Zdd ZdS )_HubAsClientc                 C   s
   || _ d S r   )_handler)r   Zhandlerr   r   r   r      s    z_HubAsClient.__init__c                 C   s   t | j|S r   )_HubAsClientMethodrB   r   r   r   r   r      s    z_HubAsClient.__getattr__N)r&   r'   r(   r   r   r   r   r   r   rA      s   rA   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )rC   c                 C   s   || _ || _d S r   _HubAsClientMethod__send_HubAsClientMethod__name)r   sendr   r   r   r   r      s    z_HubAsClientMethod.__init__c                 C   s   t | j| j d| S r   )rC   rE   rF   r   r   r   r   r      s    z_HubAsClientMethod.__getattr__c                 G   s   |  | j|S r   rD   )r   r!   r   r   r   r$      s    z_HubAsClientMethod.__call__Nr%   r   r   r   r   rC      s   rC   c                 C   s6   t | r| jjjd S t | r*| jjS tddS )zW
    Find the number of arguments a function or method takes (excluding ``self``).
    r   z"f should be a function or a methodN)inspectZismethod__func____code__co_argcountZ
isfunction	TypeError)r?   r   r   r   r8      s
    

r8   )r2   r*   rH   r9   ior   Zxmlrpc.clientZclientr   Zurllib.requestr   Z	constantsr   errorsr   r   __all__Z__doctest_skip__r   r   r)   r   rA   rC   r8   r   r   r   r   <module>   s$   *
