B
    >cU                 @   s  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
 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	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lmZ d dlmZ d dlZddlmZ ddlmZ edZejdd dkr&ejjZne	ZG dd de Z!G dd dZ"e	ee"ddf dddZ#e$ e#Z%ej$dde#Z&ej$dde#Z'ej$d de#Z(ej$d!de#Z)g Z*i Z+e
d"e	f e	e	dd#d$d%Z,e	e	dd&d'd(Z-e	e	dd&d)d*Z.e	e	dd&d+d,Z/e	e	dd&d-d.Z0e	e	dd&d/d0Z1e	e	dd&d1d2Z2e	e	dd&d3d4Z3e	e	dd&d5d6Z4e	e	dd&d7d8Z5e	e	dd&d9d:Z6e	e	dd&d;d<Z7e	e	dd&d=d>Z8e	e	dd&d?d@Z9e	e	dd&dAdBZ:e	ddCdDdEZ;ddFdGdHZ<e	ddIdJdKZ=e	ddCdLdMZ>dS )N    N)Any)Callable)cast)Dict)	Generator)Iterable)List)Mapping)Optional)overload)Tuple)Type)TypeVar)Union   )get_mock_module)parse_ini_boolean_T   )      c               @   s   e Zd ZdZdS )PytestMockWarningz3Base class for all warnings emitted by pytest-mock.N)__name__
__module____qualname____doc__ r   r   1lib/python3.7/site-packages/pytest_mock/plugin.pyr   $   s   r   c               @   s   e Zd ZdZeddddZdddeeddd	d
ZddddZe	j
jddddZeee	j
jdddZdee e	j
jdddZdee edddZG dd dZdS )MockerFixturez
    Fixture that provides the same interface to functions in the mock module,
    ensuring that they are uninstalled at the end of each test.
    N)configreturnc             C   s   g | _ t| | _}| | j || _|j| _|j| _|j| _|j| _|j	| _	t
|dr^|j| _|j| _|j| _|j| _|j| _|j| _|j| _t
|dr|j| _d S )N	AsyncMockseal)_patches_and_mocksr   mock_module_PatcherpatchMock	MagicMockNonCallableMockZNonCallableMagicMockZPropertyMockhasattrr!   ZcallANYDEFAULTZcreate_autospecsentinelZ	mock_openr"   )selfr   r$   r   r   r   __init__.   s&    

zMockerFixture.__init__F)return_valueside_effect)r0   r1   r    c            C   sf   t | dr| j| jf}n| jf}x@| jD ]6\}}t |ds<q(t||rV|j||d q(|  q(W dS )z
        Call reset_mock() on all patchers started by this fixture.

        :param bool return_value: Reset the return_value of mocks.
        :param bool side_effect: Reset the side_effect of mocks.
        r!   
reset_mock)r0   r1   N)r*   r'   r!   r#   
isinstancer2   )r.   r0   r1   Zsupports_reset_mock_with_argspmr   r   r   resetallE   s    



zMockerFixture.resetall)r    c             C   s.   xt | jD ]\}}|  qW | j  dS )zi
        Stop all patchers started by this fixture. Can be safely called multiple
        times.
        N)reversedr#   stopclear)r.   r4   r5   r   r   r   stopall]   s    zMockerFixture.stopall)mockr    c             C   sB   x<t | jD ]&\}\}}||kr|  | j|= P qW tddS )zp
        Stops a previous patch or spy call by passing the ``MagicMock`` object
        returned by it.
        z"This mock object is not registeredN)	enumerater#   r8   
ValueError)r.   r;   indexr4   r5   r   r   r   r8   f   s    zMockerFixture.stop)objnamer    c                s   t || t|r0tt||ttfr0d}nt pBt } fdd} fdd}t	
 rxt| }nt| }| jj||||dd_d_S )a  
        Create a spy of method. It will run method normally, but it is now
        possible to use `mock` call features with it, like call count.

        :param obj: An object.
        :param name: A method in object.
        :return: Spy object.
        Fc           
      sP   d _ d _y | |}W n* tk
rD } z|_ W d d }~X Y nX |_ |S )N)
spy_returnspy_exceptionBaseException)argskwargsre)methodspy_objr   r   wrapper   s    z"MockerFixture.spy.<locals>.wrapperc           
      sV   d _ d _y | |I d H }W n* tk
rJ } z|_ W d d }~X Y nX |_ |S )N)rA   rB   rC   )rD   rE   rF   rG   )rH   rI   r   r   async_wrapper   s    z(MockerFixture.spy.<locals>.async_wrapper)r1   autospecN)getattrinspectZisclassr3   Zgetattr_staticclassmethodstaticmethodZismethodZ
isfunctionasyncioZiscoroutinefunction	functoolsupdate_wrapperr&   objectrA   rB   )r.   r?   r@   rL   rJ   rK   wrappedr   )rH   rI   r   spys   s    	

zMockerFixture.spy)r@   r    c             C   s   t tjj| jjdd |dS )z
        Create a stub method. It accepts any arguments. Ideal to register to
        callbacks in tests.

        :param name: the constructed stub's name as used in repr
        :return: Stub object.
        c              _   s   d S )Nr   )rD   rE   r   r   r   <lambda>       z$MockerFixture.stub.<locals>.<lambda>)specr@   )r   unittestr;   r(   r$   )r.   r@   r   r   r   stub   s    zMockerFixture.stubc             C   s   t t| jjdd |dS )z
        Create a async stub method. It accepts any arguments. Ideal to register to
        callbacks in tests.

        :param name: the constructed stub's name as used in repr
        :return: Stub object.
        c              _   s   d S )Nr   )rD   rE   r   r   r   rW      rX   z*MockerFixture.async_stub.<locals>.<lambda>)rY   r@   )r   AsyncMockTyper$   r!   )r.   r@   r   r   r   
async_stub   s    zMockerFixture.async_stubc               @   s~  e Zd ZdZe Zdd Zeeeee	j
jdddZedddddfeeeee eee ee eee	j
jd	
d
dZedddddfejeejeej eeej eej ejee	j
jd	
ddZdejeej eeej eej eej eeee	j
jf dddZdeeeef ef eeeef eeeef  f eeedddZededeej eeej eej dee	j
jd	ddZed eeeej eeej eej deed	ddZeedeej eeej eej eg ef eed	ddZed!edeej eeej eej eg ef eed	ddZedddddfeejeej eeej eej eeg ef  eed	ddZdS )"zMockerFixture._Patcherz
        Object to provide the same interface as mock.patch, mock.patch.object,
        etc. We need this indirection to keep the same API of the mock package.
        c             C   s   || _ || _d S )N)_Patcher__patches_and_mocksr$   )r.   Zpatches_and_mocksr$   r   r   r   r/      s    zMockerFixture._Patcher.__init__)	mock_funcwarn_on_mock_enterrD   rE   r    c                sb   |||}|  }| j||f t|dr^t|dr^|r^tjdkrJd nd  fdd|j_|S )zPatches something by calling the given function from the mock
            module, registering the patch to stop it later and returns the
            mock object resulting from the mock call.
            r2   	__enter__)r            c                  s   t jdt dS )Na0  Mocks returned by pytest-mock do not need to be used as context managers. The mocker fixture automatically undoes mocking at the end of a test. This warning can be ignored if it was triggered by mocking a context manager. https://pytest-mock.readthedocs.io/en/latest/remarks.html#usage-as-context-manager)
stacklevel)warningswarnr   r   )depthr   r   rW      s   z5MockerFixture._Patcher._start_patch.<locals>.<lambda>)startr^   appendr*   sysversion_infora   r1   )r.   r_   r`   rD   rE   r4   Zmockedr   )rh   r   _start_patch   s    


z#MockerFixture._Patcher._start_patchNF)
target	attributenewrY   createspec_setrL   new_callablerE   r    c	       
   	   K   s>   || j kr| jj }| j| jjjd||f||||||d|	S )zAPI to mock.patch.objectT)rp   rY   rq   rr   rL   rs   )r,   r$   rm   r&   rT   )
r.   rn   ro   rp   rY   rq   rr   rL   rs   rE   r   r   r   rT      s    
zMockerFixture._Patcher.objectc	       
   	   K   s>   || j kr| jj }| j| jjjd||f||||||d|	S )zThis is equivalent to mock.patch.object except that the returned mock
            does not issue a warning when used as a context manager.F)rp   rY   rq   rr   rL   rs   )r,   r$   rm   r&   rT   )
r.   rn   ro   rp   rY   rq   rr   rL   rs   rE   r   r   r   context_manager  s    
z&MockerFixture._Patcher.context_manager)rn   rY   rq   rr   rL   rs   rE   r    c             K   s(   | j | jjjd|f|||||d|S )zAPI to mock.patch.multipleT)rY   rq   rr   rL   rs   )rm   r$   r&   multiple)r.   rn   rY   rq   rr   rL   rs   rE   r   r   r   ru   %  s    zMockerFixture._Patcher.multipler   )in_dictvaluesr9   rE   r    c             K   s"   | j | jjjd|f||d|S )zAPI to mock.patch.dictT)rw   r9   )rm   r$   r&   dict)r.   rv   rw   r9   rE   r   r   r   rx   <  s    zMockerFixture._Patcher.dict.)	rn   rp   rY   rq   rr   rL   rs   rE   r    c       	      K   s   d S )Nr   )	r.   rn   rp   rY   rq   rr   rL   rs   rE   r   r   r   __call__M  s    zMockerFixture._Patcher.__call__c       	      K   s   d S )Nr   )	r.   rn   rp   rY   rq   rr   rL   rs   rE   r   r   r   ry   [  s    c       	      K   s   d S )Nr   )	r.   rn   rp   rY   rq   rr   rL   rs   rE   r   r   r   ry   i  s    c      	      K   s   d S )Nr   )	r.   rn   rp   rY   rq   rr   rL   rs   rE   r   r   r   ry   w  s    c       	   	   K   s:   || j kr| jj }| j| jjd|f||||||d|S )zAPI to mock.patchT)rp   rY   rq   rr   rL   rs   )r,   r$   rm   r&   )	r.   rn   rp   rY   rq   rr   rL   rs   rE   r   r   r   ry     s    
)NFNNN)r   F)......).....).....)r   r   r   r   rT   r,   r/   r   boolrZ   r;   r(   rm   strr
   builtinsrt   r   ru   r   r	   r   r   rx   r   ry   r   r   r   r   r   r   r%      s    ,    ( 4     "    "
     
2r%   )N)N)r   r   r   r   r   r/   rz   r6   r:   rZ   r;   r(   r8   rT   r{   rV   r
   r[   r\   r]   r%   r   r   r   r   r   (   s   	5r   )pytestconfigr    c             c   s   t | }|V  |  dS )z
    Return an object that has the same interface to the `mock` module, but
    takes care of automatically undoing all patches after each test method.
    N)r   r:   )r}   resultr   r   r   _mocker  s    r   class)ZscopemodulepackageZsession.)__wrapped_mock_method__rD   rE   r    c             O   s0  d}y| || d S  t k
r* } zt|ddr<t|}n|d }t|}|jd k	r|j\}}d}	y||dd  ks|t W n2 t k
r }
 z|	dt|
 7 }	W d d }
~
X Y nX y||kst W n2 t k
r } z|	dt| 7 }	W d d }~X Y nX |	r|d|	 7 }t |}d|_|W d d }~X Y nX d S )	NT_mock_introspection_appliedr    r   z
Args:
z	
Kwargs:
z 

pytest introspection follows:
)AssertionErrorrM   r{   	call_argsr   )r   rD   rE   __tracebackhide__rG   msgZ__mock_selfZactual_argsZactual_kwargsZintrospectionZe_argsZe_kwargsr   r   r   assert_wrapper  s2    


""r   )rD   rE   r    c              O   s   d}t td f| | d S )NTassert_not_called)r   _mock_module_originals)rD   rE   r   r   r   r   wrap_assert_not_called  s    r   c              O   s   d}t td f| | d S )NTassert_called_with)r   r   )rD   rE   r   r   r   r   wrap_assert_called_with  s    r   c              O   s   d}t td f| | d S )NTassert_called_once)r   r   )rD   rE   r   r   r   r   wrap_assert_called_once  s    r   c              O   s   d}t td f| | d S )NTassert_called_once_with)r   r   )rD   rE   r   r   r   r   wrap_assert_called_once_with  s    r   c              O   s   d}t td f| | d S )NTassert_has_calls)r   r   )rD   rE   r   r   r   r   wrap_assert_has_calls  s    r   c              O   s   d}t td f| | d S )NTassert_any_call)r   r   )rD   rE   r   r   r   r   wrap_assert_any_call  s    r   c              O   s   d}t td f| | d S )NTassert_called)r   r   )rD   rE   r   r   r   r   wrap_assert_called  s    r   c              O   s   d}t td f| | d S )NTassert_not_awaited)r   r   )rD   rE   r   r   r   r   wrap_assert_not_awaited  s    r   c              O   s   d}t td f| | d S )NTassert_awaited_with)r   r   )rD   rE   r   r   r   r   wrap_assert_awaited_with  s    r   c              O   s   d}t td f| | d S )NTassert_awaited_once)r   r   )rD   rE   r   r   r   r   wrap_assert_awaited_once  s    r   c              O   s   d}t td f| | d S )NTassert_awaited_once_with)r   r   )rD   rE   r   r   r   r   wrap_assert_awaited_once_with  s    r   c              O   s   d}t td f| | d S )NTassert_has_awaits)r   r   )rD   rE   r   r   r   r   wrap_assert_has_awaits  s    r   c              O   s   d}t td f| | d S )NTassert_any_await)r   r   )rD   rE   r   r   r   r   wrap_assert_any_await  s    r   c              O   s   d}t td f| | d S )NTassert_awaited)r   r   )rD   rE   r   r   r   r   wrap_assert_awaited  s    r   )r   r    c          	   C   s&  t rdS t| }tttttttd}xh|	 D ]\\}}yt
|j|}W n tk
r\   w.Y nX |t |< |j|j||}|  t| q.W t|drtttttttd}xh|	 D ]\\}}yt
|j|}W n tk
r   wY nX |t |< |j|j||}|  t| qW | t dS )z
    Wrap assert methods of mock module so we can hide their traceback and
    add introspection information to specified argument asserts.
    N)r   r   r   r   r   r   r   r!   )r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   itemsrM   r)   AttributeErrorr&   rT   ri   _mock_module_patchesrj   r*   r   r   r   r   r   r   r   r!   Zadd_cleanupunwrap_assert_methods)r   r$   ZwrappersrH   rJ   ZoriginalpatcherZasync_wrappersr   r   r   wrap_assert_methods  sJ    r   )r    c              C   sf   xLt D ]D} y|   W q tk
rH } zt|dkr6n W d d }~X Y qX qW g t d d < t  d S )Nz stop called on unstarted patcher)r   r8   RuntimeErrorr{   r   r9   )r   rG   r   r   r   r   Q  s    
r   )parserr    c             C   s$   | j dddd | j dddd d S )Nmock_traceback_monkeypatchzRMonkeypatch the mock library to improve reporting of the assert_called_... methodsT)defaultZmock_use_standalone_modulezPUse standalone "mock" (from PyPI) instead of builtin "unittest.mock" on Python 3F)Zaddini)r   r   r   r   pytest_addoptionb  s    r   c             C   s0   | j ddd}t| dr,|dkr,t|  d S )Nz--tbauto)r   r   Znative)Z	getoptionr   Zgetinir   )r   tbr   r   r   pytest_configureq  s    r   )?rQ   r|   rR   rN   rk   Zunittest.mockrZ   rf   typingr   r   r   r   r   r   r   r	   r
   r   r   r   r   r   ZpytestZ_utilr   r   r   rl   r;   r!   r\   UserWarningr   r   r   ZfixtureZmockerZclass_mockerZmodule_mockerZpackage_mockerZsession_mockerr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sv   
  |
5