a
    !f*                  	   @   s  d 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m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e
d dddZeddeeeee f  dddd Z ee	def eeed!d"d Z d.ee	def  eeedef d!d#d Z ed/ddeee! eee! df f eeeee f  d$d%d&d'Z"eeee! eee! df f e	def eeed(d)d'Z"e!fddeee! eee! df f eeeeee f  eed$ef d*d+d'Z"G d,d dej#Z$eG d-d$ d$e$Z%dS )0z/Record warnings during test function execution.    Npformat)TracebackType)Any)Callable)	Generator)Iterator)List)Optional)Pattern)Tuple)Type)TypeVar)Union)final)overload)check_ispytest)WARNS_NONE_ARG)fixture)failT)WarningsRecorderNNreturnc                  c   sB   t dd} |   td | V  W d   n1 s40    Y  dS )zReturn a :class:`WarningsRecorder` instance that records all warnings emitted by test functions.

    See https://docs.pytest.org/en/latest/how-to/capture-warnings.html for information
    on warning categories.
    T	_ispytestdefaultN)r   warningssimplefilter)Zwrec r   P/var/www/html/python-backend/venv/lib/python3.9/site-packages/_pytest/recwarn.pyrecwarn   s    

r!   .matchr   )r#   r   c                 C   s   d S Nr   r"   r   r   r    deprecated_call*   s    r%   )funcargskwargsr   c                 O   s   d S r$   r   )r&   r'   r(   r   r   r    r%   1   s    c                 O   s0   d}| dur| f| }t ttfg|R i |S )a  Assert that code produces a ``DeprecationWarning`` or ``PendingDeprecationWarning``.

    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)r&   r'   r(   __tracebackhide__r   r   r    r%   8   s    
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)   a   s    )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 i |W  d   S 1 s0    Y  dS )a  Assert that code raises a particular class of warning.

    Specifically, the parameter ``expected_warning`` can be a warning class or sequence
    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 raised (regardless of whether it is an ``expected_warning`` or not).

    This function can be used as a context manager, which will capture all the raised
    warnings inside it::

        >>> 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, 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)   k   s    .
c                       s   e Zd ZdZddedd fddZeed d	d
dZe	ddddZ
ed d	ddZe	d	ddZefee ddddZdd	ddZd d	 fddZeee  ee ee 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   N)r   r   c                   s&   t | t jdd d| _g | _d S )NT)recordF)r   super__init___entered_list)selfr   	__class__r   r    r9      s    zWarningsRecorder.__init__zwarnings.WarningMessager   c                 C   s   | j S )zThe list of recorded warnings.r;   r<   r   r   r    list   s    zWarningsRecorder.list)ir   c                 C   s
   | j | S )z Get a recorded warning by index.r?   )r<   rB   r   r   r    __getitem__   s    zWarningsRecorder.__getitem__c                 C   s
   t | jS )z&Iterate through the recorded warnings.)iterr;   r@   r   r   r    __iter__   s    zWarningsRecorder.__iter__c                 C   s
   t | jS )z The number of recorded warnings.)lenr;   r@   r   r   r    __len__   s    zWarningsRecorder.__len__)clsr   c                 C   sF   t | jD ]$\}}t|j|r
| j|  S q
d}t|ddS )z>Pop the first recorded warning, raise exception if not exists.Tz not found in warning listN)	enumerater;   
issubclasscategorypopAssertionError)r<   rH   rB   wr,   r   r   r    rL      s
    zWarningsRecorder.popc                 C   s   g | j dd< dS )z$Clear the list of recorded warnings.Nr?   r@   r   r   r    clear   s    zWarningsRecorder.clearc                    sD   | j rd}td| dt  }|d us0J || _td | S )NTzCannot enter z twicealways)r:   RuntimeErrorr8   	__enter__r;   r   r   )r<   r,   r;   r=   r   r    rR      s    

zWarningsRecorder.__enter__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:   rQ   r8   __exit__)r<   rT   rU   rV   r,   r=   r   r    rW      s
    zWarningsRecorder.__exit__)__name__
__module____qualname____doc__boolr9   propertyr	   rA   intrC   r   rE   rG   Warningr   rL   rO   rR   r
   BaseExceptionr   rW   __classcell__r   r   r=   r    r      s   
c                       s   e Zd Zedfddeeee eee df f  eeee	e f  e
dd fddZeee  ee ee dd fd	d
Z  ZS )r-   NFr   .)r.   r/   r   r   c                   s   t | t jdd d}|d u r6tjtdd d }nVt|trj|D ]}t|t	sDt
|t| qD|}n"t|t	r||f}nt
|t| || _|| _d S )NTr   z/exceptions must be derived from Warning, not %s   )
stacklevel)r   r8   r9   r   warnr   
isinstancetuplerJ   r_   r3   r5   r.   r/   )r<   r.   r/   r   msgZexpected_warning_tupexcr=   r   r    r9      s     	


zWarningsChecker.__init__rS   c                    s   t  ||| d} fdd}|d u r|d u r|d u rֈ jd urt fdd D sxd}td j d|  d n^ jd urֈ D ].}t|j jrt	 j
t|jr qqtd j d	 j d
|   d S )NTc                      s   t dd  D ddS )Nc                 S   s   g | ]
}|j qS r   )message).0r7   r   r   r    
<listcomp>#      z?WarningsChecker.__exit__.<locals>.found_str.<locals>.<listcomp>   )indentr   r   r@   r   r    	found_str"  s    z+WarningsChecker.__exit__.<locals>.found_strc                 3   s   | ]}t |j jV  qd S r$   )rJ   rK   r.   )rj   rr@   r   r    	<genexpr>(  rl   z+WarningsChecker.__exit__.<locals>.<genexpr>z"DID NOT WARN. No warnings of type z0 were emitted.
The list of emitted warnings is: .z* matching the regex were emitted.
 Regex: z
 Emitted warnings: )r8   rW   r.   anyr   r/   rJ   rK   recompilesearchstrri   )r<   rT   rU   rV   r,   ro   rp   r=   r@   r    rW     s4    


zWarningsChecker.__exit__)rX   rY   rZ   r_   r
   r   r   r   rw   r   r\   r9   r`   r   rW   ra   r   r   r=   r    r-      s"   
)N).)&r[   rt   r   pprintr   typesr   typingr   r   r   r   r	   r
   r   r   r   r   r   Z_pytest.compatr   r   Z_pytest.deprecatedr   r   Z_pytest.fixturesr   Z_pytest.outcomesr   r   r!   rw   r%   r_   r)   catch_warningsr   r-   r   r   r   r    <module>   s    
  


?O