3
Z_ð]¬C  ã               @   s>  d dl Z d dlZd dlZd dlZddddgZed/ƒZG d	d
„ d
eƒZdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zi Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zg dfd+d,„Zed-k�r:ejjd ƒ eƒ  e ejd  ƒ�$Z!e"e!j#ƒ ejd  d.ƒZ$e%e$ƒ W dQ R X dS )0é    NÚinjectÚimport_patchedÚmonkey_patchÚis_monkey_patchedÚ__builtins__Ú__file__Ú__name__c               @   s,   e Zd ZdZf fdd„Zdd„ Zdd„ ZdS )	ÚSysModulesSaverz…Class that captures some subset of the current state of
    sys.modules.  Pass in an iterator of module names to the
    constructor.c             C   s   i | _ tjƒ  | j|Ž  d S )N)Ú_savedÚimpÚacquire_lockÚsave)ÚselfÚmodule_names© r   ú4/tmp/pip-build-yz_zf6az/eventlet/eventlet/patcher.pyÚ__init__   s    zSysModulesSaver.__init__c             G   s&   x |D ]}t jj|dƒ| j|< qW dS )z&Saves the named modules to the object.N)ÚsysÚmodulesÚgetr
   )r   r   Úmodnamer   r   r   r      s    
zSysModulesSaver.savec             C   sd   zTxNt j| jƒD ]>\}}|dk	r,|tj|< qytj|= W q tk
rL   Y qX qW W dtjƒ  X dS )zRRestores the modules that the saver knows about into
        sys.modules.
        N)ÚsixÚ	iteritemsr
   r   r   ÚKeyErrorr   Úrelease_lock)r   r   Úmodr   r   r   Úrestore   s    zSysModulesSaver.restoreN)r   Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r   r	      s   r	   c       	      G   s$  d|  }|t jkrt j| S |s>tƒ tƒ  tƒ  tƒ  tƒ  }tdd„ |D ƒƒ}|j| ƒ x|D ]\}}|t j|< q`W t jj	| dƒ x2t
t jjƒ ƒD ] }|j| d ƒr”t jj	|dƒ q”W z\t| i i | jdƒdd… ƒ}|dk	�rx&t|ƒD ]}|tkrêt||ƒ||< qêW |t j|< W d|jƒ  X |S )aÌ  Base method for "injecting" greened modules into an imported module.  It
    imports the module specified in *module_name*, arranging things so
    that the already-imported modules in *additional_modules* are used when
    *module_name* makes its imports.

    **Note:** This function does not create or change any sys.modules item, so
    if your greened module use code like 'sys.modules["your_module_name"]', you
    need to update sys.modules by yourself.

    *new_globals* is either None or a globals dictionary that gets populated
    with the contents of the *module_name* module.  This is useful when creating
    a "green" version of some other module.

    *additional_modules* should be a collection of two-element tuples, of the
    form (<name>, <module>).  If it's not specified, a default selection of
    name/module pairs is used, which should cover all use cases but may be
    slower because there are inevitably redundant or unnecessary imports.
    Z__patched_module_c             S   s   g | ]\}}|‘qS r   r   )Ú.0ÚnameÚmr   r   r   ú
<listcomp>R   s    zinject.<locals>.<listcomp>NÚ.é   éÿÿÿÿ)r   r   Ú_green_os_modulesÚ_green_select_modulesÚ_green_socket_modulesÚ_green_thread_modulesÚ_green_time_modulesr	   r   ÚpopÚlistÚkeysÚ
startswithÚ
__import__ÚsplitÚdirÚ	__excludeÚgetattrr   )	Úmodule_nameZnew_globalsÚadditional_modulesZpatched_nameÚsaverr!   r   Zimported_module_nameÚmoduler   r   r   r   -   s.    




c             O   s   t | df|t|jƒ ƒ žŽ S )zìImports a module in a way that ensures that the module uses "green"
    versions of the standard library modules, so that everything works
    nonblockingly.

    The only required argument is the name of the module to be imported.
    N)r   ÚtupleÚitems)r5   r6   Zkw_additional_modulesr   r   r   r   t   s    c                s4   ˆ s"t ƒ tƒ  tƒ  tƒ  tƒ  ‰ ‡ ‡fdd„}|S )a   Decorator that returns a version of the function that patches
    some modules for the duration of the function call.  This is
    deeply gross and should only be used for functions that import
    network libraries within their function bodies that there is no
    way of getting around.c           
      sF   t ƒ }x$ˆ D ]\}}|j|ƒ |tj|< qW z
ˆ| |ŽS |jƒ  X d S )N)r	   r   r   r   r   )ÚargsÚkwr7   r!   r   )r6   Úfuncr   r   Úpatched�   s    

zpatch_function.<locals>.patched)r'   r(   r)   r*   r+   )r=   r6   r>   r   )r6   r=   r   Úpatch_function�   s
    	r?   c                s   ‡ ‡fdd„}|S )au  Kind of the contrapositive of patch_function: decorates a
    function such that when it's called, sys.modules is populated only
    with the unpatched versions of the specified modules.  Unlike
    patch_function, only the names of the modules need be supplied,
    and there are no defaults.  This is a gross hack; tell your kids not
    to import inside function bodies!c           
      s>   t ˆƒ}xˆD ]}t|ƒtj|< qW z
ˆ | |ŽS |jƒ  X d S )N)r	   Úoriginalr   r   r   )r;   r<   r7   r!   )r=   r   r   r   r>   £   s    

z)_original_patch_function.<locals>.patchedr   )r=   r   r>   r   )r=   r   r   Ú_original_patch_functionœ   s    rA   c             C   sä   d|  }|t jkrt jj|ƒS t| fƒ}t jj| dƒ tjrFdddœ}tjrVdddœ}| |kr~||  }|j|ƒ t	|ƒt j|< zPt
| i i | jdƒdd… ƒ}| dkrÂt|dƒ rÂt|jjdƒ|j_|t j|< W d|jƒ  X t j| S )zd This returns an unpatched version of a module; this is useful for
    Eventlet itself (i.e. tpool).Z__original_module_NÚthreadÚ	threading)rC   ÚQueueÚ_thread)rC   Úqueuer$   r%   rD   rF   Ú
_threadingr&   )rD   rF   )r   r   r   r	   r,   r   ÚPY2ÚPY3r   r@   r0   r1   ÚhasattrrA   rD   r   r   )r   Úoriginal_namer7   ÚdepsÚ
dependencyZreal_modr   r   r   r@   ®   s,    






r@   c              K   s¦  t jjƒ  tdƒ}d
| ko d| k s(t‚y| jd
ƒ}W n tk
rJ   Y n
X || d< | jddƒ}x&tj| ƒD ]}||krlt	d| ƒ‚qlW |dkrœd| j
ƒ k}x@|D ]8}|dkrº| j|dƒ |dkrÎ| j|dƒ | j||ƒ q¢W | d � rütjdƒ � rütƒ  g }xldtfdtfdtfdtfdtfdtfdtfd	tfgD ]4\}}| | �r6tj|ƒ �r6||ƒ 7 }dt|< �q6W | d �r¾tjdƒ �r¾y ddlm}	 |	jƒ  dtd< W n tk
�r¼   Y nX tjƒ  zœx–|D ]Ž\}}
tjj|ƒ}|dk�rôt|ƒ}x2|
j D ](}t!|
|dƒ}|dk	�rüt"|||ƒ �qüW t!|
dg ƒ}x$|D ]}t#||ƒ�r:t$||ƒ �q:W �qÎW W dtj%ƒ  X tj&dk�r¢ddl'}t(dƒ}||j)_*ddl+}|j,|_-dS )a�  Globally patches certain system modules to be greenthread-friendly.

    The keyword arguments afford some control over which modules are patched.
    If no keyword arguments are supplied, all possible modules are patched.
    If keywords are set to True, only the specified modules are patched.  E.g.,
    ``monkey_patch(socket=True, select=True)`` patches only the select and
    socket modules.  Most arguments patch the single module of the same name
    (os, time, select).  The exceptions are socket, which also patches the ssl
    module if present; and thread, which patches thread, threading, and Queue.

    It's safe to call monkey_patch multiple times.
    ÚosÚselectÚsocketrB   ÚtimeÚpsycopgÚMySQLdbÚbuiltinsÚ
subprocessÚ__builtin__ÚallNz4monkey_patch() got an unexpected keyword argument %rTFr   )Úpsycopg2_patcherZ__deleted__é   rE   )	rN   rO   rP   rB   rQ   rR   rS   rT   rU   )rY   rY   ).ÚeventletZhubsZget_hubÚsetÚAssertionErrorr,   r   r   ÚiterkeysÚ	TypeErrorÚvaluesÚ
setdefaultÚalready_patchedr   Ú_green_existing_locksr'   r(   r)   r*   r+   Ú_green_MySQLdbÚ_green_builtinsÚ_green_subprocess_modulesZeventlet.supportrX   Zmake_psycopg_greenÚImportErrorr   r   r   r   r0   Z__patched__r4   ÚsetattrrJ   Údelattrr   Úversion_infoZimportlib._bootstrapr@   Ú
_bootstraprE   rC   Ú_PyRLockÚRLock)ÚonZaccepted_argsÚbZ
default_onÚkr   Zmodules_to_patchr!   Zmodules_functionrX   r   Zorig_modÚ	attr_nameZpatched_attrZdeletedÚ	importlibrB   rC   r   r   r   r   Û   s„    
 





c             C   s   | t kpt| ddƒt kS )a[  Returns True if the given module is monkeypatched currently, False if
    not.  *module* can be either the module itself or its name.

    Based entirely off the name of the module, so if you import a
    module some other way than with the import keyword (including
    import_patched), this might not be correct about that particular
    module.r   N)ra   r4   )r8   r   r   r   r   L  s    c              C   s¾   ddl } ddl}ddl}t|jƒ ƒ}t|jƒ ƒ}tjd dkrJt|jƒ ƒ}|j	j
jƒ }xb| jƒ D ]V}t||ƒr`tjd dkr”t|j|ƒr”t||ƒ q`tjd dkr`t||ƒ r`t|ƒ q`W dS )a  Make locks created before monkey-patching safe.

    RLocks rely on a Lock and on Python 2, if an unpatched Lock blocks, it
    blocks the native thread. We need to replace these with green Locks.

    This was originally noticed in the stdlib logging module.r   NrY   é   )ÚgcrC   Zeventlet.green.threadÚtypeÚLockrl   r   ri   rk   ÚgreenrB   Ú	get_identZget_objectsÚ
isinstanceÚ_RLock__blockÚ_fix_py2_rlockÚ_fix_py3_rlock)rs   rC   rZ   Z	lock_typeZ
rlock_typeZpyrlock_typeÚtidÚobjr   r   r   rb   X  s     
rb   c             C   s:   dd l }| j}|jjjƒ }|| _|jƒ r6|jƒ  || _d S )Nr   )Zeventlet.green.threadingry   rv   rC   ru   ÚlockedÚacquireZ_RLock__owner)Zrlockr|   rZ   ÚoldÚnewr   r   r   rz   s  s    rz   c             C   s²   dd l }dd l}|jƒ }x| jƒ r4| jƒ  |jƒ  qW | jƒ rF|jƒ  |jƒ  x^|j| ƒD ]P}yt|ƒ}W n t	k
r~   Y qZX x(|j
ƒ D ]\}}|| krŠt|||ƒ qŠW qZW d S )Nr   )rs   rC   rk   Ú	_is_ownedÚreleaser   ZcollectZget_referrersÚvarsr^   r:   rg   )r€   rs   rC   r�   ÚrefZref_varsro   Úvr   r   r   r{   }  s"    
r{   c              C   s   ddl m}  d| fgS )Nr   )rN   rN   )Úeventlet.greenrN   )rN   r   r   r   r'   ’  s    r'   c              C   s>   ddl m}  d| fg}tjdkr:ddl m} |jd|fƒ |S )	Nr   )rO   rO   rY   é   )Ú	selectorsr‰   )rY   rˆ   )r‡   rO   r   ri   r‰   Úappend)rO   r   r‰   r   r   r   r(   —  s    

r(   c              C   sH   ddl m}  yddl m} d| fd|fgS  tk
rB   d| fgS X d S )Nr   )rP   )ÚsslrP   r‹   )r‡   rP   r‹   rf   )rP   r‹   r   r   r   r)   ¢  s    r)   c              C   s   ddl m}  d| fgS )Nr   )rU   rU   )r‡   rU   )rU   r   r   r   re   «  s    re   c              C   s`   ddl m}  ddl m} ddl m} tjr@d| fd|fd|fgS tjr\d| fd	|fd|fgS d S )
Nr   )rD   )rB   )rC   rD   rB   rC   rF   rE   )r‡   rD   rB   rC   r   rH   rI   )rD   rB   rC   r   r   r   r*   °  s    r*   c              C   s   ddl m}  d| fgS )Nr   )rQ   rQ   )r‡   rQ   )rQ   r   r   r   r+   º  s    r+   c              C   s0   yddl m}  d| fgS  tk
r*   g S X d S )Nr   )rS   rS   )r‡   rS   rf   )rS   r   r   r   rc   ¿  s
    
rc   c              C   s:   y ddl m}  tjrdnd| fgS  tk
r4   g S X d S )Nr   )ÚbuiltinrV   rT   )r‡   rŒ   r   rH   rf   )rŒ   r   r   r   rd   Ç  s
    rd   c                s0   |dkrˆj }|jt‡ ‡fdd„|D ƒƒƒ dS )a   Copy properties from *source* (assumed to be a module) to
    *destination* (assumed to be a dict).

    *ignore* lists properties that should not be thusly copied.
    *srckeys* is a list of keys to copy, if the source's __all__ is
    untrustworthy.
    Nc                s,   g | ]$}|j d ƒp|ˆ ks|tˆ|ƒf‘qS )Ú__)r/   r4   )r    r!   )ÚignoreÚsourcer   r   r#   Ú  s   z$slurp_properties.<locals>.<listcomp>)Ú__all__ÚupdateÚdict)r�   ZdestinationrŽ   Zsrckeysr   )rŽ   r�   r   Úslurp_propertiesÏ  s
    r“   Ú__main__Úexec)r   r   r   )&r   r   rZ   r   r�   r[   r3   Úobjectr	   r   r   r?   rA   r@   ra   r   r   rb   rz   r{   r'   r(   r)   re   r*   r+   rc   rd   r“   r   Úargvr,   ÚopenÚfÚcompileÚreadÚcoder•   r   r   r   r   Ú<module>   s@    G*q
	

