o
    hd+                     @   s   d Z ddlZddlZddlZddlmZmZ ddlmZ dd Z	dd Z
d	d
 Zdd ZG dd dZ		dddZdd Zdd ZddddZdS )zUseful utility decorators.     N)wrapsupdate_wrappersympy_deprecation_warningc                    sD   ddl m ddlm  ddlm t fdd}|S )z'A factory for ``threaded`` decorators. r   )sympify)
MatrixBase)iterablec                    s   t | r|  fddS | r/z|  fdd| D W S  ty.   |  Y S w | } rG| jrG| j fdd| jD  S | jrd| | jg R i | jg R i S | g R i S )Nc                    s   | g R i S N )fargsfunckwargsr
   M/var/www/vscode/kcb/lib/python3.10/site-packages/sympy/utilities/decorator.py<lambda>   s    z9threaded_factory.<locals>.threaded_func.<locals>.<lambda>c                    "   g | ]}|g R i qS r
   r
   .0r   r   r
   r   
<listcomp>      " z;threaded_factory.<locals>.threaded_func.<locals>.<listcomp>c                    r   r
   r
   r   r   r
   r   r      r   )	
isinstance	applyfunc	__class__	TypeErroris_Addr   is_Relationallhsrhs)exprr   r   r   r   r   r   use_addr   r   r   threaded_func   s    

z'threaded_factory.<locals>.threaded_func)
sympy.corer   sympy.matricesr   sympy.utilities.iterablesr   r   )r   r!   r#   r
   r    r   threaded_factory
   s   r'   c                 C   
   t | dS )aU  Apply ``func`` to sub--elements of an object, including :class:`~.Add`.

    This decorator is intended to make it uniformly possible to apply a
    function to all elements of composite objects, e.g. matrices, lists, tuples
    and other iterable containers, or just expressions.

    This version of :func:`threaded` decorator allows threading over
    elements of :class:`~.Add` class. If this behavior is not desirable
    use :func:`xthreaded` decorator.

    Functions using this decorator must have the following signature::

      @threaded
      def function(expr, *args, **kwargs):

    Tr'   r   r
   r
   r   threaded'      
r+   c                 C   r(   )aX  Apply ``func`` to sub--elements of an object, excluding :class:`~.Add`.

    This decorator is intended to make it uniformly possible to apply a
    function to all elements of composite objects, e.g. matrices, lists, tuples
    and other iterable containers, or just expressions.

    This version of :func:`threaded` decorator disallows threading over
    elements of :class:`~.Add` class. If this behavior is not desirable
    use :func:`threaded` decorator.

    Functions using this decorator must have the following signature::

      @xthreaded
      def function(expr, *args, **kwargs):

    Fr)   r*   r
   r
   r   	xthreaded;   r,   r-   c                    s$   ddl  fdd}t| }|S )zwAfter the function finishes, resets the value of ``mpmath.mp.dps`` to
    the value it had before the function was run.r   Nc                     s,   j j}z | i |W |j _S |j _w r	   )mpdps)r   r   r/   r   mpmathr
   r   func_wrapperT   s   z)conserve_mpmath_dps.<locals>.func_wrapper)r1   r   )r   r2   r
   r0   r   conserve_mpmath_dpsO   s   
r3   c                   @   s"   e Zd ZdZdd ZdddZdS )no_attrs_in_subclassaE  Don't 'inherit' certain attributes from a base class

    >>> from sympy.utilities.decorator import no_attrs_in_subclass

    >>> class A(object):
    ...     x = 'test'

    >>> A.x = no_attrs_in_subclass(A, A.x)

    >>> class B(A):
    ...     pass

    >>> hasattr(A, 'x')
    True
    >>> hasattr(B, 'x')
    False

    c                 C   s   || _ || _d S r	   )clsr   )selfr5   r   r
   r
   r   __init__r   s   
zno_attrs_in_subclass.__init__Nc                 C   s.   || j krt| jdr| j||S | jS t)N__get__)r5   hasattrr   r8   AttributeError)r6   instanceownerr
   r
   r   r8   v   s
   
zno_attrs_in_subclass.__get__r	   )__name__
__module____qualname____doc__r7   r8   r
   r
   r
   r   r4   _   s    r4   c                    sr   i  | dur
|  d< |dur| d< |dur| d< |dur"| d< |dur*| d<  fdd fd	d
}|S )a  
    Adds metadata about the dependencies which need to be met for doctesting
    the docstrings of the decorated objects.

    ``exe`` should be a list of executables

    ``modules`` should be a list of modules

    ``disable_viewers`` should be a list of viewers for :func:`~sympy.printing.preview.preview` to disable

    ``python_version`` should be the minimum Python version required, as a tuple
    (like ``(3, 0)``)
    Nexecutablesmodulesdisable_viewerspython_versionground_typesc                     sP   ddl m} m}m} | }||d }z|jdi   W dS  | y'   Y dS w )Nr   )DependencyErrorSymPyDocTestsPyTestReporterTFr
   )sympy.testing.runtestsrF   rG   rH   _check_dependencies)rF   rG   rH   rt)dependenciesr
   r   	skiptests   s   
z%doctest_depends_on.<locals>.skiptestsc                    s6    | _ | _t| rt| | j | _t| | j| _| S r	   )_doctest_depends_on__doctest_skip__inspectisclassr4   _doctest_depdends_on)fnrM   rN   r
   r   depends_on_deco   s   
z+doctest_depends_on.<locals>.depends_on_decor
   )exerB   rC   rD   rE   rV   r
   rU   r   doctest_depends_on~   s   rX   c                 C   sv   t | tjr| j}| j}nt | tttfr!tj| j j	}| j}nt
d|  d|vr2|g|d< | S |d | | S )a  
    Append ``obj``'s name to global ``__all__`` variable (call site).

    By using this decorator on functions or classes you achieve the same goal
    as by filling ``__all__`` variables manually, you just do not have to repeat
    yourself (object's name). You also know if object is public at definition
    site, not at some random location (where ``__all__`` was set).

    Note that in multiple decorator setup (in almost all cases) ``@public``
    decorator must be applied before any other decorators, because it relies
    on the pointer to object's global namespace. If you apply other decorators
    first, ``@public`` may end up modifying the wrong namespace.

    Examples
    ========

    >>> from sympy.utilities.decorator import public

    >>> __all__ # noqa: F821
    Traceback (most recent call last):
    ...
    NameError: name '__all__' is not defined

    >>> @public
    ... def some_function():
    ...     pass

    >>> __all__ # noqa: F821
    ['some_function']

    z&expected a function or a class, got %s__all__)r   typesFunctionType__globals__r=   typesysrB   r>   __dict__r   append)objnsnamer
   r
   r   public   s    
rd   c                    s0   dj   t t fdd}t|S )zProperty decorator that caches the value of potentially expensive
    ``propfunc`` after the first evaluation. The cached value is stored in
    the corresponding property name with an attached underscore._c                    s,   t |  }|u r| }t|  | |S r	   )getattrsetattr)r6   valattrnamepropfuncsentinelr
   r   accessor   s
   z"memoize_property.<locals>.accessor)r=   objectr   property)rk   rm   r
   ri   r   memoize_property   s
   
rp      )
stacklevelc                   s   ||d  fdd}|S )a  
    Mark a function as deprecated.

    This decorator should be used if an entire function or class is
    deprecated. If only a certain functionality is deprecated, you should use
    :func:`~.warns_deprecated_sympy` directly. This decorator is just a
    convenience. There is no functional difference between using this
    decorator and calling ``warns_deprecated_sympy()`` at the top of the
    function.

    The decorator takes the same arguments as
    :func:`~.warns_deprecated_sympy`. See its
    documentation for details on what the keywords to this decorator do.

    See the :ref:`deprecation-policy` document for details on when and how
    things should be deprecated in SymPy.

    Examples
    ========

    >>> from sympy.utilities.decorator import deprecated
    >>> from sympy import simplify
    >>> @deprecated("""    ... The simplify_this(expr) function is deprecated. Use simplify(expr)
    ... instead.""", deprecated_since_version="1.1",
    ... active_deprecations_target='simplify-this-deprecation')
    ... def simplify_this(expr):
    ...     """
    ...     Simplify ``expr``.
    ...
    ...     .. deprecated:: 1.1
    ...
    ...        The ``simplify_this`` function is deprecated. Use :func:`simplify`
    ...        instead. See its documentation for more information. See
    ...        :ref:`simplify-this-deprecation` for details.
    ...
    ...     """
    ...     return simplify(expr)
    >>> from sympy.abc import x
    >>> simplify_this(x*(x + 1) - x**2) # doctest: +SKIP
    <stdin>:1: SymPyDeprecationWarning:
    <BLANKLINE>
    The simplify_this(expr) function is deprecated. Use simplify(expr)
    instead.
    <BLANKLINE>
    See https://docs.sympy.org/latest/explanation/active-deprecations.html#simplify-this-deprecation
    for details.
    <BLANKLINE>
    This has been deprecated since SymPy version 1.1. It
    will be removed in a future version of SymPy.
    <BLANKLINE>
      simplify_this(x)
    x

    See Also
    ========
    sympy.utilities.exceptions.SymPyDeprecationWarning
    sympy.utilities.exceptions.sympy_deprecation_warning
    sympy.utilities.exceptions.ignore_warnings
    sympy.testing.pytest.warns_deprecated_sympy

    )deprecated_since_versionactive_deprecations_targetc                    sT   t  drG  fddd } j|_|S t  fdd} |_|S )N__mro__c                       sV   e Zd ZjZjZZdjv r fddZ  ZS  fddZ  ZS )9deprecated.<locals>.deprecated_decorator.<locals>.wrapper__new__c                    s2   t fi di t j| g|R i |S Nrr   )r   superrw   )r5   r   r   r   decorator_kwargsmessagerr   r
   r   rw   >  s   zAdeprecated.<locals>.deprecated_decorator.<locals>.wrapper.__new__c                    s.   t fi di t j|i | d S rx   )r   ry   r7   )r6   r   r   rz   r
   r   r7   B  s   zBdeprecated.<locals>.deprecated_decorator.<locals>.wrapper.__init__)	r=   r>   r?   r@   _sympy_deprecated_funcr_   rw   r7   __classcell__r
   r{   r|   rr   wrapped)r   r   wrapper9  s    
r   c                     s&   t fi  di | i |S rx   r   r"   r   r
   r   r   G  s   rv   )r9   r=   r   r}   )r   r   r{   r|   rr   )r   r   deprecated_decorator7  s   
z(deprecated.<locals>.deprecated_decoratorr
   )r|   rs   rt   rr   r   r
   r   r   
deprecated   s
   @r   )NNNNN)r@   r^   rZ   rQ   	functoolsr   r   sympy.utilities.exceptionsr   r'   r+   r-   r3   r4   rX   rd   rp   r   r
   r
   r
   r   <module>   s$    
41