o
    8Va%                     @   s  d 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 eddZ	zddl
Z
eeddZW n ey9   dZY nw er\e
jZe
jZe
jZe
jjZe
jjZe
jjZe
jjZddlmZ nQG dd	 d	Zd*d
dZG dd dZG dd deZG dd deZG dd deZG dd deZdd Zdd Zdd Zdd Zdd Zejd d!d"d#Zd$d% Z ejd&d' Z!ejd(d) Z"dS )+z$py.test hacks to support XFAIL/XPASS    N)SymPyDeprecationWarningZTRAVIS_BUILD_NUMBERZ_running_pytestF)Failedc                   @   s   e Zd Zdd Zdd ZdS )ExceptionInfoc                 C   
   || _ d S N)value)selfr    r	   6/usr/lib/python3/dist-packages/sympy/testing/pytest.py__init__$      
zExceptionInfo.__init__c                 C   s   d | jS )Nz<ExceptionInfo {!r}>)formatr   r   r	   r	   r
   __repr__'   s   zExceptionInfo.__repr__N)__name__
__module____qualname__r   r   r	   r	   r	   r
   r   #   s    r   c              
   C   sp   |du rt | S t|r+z|  W td | y* } z
t|W  Y d}~S d}~ww t|tr4tdtd)a  
        Tests that ``code`` raises the exception ``expectedException``.

        ``code`` may be a callable, such as a lambda expression or function
        name.

        If ``code`` is not given or None, ``raises`` will return a context
        manager for use in ``with`` statements; the code to execute then
        comes from the scope of the ``with``.

        ``raises()`` does nothing if the callable raises the expected exception,
        otherwise it raises an AssertionError.

        Examples
        ========

        >>> from sympy.testing.pytest import raises

        >>> raises(ZeroDivisionError, lambda: 1/0)
        <ExceptionInfo ZeroDivisionError(...)>
        >>> raises(ZeroDivisionError, lambda: 1/2)
        Traceback (most recent call last):
        ...
        Failed: DID NOT RAISE

        >>> with raises(ZeroDivisionError):
        ...     n = 1/0
        >>> with raises(ZeroDivisionError):
        ...     n = 1/2
        Traceback (most recent call last):
        ...
        Failed: DID NOT RAISE

        Note that you cannot test multiple statements via
        ``with raises``:

        >>> with raises(ZeroDivisionError):
        ...     n = 1/0    # will execute and raise, aborting the ``with``
        ...     n = 9999/0 # never executed

        This is just what ``with`` is supposed to do: abort the
        contained statement sequence at the first exception and let
        the context manager deal with the exception.

        To test multiple statements, you'll need a separate ``with``
        for each:

        >>> with raises(ZeroDivisionError):
        ...     n = 1/0    # will execute and raise
        >>> with raises(ZeroDivisionError):
        ...     n = 9999/0 # will also execute and raise

        NDID NOT RAISEz'raises(xxx, "code")' has been phased out; change 'raises(xxx, "expression")' to 'raises(xxx, lambda: expression)', 'raises(xxx, "statement")' to 'with raises(xxx): statement'z1raises() expects a callable for the 2nd argument.)RaisesContextcallabler   r   
isinstancestr	TypeError)expectedExceptioncodeer	   r	   r
   raises+   s"   6
r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )r   c                 C   r   r   )r   )r   r   r	   r	   r
   r   u   r   zRaisesContext.__init__c                 C   s   d S r   r	   r   r	   r	   r
   	__enter__x   s   zRaisesContext.__enter__c                 C   s   |d u rt dt|| jS )Nr   )r   
issubclassr   )r   exc_type	exc_value	tracebackr	   r	   r
   __exit__{   s   zRaisesContext.__exit__N)r   r   r   r   r   r"   r	   r	   r	   r
   r   t   s    r   c                   @      e Zd ZdS )XFailNr   r   r   r	   r	   r	   r
   r$          r$   c                   @   r#   )XPassNr%   r	   r	   r	   r
   r'      r&   r'   c                   @   r#   )SkippedNr%   r	   r	   r	   r
   r(      r&   r(   c                   @   r#   )r   Nr%   r	   r	   r	   r
   r      r&   r   c                    s    fdd}t | }|S )Nc               
      sP   z   W n t y" }  zt| }|dkrt jtdd } ~ ww t j)NZTimeout)	Exceptionr   r$   r   r(   r'   )r   messagefuncr	   r
   wrapper   s   


zXFAIL.<locals>.wrapper	functoolsupdate_wrapper)r,   r-   r	   r+   r
   XFAIL   s   r1   c                 C   s   t | r   r(   )r   r	   r	   r
   skip      r3   c                    s    fdd}|S )z0Similar to ``skip()``, but this is a decorator. c                    s    fdd}t || }|S )Nc                      s   t  r   r2   r	   reasonr	   r
   func_wrapper   r4   z+SKIP.<locals>.wrapper.<locals>.func_wrapperr.   r,   r7   r5   r	   r
   r-      s   zSKIP.<locals>.wrapperr	   )r6   r-   r	   r5   r
   SKIP   s   r9   c                    s(   d _  fdd}t| } |_|S )NTc                      s
      d S r   r	   r	   r+   r	   r
   r7      r   zslow.<locals>.func_wrapper)Z_slowr/   r0   __wrapped__r8   r	   r+   r
   slow   s
   r;   c                 C   s   | S )zBDummy decorator for marking tests that fail when cache is disabledr	   r+   r	   r	   r
   nocache_fail   s   r<    )matchc                #   s    t jdd}t d t d|  dV  W d   n1 s!w   Y  t fdd|D s@d d	d
 |D f }t|dS )a  Like raises but tests that warnings are emitted.

        >>> from sympy.testing.pytest import warns
        >>> import warnings

        >>> with warns(UserWarning):
        ...     warnings.warn('deprecated', UserWarning)

        >>> with warns(UserWarning):
        ...     pass
        Traceback (most recent call last):
        ...
        Failed: DID NOT WARN. No warnings of type UserWarning        was emitted. The list of emitted warnings is: [].
        TrecordignorealwaysNc                 3   s    | ]	}t |j V  qd S r   )r   category.0w
warningclsr	   r
   	<genexpr>   s    zwarns.<locals>.<genexpr>z^Failed: DID NOT WARN. No warnings of type %s was emitted. The list of emitted warnings is: %s.c                 S   s   g | ]}|j qS r	   )r*   rD   r	   r	   r
   
<listcomp>   s    zwarns.<locals>.<listcomp>)warningscatch_warningssimplefilterfilterwarningsanyr   )rH   r>   warnrecmsgr	   rG   r
   warns   s   
rR   c                    s*   ddl m   fdd}t|}|S )a8  
    Decorator used to run the test twice: the first time `e^x` is represented
    as ``Pow(E, x)``, the second time as ``exp(x)`` (exponential object is not
    a power).

    This is a temporary trick helping to manage the elimination of the class
    ``exp`` in favor of a replacement by ``Pow(E, ...)``.
    r   )_exp_is_powc                      sb    d   W d    n1 sw   Y   d   W d    d S 1 s*w   Y  d S )NTFr	   r	   rS   r,   r	   r
   	func_wrap   s   

"z _both_exp_pow.<locals>.func_wrap)Zsympy.core.parametersrS   r/   r0   )r,   rU   r-   r	   rT   r
   _both_exp_pow   s   	rV   c                   c   s6    t t dV  W d   dS 1 sw   Y  dS )aS  Shorthand for ``warns(SymPyDeprecationWarning)``

    This is the recommended way to test that ``SymPyDeprecationWarning`` is
    emitted for deprecated features in SymPy. To test for other warnings use
    ``warns``. To suppress warnings without asserting that they are emitted
    use ``ignore_warnings``.

    >>> from sympy.testing.pytest import warns_deprecated_sympy
    >>> from sympy.utilities.exceptions import SymPyDeprecationWarning
    >>> with warns_deprecated_sympy():
    ...     SymPyDeprecationWarning("Don't use", feature="old thing",
    ...         deprecated_since_version="1.0", issue=123).warn()

    >>> with warns_deprecated_sympy():
    ...     pass
    Traceback (most recent call last):
    ...
    Failed: DID NOT WARN. No warnings of type     SymPyDeprecationWarning was emitted. The list of emitted warnings is: [].
    N)rR   r   r	   r	   r	   r
   warns_deprecated_sympy   s   
"rW   c                 c   sr    t jdd}t d|  dV  W d   n1 sw   Y  |D ]}t|j| s6t |j|j|j|j q"dS )ar  Context manager to suppress warnings during tests.

    This function is useful for suppressing warnings during tests. The warns
    function should be used to assert that a warning is raised. The
    ignore_warnings function is useful in situation when the warning is not
    guaranteed to be raised (e.g. on importing a module) or if the warning
    comes from third-party code.

    When the warning is coming (reliably) from SymPy the warns function should
    be preferred to ignore_warnings.

    >>> from sympy.testing.pytest import ignore_warnings
    >>> import warnings

    Here's a warning:

    >>> with warnings.catch_warnings():  # reset warnings in doctest
    ...     warnings.simplefilter('error')
    ...     warnings.warn('deprecated', UserWarning)
    Traceback (most recent call last):
      ...
    UserWarning: deprecated

    Let's suppress it with ignore_warnings:

    >>> with warnings.catch_warnings():  # reset warnings in doctest
    ...     warnings.simplefilter('error')
    ...     with ignore_warnings(UserWarning):
    ...         warnings.warn('deprecated', UserWarning)

    (No warning emitted)
    Tr?   rB   N)	rK   rL   rM   r   rC   warn_explicitr*   filenamelineno)rH   rP   rF   r	   r	   r
   ignore_warnings  s   #r[   r   )#__doc__sysr/   os
contextlibrK   Zsympy.utilities.exceptionsr   getenvZ	ON_TRAVISZpytestgetattrZ
USE_PYTESTImportErrorr   rR   r3   ZmarkZxfailr1   r9   r;   r<   Z_pytest.outcomesr   r   r   r)   r$   r'   r(   contextmanagerrV   rW   r[   r	   r	   r	   r
   <module>   sT    
I
!
