U
    `»{j«3  ã                   @  sÈ  d 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	 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 er¬ddlm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 edƒZeddœdd„ƒZeddœdddœdd„ƒZed d!d!dd"œd#d„ƒZd3d$d!d!d%d"œd&d„Zed4ddœd'dd(d)œd*d+„ƒZed'd d!d!dd,œd-d+„ƒZe fddœd'd!dd!d.d/œd0d+„ZG d1d„ dej!ƒZ"eG d2d(„ d(e"ƒƒZ#dS )5z/Record warnings during test function execution.é    )Úannotations©ÚpformatN)ÚTracebackType)ÚAny)ÚCallable)Úfinal)Ú	Generator)ÚIterator)Úoverload)ÚPattern)ÚTYPE_CHECKING)ÚTypeVar)ÚSelf)Úcheck_ispytest)Úfixture)ÚExit)ÚfailÚTzGenerator[WarningsRecorder]©Úreturnc               	   c  s.   t dd�} | � t d¡ | V  W 5 Q R X dS )z¥Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions.

    See :ref:`warnings` for information on warning categories.
    T©Ú	_ispytestÚdefaultN)ÚWarningsRecorderÚwarningsÚsimplefilter)Zwrec© r   úN/var/www/html/bwave/python/venv/lib/python3.8/site-packages/_pytest/recwarn.pyÚrecwarn"   s    

r   .©Úmatchústr | Pattern[str] | Noner   )r!   r   c                 C  s   d S ©Nr   r    r   r   r   Údeprecated_call.   s    r$   zCallable[..., T]r   )ÚfuncÚargsÚkwargsr   c                 O  s   d S r#   r   )r%   r&   r'   r   r   r   r$   2   s    zCallable[..., Any] | NonezWarningsRecorder | Anyc                 O  s,   d}| dk	r| f|˜}t tttff|ž|ŽS )a¥  Assert that code produces a ``DeprecationWarning`` or ``PendingDeprecationWarning`` or ``FutureWarning``.

    This function can be used as a context manager::

        >>> import warnings
        >>> def api_call_v2():
        ...     warnings.warn('use v3 of this api', DeprecationWarning)
        ...     return 200

        >>> import pytest
        >>> with pytest.deprecated_call():
        ...    assert api_call_v2() == 200

    It can also be used by passing a function and ``*args`` and ``**kwargs``,
    in which case it will ensure calling ``func(*args, **kwargs)`` produces one of
    the warnings types above. The return value is the return value of the function.

    In the context manager form you may use the keyword argument ``match`` to assert
    that the warning matches a text or regex.

    The context manager produces a list of :class:`warnings.WarningMessage` objects,
    one for each warning raised.
    TN)ÚwarnsÚDeprecationWarningÚPendingDeprecationWarningÚFutureWarning)r%   r&   r'   Ú__tracebackhide__r   r   r   r$   6   s    
ÿÿÿú)type[Warning] | tuple[type[Warning], ...]ÚWarningsChecker)Úexpected_warningr!   r   c                C  s   d S r#   r   )r/   r!   r   r   r   r(   X   s    r(   )r/   r%   r&   r'   r   c                 O  s   d S r#   r   )r/   r%   r&   r'   r   r   r   r(   `   s    zWarningsChecker | Any)r/   r&   r!   r'   r   c             
   O  s–   d}|s8|r*d  t|ƒ¡}td|› d�ƒ‚t| |dd�S |d }t|ƒs`t|›dt|ƒ› d�ƒ‚t| dd	��  ||d
d… |ŽW  5 Q R £ S Q R X dS )a  Assert that code raises a particular class of warning.

    Specifically, the parameter ``expected_warning`` can be a warning class or tuple
    of warning classes, and the code inside the ``with`` block must issue at least one
    warning of that class or classes.

    This helper produces a list of :class:`warnings.WarningMessage` objects, one for
    each warning emitted (regardless of whether it is an ``expected_warning`` or not).
    Since pytest 8.0, unmatched warnings are also re-emitted when the context closes.

    This function can be used as a context manager::

        >>> import pytest
        >>> with pytest.warns(RuntimeWarning):
        ...    warnings.warn("my warning", RuntimeWarning)

    In the context manager form you may use the keyword argument ``match`` to assert
    that the warning matches a text or regex::

        >>> with pytest.warns(UserWarning, match='must be 0 or None'):
        ...     warnings.warn("value must be 0 or None", UserWarning)

        >>> with pytest.warns(UserWarning, match=r'must be \d+$'):
        ...     warnings.warn("value must be 42", UserWarning)

        >>> with pytest.warns(UserWarning):  # catch re-emitted warning
        ...     with pytest.warns(UserWarning, match=r'must be \d+$'):
        ...         warnings.warn("this is not here", UserWarning)
        Traceback (most recent call last):
          ...
        Failed: DID NOT WARN. No warnings of type ...UserWarning... were emitted...

    **Using with** ``pytest.mark.parametrize``

    When using :ref:`pytest.mark.parametrize ref` it is possible to parametrize tests
    such that some runs raise a warning and others do not.

    This could be achieved in the same way as with exceptions, see
    :ref:`parametrizing_conditional_raising` for an example.

    Tz, z5Unexpected keyword arguments passed to pytest.warns: z"
Use context-manager form instead?)Ú
match_exprr   r   z object (type: z) must be callabler   é   N)ÚjoinÚsortedÚ	TypeErrorr.   ÚcallableÚtype)r/   r!   r&   r'   r,   Úargnamesr%   r   r   r   r(   i   s    /
ÿc                      s¸   e Zd ZdZddœdddœ‡ fdd„Zed	d
œdd„ƒZdddœdd„Zdd
œdd„Zdd
œdd„Z	e
fdddœdd„Zdd
œdd„Zdd
œ‡ fdd„Zd d!d"dd#œ‡ fd$d%„Z‡  ZS )&r   aF  A context manager to record raised warnings.

    Each recorded warning is an instance of :class:`warnings.WarningMessage`.

    Adapted from `warnings.catch_warnings`.

    .. note::
        ``DeprecationWarning`` and ``PendingDeprecationWarning`` are treated
        differently; see :ref:`ensuring_function_triggers`.

    Fr   ÚboolÚNone)r   r   c                  s&   t |ƒ tƒ jdd� d| _g | _d S )NT)ÚrecordF)r   ÚsuperÚ__init__Ú_enteredÚ_list)Úselfr   ©Ú	__class__r   r   r<   ¶   s    zWarningsRecorder.__init__zlist[warnings.WarningMessage]r   c                 C  s   | j S )zThe list of recorded warnings.©r>   ©r?   r   r   r   Úlist¼   s    zWarningsRecorder.listÚintúwarnings.WarningMessage)Úir   c                 C  s
   | j | S )z Get a recorded warning by index.rB   )r?   rG   r   r   r   Ú__getitem__Á   s    zWarningsRecorder.__getitem__z!Iterator[warnings.WarningMessage]c                 C  s
   t | jƒS )z&Iterate through the recorded warnings.)Úiterr>   rC   r   r   r   Ú__iter__Å   s    zWarningsRecorder.__iter__c                 C  s
   t | jƒS )z The number of recorded warnings.)Úlenr>   rC   r   r   r   Ú__len__É   s    zWarningsRecorder.__len__ztype[Warning])Úclsr   c                 C  sˆ   d}t | jƒD ]N\}}|j|kr0| j |¡  S t|j|ƒr|dksXt|j| j| jƒs|}q|dk	rr| j |¡S d}t|›d�ƒ‚dS )zÁPop the first recorded warning which is an instance of ``cls``,
        but not an instance of a child class of any other match.
        Raises ``AssertionError`` if there is no match.
        NTz not found in warning list)Ú	enumerater>   ÚcategoryÚpopÚ
issubclassÚAssertionError)r?   rM   Zbest_idxrG   Úwr,   r   r   r   rP   Í   s    
ÿþzWarningsRecorder.popc                 C  s   g | j dd…< dS )z$Clear the list of recorded warnings.NrB   rC   r   r   r   Úclearà   s    zWarningsRecorder.clearr   c                   sD   | j rd}td| ›d�ƒ‚tƒ  ¡ }|d k	s0t‚|| _t d¡ | S )NTzCannot enter z twiceÚalways)r=   ÚRuntimeErrorr;   Ú	__enter__rR   r>   r   r   )r?   r,   r>   r@   r   r   rW   ä   s    

zWarningsRecorder.__enter__útype[BaseException] | NoneúBaseException | NoneúTracebackType | None©Úexc_typeÚexc_valÚexc_tbr   c                   s4   | j sd}td| ›d�ƒ‚tƒ  |||¡ d| _ d S )NTzCannot exit z without entering firstF)r=   rV   r;   Ú__exit__)r?   r\   r]   r^   r,   r@   r   r   r_   ï   s
    zWarningsRecorder.__exit__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r<   ÚpropertyrD   rH   rJ   rL   ÚWarningrP   rT   rW   r_   Ú__classcell__r   r   r@   r   r   ©   s   c                      s\   e Zd Zedfddœdddddœ‡ fd	d
„Zdddœdd„Zdddddœ‡ fdd„Z‡  ZS )r.   NFr   r-   r"   r8   r9   )r/   r0   r   r   c                  sŠ   t |ƒ tƒ jdd� d}t|tƒrN|D ]}t|tƒs(t|t|ƒ ƒ‚q(|}n,t|tƒrjt|tƒrj|f}nt|t|ƒ ƒ‚|| _	|| _
d S )NTr   z/exceptions must be derived from Warning, not %s)r   r;   r<   Ú
isinstanceÚtuplerQ   re   r4   r6   r/   r0   )r?   r/   r0   r   ÚmsgÚexcZexpected_warning_tupr@   r   r   r<     s     

 ÿzWarningsChecker.__init__rF   )Úwarningr   c                 C  s>   | j d k	st‚t|j| j ƒo<t| jd kp:t | jt|j	ƒ¡ƒS r#   )
r/   rR   rQ   rO   r8   r0   ÚreÚsearchÚstrÚmessage)r?   rk   r   r   r   Úmatches  s    ÿzWarningsChecker.matchesrX   rY   rZ   r[   c                   sP  t ƒ  |||¡ d}|d k	r4t|tƒr0t|tƒr4d S ddœ‡ fdd„}znt‡ fdd„ˆ D ƒƒsztdˆ j› d|ƒ › d�ƒ n8t‡ fdd„ˆ D ƒƒs²tdˆ j› dˆ j› d|ƒ › d�ƒ W 5 ˆ D ]0}ˆ  |¡sºtj|j|j	|j
|j|j|jd� qºˆ D ]X}t|jƒtk	�rqð|jj�sqð|jjd }t|tƒ�r,qðtd|›d	t|ƒj› d
�ƒ‚qðX d S )NTrn   r   c                     s   t dd„ ˆ D ƒdd�S )Nc                 S  s   g | ]
}|j ‘qS r   )ro   )Ú.0r:   r   r   r   Ú
<listcomp>8  s     z?WarningsChecker.__exit__.<locals>.found_str.<locals>.<listcomp>é   )Úindentr   r   rC   r   r   Ú	found_str7  s    z+WarningsChecker.__exit__.<locals>.found_str)ro   rO   ÚfilenameÚlinenoÚmoduleÚsourcer   z$Warning must be str or Warning, got z (type ú)c                 3  s   | ]}t |jˆ jƒV  qd S r#   )rQ   rO   r/   ©rq   rS   rC   r   r   Ú	<genexpr>;  s     z+WarningsChecker.__exit__.<locals>.<genexpr>z"DID NOT WARN. No warnings of type z" were emitted.
 Emitted warnings: Ú.c                 3  s   | ]}ˆ   |¡V  qd S r#   )rp   r{   rC   r   r   r|   @  s     z* matching the regex were emitted.
 Regex: z
 Emitted warnings: )r;   r_   rg   Ú	Exceptionr   rp   r   Úwarn_explicitro   rO   rv   rw   ra   ry   r6   ÚUserWarningr&   rn   r4   r`   Úanyr   r/   r0   )r?   r\   r]   r^   r,   ru   rS   ri   r@   rC   r   r_   "  sN    ÿýÿÿ
ú
ÿzWarningsChecker.__exit__)r`   ra   rb   re   r<   rp   r_   rf   r   r   r@   r   r.      s   ýû)N).)$rc   Ú
__future__r   Úpprintr   rl   Útypesr   Útypingr   r   r   r	   r
   r   r   r   r   Útyping_extensionsr   r   Z_pytest.deprecatedr   Z_pytest.fixturesr   Z_pytest.outcomesr   r   r   r   r$   r(   re   Úcatch_warningsr   r.   r   r   r   r   Ú<module>   sV    ÿ" ÿý	ÿý@W