o
    GZŽh°+  ã                   @   s¶   d Z ddlm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
 edƒZ	 dd„ Zd	d
„ Zdd„ Zdd„ ZG dd„ dƒZ		ddd„Zdedefdd„Zdd„ Zddœdd„ZdS )zUseful utility decorators. é    )ÚTypeVarN)ÚwrapsÚupdate_wrapper©Úsympy_deprecation_warningÚTc                    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   úH/var/www/auris/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   )	Ú
isinstanceZ	applyfuncÚ	__class__Ú	TypeErrorZis_Addr   Zis_RelationalÚlhsÚrhs)Úexprr   r   ©r	   r   r
   r   Úuse_add©r   r   r   Úthreaded_func   s    
ÿ
ÿz'threaded_factory.<locals>.threaded_func)Z
sympy.corer   Zsympy.matricesr	   Z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   Ú	xthreadedA   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_wrapperZ   s   z)conserve_mpmath_dps.<locals>.func_wrapper)r-   r   )r   r.   r   r,   r   Úconserve_mpmath_dpsU   s   
r/   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   )Úselfr1   r   r   r   r   Ú__init__x   s   
zno_attrs_in_subclass.__init__Nc                 C   s.   || j krt| jdƒr| j ||¡S | jS t‚)NÚ__get__)r1   Úhasattrr   r4   ÚAttributeError)r2   ÚinstanceÚownerr   r   r   r4   |   s
   
zno_attrs_in_subclass.__get__r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r3   r4   r   r   r   r   r0   e   s    r0   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)``)
    NZ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   )Zsympy.testing.runtestsrA   rB   rC   Z_check_dependencies)rA   rB   rC   ÚrÚt)Údependenciesr   r   Ú	skiptestsŸ   s   
ýÿz%doctest_depends_on.<locals>.skiptestsc                    s6   ˆ | _ ˆ| _t | ¡rt| | j ƒ| _t| | jƒ| _| S r   )Z_doctest_depends_onZ__doctest_skip__ÚinspectÚisclassr0   Z_doctest_depdends_on)Úfn©rF   rG   r   r   Údepends_on_decoª   s   
ÿÿz+doctest_depends_on.<locals>.depends_on_decor   )Úexer=   r>   r?   r@   rL   r   rK   r   Údoctest_depends_on„   s   rN   ÚobjÚreturnc                 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__r9   ÚtypeÚsysr=   r:   Ú__dict__r   Úappend)rO   ÚnsÚnamer   r   r   Úpublic¸   s    
þr[   c                    s0   dˆj  ‰ tƒ ‰tˆƒ‡ ‡‡fdd„ƒ}t|ƒS )zÍProperty 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)r2   Úval©ÚattrnameÚpropfuncÚsentinelr   r   Úaccessorð   s
   z"memoize_property.<locals>.accessor)r9   Úobjectr   Úproperty)rb   rd   r   r`   r   Úmemoize_propertyé   s
   
rg   é   )Ú
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 ©Nri   )r   Úsuperrn   )r1   r   r   ©r   Údecorator_kwargsÚmessageri   r   r   rn   D  s   zAdeprecated.<locals>.deprecated_decorator.<locals>.wrapper.__new__c                    s.   t ˆfi ˆ¤dˆi¤Ž tƒ j|i |¤Ž d S ro   )r   rp   r3   )r2   r   r   rq   r   r   r3   H  s   zBdeprecated.<locals>.deprecated_decorator.<locals>.wrapper.__init__)	r9   r:   r;   r<   Ú_sympy_deprecated_funcrW   rn   r3   Ú__classcell__r   ©rr   rs   ri   Úwrapped)r   r   Úwrapper?  s    
rx   c                     s&   t ˆfi ˆ ¤dˆi¤Ž ˆ| i |¤ŽS ro   r   r!   rv   r   r   rx   M  s   rm   )r5   r9   r   rt   )rw   rx   ©rr   rs   ri   )rw   r   Údeprecated_decorator=  s   
ûz(deprecated.<locals>.deprecated_decoratorr   )rs   rj   rk   ri   rz   r   ry   r   Ú
deprecatedû   s
   @ÿr{   )NNNNN)r<   Útypingr   rV   rR   rH   Ú	functoolsr   r   Zsympy.utilities.exceptionsr   r   r#   r'   r)   r/   r0   rN   r[   rg   r{   r   r   r   r   Ú<module>   s*    
ÿ41ÿ