a
    Š©lcD  ã                   @   sp   d Z ddlmZ ddlmZ ddlmZ dZdZdZ	dZ
G d	d
„ d
ƒZedd„ ƒZefdd„ZG dd„ dƒZdS )a   
Recursions are the recipe of |jedi| to conquer Python code. However, someone
must stop recursions going mad. Some settings are here to make |jedi| stop at
the right time. You can read more about them :ref:`here <settings-recursion>`.

Next to the internal ``jedi.inference.cache`` this module also makes |jedi| not
thread-safe, because ``execution_recursion_decorator`` uses class variables to
count the function calls.

.. _settings-recursion:

Settings
~~~~~~~~~~

Recursion settings are important if you don't want extremely
recursive python code to go absolutely crazy.

The default values are based on experiments while completing the |jedi| library
itself (inception!). But I don't think there's any other Python library that
uses recursion in a similarly extreme way. Completion should also be fast and
therefore the quality might not always be maximal.

.. autodata:: recursion_limit
.. autodata:: total_function_execution_limit
.. autodata:: per_function_execution_limit
.. autodata:: per_function_recursion_limit
é    )Úcontextmanager)Údebug)Ú	NO_VALUESé   éÈ   é   é   c                   @   s   e Zd Zdd„ ZdS )ÚRecursionDetectorc                 C   s
   g | _ d S ©N)Úpushed_nodes©Úself© r   úT/var/www/html/django/DPS/env/lib/python3.9/site-packages/jedi/inference/recursion.pyÚ__init__6   s    zRecursionDetector.__init__N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r	   5   s   r	   c                 c   sZ   | j j}||v r.t d|t|ddƒ¡ dV  n(z| |¡ dV  W | ¡  n
| ¡  0 dS )z
    A decorator to detect recursions in statements. In a recursion a statement
    at the same place, in the same module may not be executed two times.
    zcatched stmt recursion: %s @%sÚ	start_posNFT)Zrecursion_detectorr   r   ÚwarningÚgetattrÚappendÚpop)Úinference_stateÚnoder   r   r   r   Úexecution_allowed:   s    
ÿ
r   c                    s   ‡ fdd„}|S )Nc                    s   ‡‡ fdd„}|S )Nc                    sH   | j j}| | ¡}z&|rˆ }nˆ| fi |¤Ž}W | ¡  n
| ¡  0 |S r
   )r   Zexecution_recursion_detectorÚpush_executionÚpop_execution)r   ÚkwargsÚdetectorZlimit_reachedÚresult)ÚdefaultÚfuncr   r   ÚwrapperP   s    
zAexecution_recursion_decorator.<locals>.decorator.<locals>.wrapperr   )r"   r#   ©r!   )r"   r   Ú	decoratorO   s    z0execution_recursion_decorator.<locals>.decoratorr   )r!   r%   r   r$   r   Úexecution_recursion_decoratorN   s    r&   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚExecutionRecursionDetectorz+
    Catches recursions of executions.
    c                 C   s"   || _ d| _g | _i | _d| _d S )Nr   )Z_inference_stateÚ_recursion_levelÚ_parent_execution_funcsÚ_funcdef_execution_countsÚ_execution_count)r   r   r   r   r   r   c   s
    z#ExecutionRecursionDetector.__init__c                 C   s   | j  ¡  |  jd8  _d S )Né   )r)   r   r(   r   r   r   r   r   k   s    
z(ExecutionRecursionDetector.pop_executionc                 C   sâ   |j }|  jd7  _| j |¡ | ¡ }| ¡ r4dS | jtkrNt dt¡ dS | j	t
krht dt
¡ dS |  j	d7  _	| j |d¡tkrª| ¡ dkr˜dS t dt|¡ dS | j|  d7  < | j |¡tkrÞt d	t|¡ dS dS )
Nr,   FzRecursion limit (%s) reachedTz%Function execution limit (%s) reachedr   Útypingz-Per function execution limit (%s) reached: %sz-Per function recursion limit (%s) reached: %s)Z	tree_noder(   r)   r   Zget_root_contextZis_builtins_moduleÚrecursion_limitr   r   r+   Útotal_function_execution_limitr*   Ú
setdefaultÚper_function_execution_limitZ
py__name__ÚcountÚper_function_recursion_limit)r   Z	executionZfuncdefZmodule_contextr   r   r   r   o   s>    

ýýz)ExecutionRecursionDetector.push_executionN)r   r   r   Ú__doc__r   r   r   r   r   r   r   r'   _   s   r'   N)r4   Ú
contextlibr   Zjedir   Zjedi.inference.base_valuer   r.   r/   r1   r3   r	   r   r&   r'   r   r   r   r   Ú<module>   s   
