B
    pjÆ`½  ã               @   sª   d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddl	m
Z
 ej ej ej¡¡ZG dd„ de	jƒZG dd	„ d	ƒZeZd
d„ Zdd„ Zdd„ ZdS )zh
gateway code for initiating popen, socket and ssh connections.
(c) 2004-2013, Holger Krekel and others
é    Né   )Úgateway_base)ÚMessagec                   sr   e Zd ZdZ‡ fdd„Zedd„ ƒZdd„ Zdd	„ Zddd„Z	ddd„Z
dd„ Zdd„ Zdd„ Zddd„Z‡  ZS )ÚGatewayz/Gateway to a local or remote Python Intepreter.c                s*   t t| ƒj||jdd || _|  ¡  d S )Nr   )ÚioÚidZ_startcount)Úsuperr   Ú__init__r   ÚspecZ_initreceive)Úselfr   r
   )Ú	__class__© ú.lib/python3.7/site-packages/execnet/gateway.pyr	      s    zGateway.__init__c             C   s   | j jS )N)Ú_ioÚremoteaddress)r   r   r   r   r      s    zGateway.remoteaddressc             C   s\   y"|   ¡ rdpd}t| j ¡ ƒ}W n tk
r>   d}d}Y nX d | jj| j|| j	j
|¡S )z3return string representing gateway type and status.zreceive-liveznot-receivingZuninitializedÚnoz-<{} id={!r} {}, {} model, {} active channels>)ÚhasreceiverÚlenÚ_channelfactoryZchannelsÚAttributeErrorÚformatr   Ú__name__r   Z	execmodelZbackend)r   ÚrÚir   r   r   Ú__repr__!   s    
zGateway.__repr__c          
   C   s    |   d¡ | | jkr"|   d¡ dS | j | ¡ y.|   d¡ |  tj¡ |   d¡ | j ¡  W n> tt	t
fk
rš   t ¡ d }|   d¡ |   d| ¡ Y nX dS )	z›trigger gateway exit.  Defer waiting for finishing
        of receiver-thread and subprocess activity to when
        group.terminate() is called.
        zgateway.exit() calledz'gateway already unregistered with groupNz--> sending GATEWAY_TERMINATEz--> io.close_writer   z-io-error: could not send termination sequencez exception: %r)Z_traceÚ_groupZ_unregisterÚ_sendr   ZGATEWAY_TERMINATEr   Zclose_writeÚ
ValueErrorÚEOFErrorÚIOErrorÚsysÚexc_info)r   Úvr   r   r   Úexit-   s    





zGateway.exitTFc             C   s*   ||f| _ t | j ¡}| jtj|d dS )z­
        set the string coercion for this gateway
        the default is to try to convert py2 str as py3 str,
        but not to try and convert py3 str to py2 str
        )ÚdataN)Z
_strconfigr   Údumps_internalr   r   ZRECONFIGURE)r   Zpy2str_as_py3strZpy3str_as_py2strr$   r   r   r   ÚreconfigureA   s    
zGateway.reconfigurec             C   s<   |st | dƒs6|  t¡}zt| ¡ ƒ| _W d| ¡  X | jS )z,return some sys/env information from remote.Ú_cache_rinfoN)ÚhasattrÚremote_execÚrinfo_sourceÚRInfoÚreceiver'   Z	waitclose)r   ÚupdateZchr   r   r   Ú_rinfoK   s    

zGateway._rinfoc             C   s   | j  ¡ dkS )z/return True if gateway is able to receive data.r   )Z_receivepoolZactive_count)r   r   r   r   r   U   s    zGateway.hasreceiverc             C   s6   |   ¡ }|  tj|j¡ | ¡ }| j |j¡ t|ƒS )z8return information object about remote execution status.)	Ú
newchannelr   r   ZSTATUSr   r,   r   Z_local_closeÚRemoteStatus)r   ÚchannelZ
statusdictr   r   r   Úremote_statusY   s
    zGateway.remote_statusc          
   K   s¤   d}d}t |tjƒr4t |¡}t |¡ t |¡}n4t |tjƒrZ|j	}t |¡}t
|ƒ}nt t|ƒ¡}|sx|rxtdƒ‚|  ¡ }|  tj|jt ||||f¡¡ |S )a®  return channel object and connect it to a remote
        execution thread where the given ``source`` executes.

        * ``source`` is a string: execute source string remotely
          with a ``channel`` put into the global namespace.
        * ``source`` is a pure function: serialize source and
          call function with ``**kwargs``, adding a
          ``channel`` object to the keyword arguments.
        * ``source`` is a pure module: execute source of module
          with a ``channel`` in its global namespace

        In all cases the binding ``__name__='__channelexec__'``
        will be available in the global namespace of the remotely
        executing code.
        Nz-can't pass kwargs to non-function remote_exec)Ú
isinstanceÚtypesÚ
ModuleTypeÚinspectZgetsourcefileÚ	linecacheÚupdatecacheÚ	getsourceÚFunctionTyper   Ú_source_of_functionÚtextwrapÚdedentÚstrÚ	TypeErrorr/   r   r   ZCHANNEL_EXECr   r   r%   )r   ÚsourceÚkwargsZ	call_nameÚ	file_namer1   r   r   r   r)   c   s&    



zGateway.remote_execNc             C   s   t dƒ dS )z1DEPRECATED.  Is currently a NO-OPERATION already.z?WARNING: remote_init_threads() is a no-operation in execnet-1.2N)Úprint)r   Znumr   r   r   Úremote_init_threads‹   s    zGateway.remote_init_threads)TF)F)N)r   Ú
__module__Ú__qualname__Ú__doc__r	   Úpropertyr   r   r#   r&   r.   r   r2   r)   rD   Ú__classcell__r   r   )r   r   r      s   




(r   c               @   s   e Zd Zdd„ Zdd„ ZdS )r+   c             C   s   | j  |¡ d S )N)Ú__dict__r-   )r   rA   r   r   r   r	   ‘   s    zRInfo.__init__c             C   s&   d  dd„ t| j ¡ ƒD ƒ¡}d| S )Nz, c             s   s   | ]}d | V  qdS )z%s=%sNr   )Ú.0Úitemr   r   r   ú	<genexpr>•   s    z!RInfo.__repr__.<locals>.<genexpr>z
<RInfo %r>)ÚjoinÚsortedrJ   Úitems)r   Úinfor   r   r   r   ”   s    zRInfo.__repr__N)r   rE   rF   r	   r   r   r   r   r   r+      s   r+   c          	   C   sB   dd l }dd l}|  t|j|jd d… |j| ¡ | ¡ d¡ d S )Nr   é   )Ú
executableÚversion_infoÚplatformÚcwdÚpid)	r    ÚosÚsendÚdictrS   rT   rU   ÚgetcwdÚgetpid)r1   r    rX   r   r   r   r*   œ   s    r*   c                s`   dd l ‰ydd l‰ W n tk
r0   dd l‰ Y nX t |j¡‰‡ ‡‡fdd„ˆ ˆ | ¡¡D ƒS )Nr   c                s4   g | ],}t |ˆjƒr|jˆkr|jˆ jkr|j‘qS r   )r3   ÚNamer   rJ   )rK   Znode)Ú__builtin__ÚastÚvarsr   r   ú
<listcomp>µ   s   
z-_find_non_builtin_globals.<locals>.<listcomp>)	r_   r^   ÚImportErrorÚbuiltinsrZ   ÚfromkeysÚco_varnamesÚwalkÚparse)r@   Úcodeobjr   )r^   r_   r`   r   Ú_find_non_builtin_globals«   s    ri   c             C   sú   | j dkrtdƒ‚yt | ¡}W n" tk
rB   t | ¡d }Y nX |j}|rZ|d dkrbtdƒ‚tjrv| j	}| j
}n| j}| j}|d k	r’tdƒ‚yt | ¡}W n  tk
rÀ   td|  ƒ‚Y nX t |¡}t||ƒ}|rätd|ƒ‚d	|jd
  }|| S )Nz<lambda>z can't evaluate lambda functions'r   r1   z0expected first function argument to be `channel`z'functions with closures can't be passedzcan't find source file for %sz.the use of non-builtin globals isn't supportedÚ
r   )r   r   r6   Zgetfullargspecr   Z
getargspecÚargsr   ZISPY3Ú__closure__Ú__code__Zfunc_closureZ	func_coder9   r   r<   r=   ri   Úco_firstlineno)ZfunctionZsigrk   Zclosurerh   r@   Zused_globalsZ
leading_wsr   r   r   r;   ½   s4    



r;   )rG   r6   r7   rX   r    r<   r4   ZexecnetÚ r   r   ÚpathÚdirnameÚ__file__Z	importdirZBaseGatewayr   r+   r0   r*   ri   r;   r   r   r   r   Ú<module>   s    {	