+
    eD                         R t ^ RIHt ^ RIHt ^ RIHt ^t ^t ^t	 ^t
  ! R R4      t]R 4       t]3R lt ! R R	4      tR
# )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_VALUESc                   &   a  ] tR t^5t o R tRtV tR# )RecursionDetectorc                    . V n         R # Npushed_nodesselfs   &:/usr/lib/python3/dist-packages/jedi/inference/recursion.py__init__RecursionDetector.__init__6   s
        r	   N)__name__
__module____qualname____firstlineno__r   __static_attributes____classdictcell____classdict__s   @r   r   r   5   s      r   r   c           	   #    "   V P                   P                  pW9   d*   \        P                  ! RV\	        VRR4      4       Rx  R#  VP                  V4       Rx  VP                  4        R#   TP                  4        i ; i5i)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)recursion_detectorr
   r   warninggetattrappendpop)inference_statenoder
   s   && r   execution_allowedr"   :   sp      #55BBL6dK6	8	%JLs   AB	A0 B0BBc                    a  V 3R  lpV# )c                    <a  VV 3R  lpV# )c                    < V P                   P                  pVP                  V 4      p V'       d   SpM	S! V 3/ VB pVP                  4        V#   TP                  4        i ; ir   )r    execution_recursion_detectorpush_executionpop_execution)r   kwargsdetectorlimit_reachedresultdefaultfuncs   &,   r   wrapperAexecution_recursion_decorator.<locals>.decorator.<locals>.wrapperP   sa    ++HHH$33D9M) $F!$1&1F&&(M &&(s   A A A" )r.   r/   r-   s   f r   	decorator0execution_recursion_decorator.<locals>.decoratorO   s    
	 r   r1   )r-   r2   s   f r   execution_recursion_decoratorr4   N   s     r   c                   6   a  ] tR t^_t o RtR tR tR tRtV t	R# )ExecutionRecursionDetectorz#
Catches recursions of executions.
c                J    Wn         ^ V n        . V n        / V n        ^ V n        R# )    N)_inference_state_recursion_level_parent_execution_funcs_funcdef_execution_counts_execution_count)r   r    s   &&r   r   #ExecutionRecursionDetector.__init__c   s(     / !')$)+& !r   c                l    V P                   P                  4        V ;P                  ^,          un        R# )   N)r;   r   r:   r   s   &r   r(   (ExecutionRecursionDetector.pop_executionk   s%    $$((*"r   c                F   VP                   pV ;P                  ^,          un        V P                  P                  V4       VP	                  4       pVP                  4       '       d   R# V P                  \        8  d   \        P                  ! R\        4       R# V P                  \        8  d   \        P                  ! R\        4       R# V ;P                  ^,          un	        V P                  P                  V^ 4      \        8  d6   VP                  4       R8X  d   R# \        P                  ! R\        V4       R# V P                  V;;,          ^,          uu&   V P                  P                  V4      \         8  d   \        P                  ! R\         V4       R# R# )r@   FzRecursion limit (%s) reachedTz%Function execution limit (%s) reachedtypingz-Per function execution limit (%s) reached: %sz-Per function recursion limit (%s) reached: %s)	tree_noder:   r;   r   get_root_contextis_builtins_modulerecursion_limitr   r   r=   total_function_execution_limitr<   
setdefaultper_function_execution_limit
py__name__countper_function_recursion_limit)r   	executionfuncdefmodule_contexts   &&  r   r'   )ExecutionRecursionDetector.push_executiono   s@   %% 	"$$++G4"335,,..   ?2MM8/J  $BBMMACab"))44Wa@D``((*h6MM?,
 &&w/14/''--g69UUMM?,
 r   )r=   r<   r9   r;   r:   N)
r   r   r   r   __doc__r   r(   r'   r   r   r   s   @r   r6   r6   _   s     "#* *r   r6   N)rR   
contextlibr   jedir   jedi.inference.base_valuer   rG   rH   rJ   rM   r   r"   r4   r6   r1   r   r   <module>rV      sz   8 &  /  "%   !   ! 
 
  & +4 ": :r   