3
(hk                 @   sz   d dl Z d dlZd dlZd dlmZ d dlZd dlmZ yejdj	Z
W n ejk
rb   dZ
Y nX d
ddZdd	 ZdS )    N)
ModuleType)filterzpython-monkey-businessTc                s  |dkrHt ttfr }dn(t ttfrHtdd D rH}ddkrbtjt| dS dkrpj	t |ttfrtdd |D r fdd|D S t |ttfst
dyt|}W nD tk
r   tdd	d
jtdt|dd|j	j	gi Y nX  r,t|ddkr,dS ytj|W n tk
rT   |Y nX tjfdd}||_|_tjrtj|rt|dr|jrt|}nt|}t|| t|S )a
  
    Decorator for monkeypatching functions on modules and classes.

    Example::

        # This replaces FooClass.bar with our method
        @monkeybiz.patch(FooClass)
        def bar(original_bar, *args, **kwargs):
            print "Patched!"
            return original_bar(*args, **kwargs)

        # This replaces FooClass.bar and foomodule.bar with our method
        @monkeybiz.patch([FooClass, foomodule])
        def bar(original_bar, *args, **kwargs):
            #...

    The first argument to ``monkeybiz.patch`` can be either a module, a class,
    or a list of modules and/or classes. The decorator also takes optional
    ``name`` and ``avoid_doublewrap`` keyword arguments. If ``name`` is
    omitted, the name of the function being patched will be the name of the
    function being decorated. If ``avoid_doublewrap`` is True (the default),
    then functions and methods can only be patched once using this function.

    Use ``monkeybiz.unpatch()`` to revert a monkey-patched function to its
    original.
    Nc             S   s   g | ]}t |ttfqS  )
isinstancer   type).0ir   r   F/tmp/pip-install-q3hcpn_q/python-monkey-business/monkeybiz/__init__.py
<listcomp>/   s    zpatch.<locals>.<listcomp>)objnameavoid_doublewrapc             S   s   g | ]}t |ttfqS r   )r   r   r   )r   r   r   r   r	   r
   9   s    c                s   g | ]}t | d qS ))funcr   r   r   )patch)r   o)r   r   r   r   r	   r
   :   s    z_Argument passed to @patch decorator must be a class or module, or a list of classes and modulesz%(func_repr)s does not existZ	func_repr.
__module__wrapperc                 s    f| |S )Nr   )argskwargs)r   original_callabler   r	   r   W   s    zpatch.<locals>.wrapperim_self)r   r   r   listtupleall	functoolspartialr   __name__
ValueErrorgetattrAttributeError	TypeErrorjoinr   sixget_method_functionwrapsoriginalr   PY2inspectisclasshasattrr   classmethodstaticmethodsetattr)r   r   r   r   callr   r   )r   r   r   r   r	   r      sR      


r   c             C   s   t | |t| |j dS )z4
    Undo the effects of patch(func, obj, name)
    N)r-   r   r&   )r   r   r   r   r	   unpatchl   s    r/   )NNNT)r   r(   pkg_resourcestypesr   r#   Z	six.movesr   get_distributionversion__version__DistributionNotFoundr   r/   r   r   r   r	   <module>   s   

\