B
    7r\Y                 @   s   d Z ddlZddlmZ ddlmZ ddlmZmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZ ddlmZ dd Z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G dd deZdS )z
The :mod:`jedi.api.classes` module contains the return classes of the API.
These classes are the much bigger part of the whole API, because they contain
the interesting information about completion and goto operations.
    N)search_ancestor)settings)ignoredunite)memoize_method)imports)compiled)
ImportName)instance)ClassContextFunctionExecutionContext)KeywordNamec             C   s   t | dd dS )Nc             S   s
   | j pdS )N)r   r   )	start_pos)s r   /lib/python3.7/site-packages/jedi/api/classes.py<lambda>   s    z*_sort_names_by_start_pos.<locals>.<lambda>)key)sorted)namesr   r   r   _sort_names_by_start_pos   s    r   c                s8   t |jdd}dd | D } fddt|D S )zo
    List sub-definitions (e.g., methods in class).

    :type scope: Scope
    :rtype: list of Definition
    T)Zsearch_globalc             S   s   g | ]}|qS r   r   ).0namer   r   r   
<listcomp>!   s    z!defined_names.<locals>.<listcomp>c                s   g | ]}t  |qS r   )
Definition)r   n)	evaluatorr   r   r   "   s    )nextZget_filtersvaluesr   )r   contextfilterr   r   )r   r   defined_names   s    r!   c               @   s   e Zd ZdddddddddddddZedd	 d
di D Zdd Zedd Z	edd Z
dd Zedd Zdd Zedd Zedd Zd2ddZed d! Zed"d# Zd$d% Zd&d' Zeed(d) Zd*d+ Zd,d- Zd3d/d0Zd1S )4BaseDefinitionzos.pathosio	functoolsZsqlite3 )	posixpathZ
riscospathZntpathZ
os2emxpathZmacpathgenericpathposix_io
_functoolsZ_sqlite3Z__builtin__builtinsc             c   s$   | ]\}}t |d |fV  qdS ).N)tuplesplit)r   kvr   r   r   	<genexpr>5   s    zBaseDefinition.<genexpr>zargparse._ActionsContainerzargparse.ArgumentParserc             C   sD   || _ || _t| jt| _| | _|  r4d | _n| j	 | _d S )N)

_evaluator_name
isinstancer   Z
is_keywordget_root_context_modulein_builtin_modulemodule_pathZ
py__file__)selfr   r   r   r   r   __init__9   s    
zBaseDefinition.__init__c             C   s   | j jS )z
        Name of variable/function/class/module.

        For example, for ``x = None`` it returns ``'x'``.

        :rtype: str or None
        )r4   string_name)r:   r   r   r   r   I   s    	zBaseDefinition.namec             C   sl   | j j}d}|dk	r:| }|dk	r:|jdkr:| r:d}t| j tjsL|rdx| j  D ]}|j	S W | j j	S )a  
        The type of the definition.

        Here is an example of the value of this attribute.  Let's consider
        the following source.  As what is in ``variable`` is unambiguous
        to Jedi, :meth:`jedi.Script.goto_definitions` should return a list of
        definition for ``sys``, ``f``, ``C`` and ``x``.

        >>> from jedi import Script
        >>> source = '''
        ... import keyword
        ...
        ... class C:
        ...     pass
        ...
        ... class D:
        ...     pass
        ...
        ... x = D()
        ...
        ... def f():
        ...     pass
        ...
        ... for variable in [keyword, f, C, x]:
        ...     variable'''

        >>> script = Script(source)
        >>> defs = script.goto_definitions()

        Before showing what is in ``defs``, let's sort it by :attr:`line`
        so that it is easy to relate the result to the source code.

        >>> defs = sorted(defs, key=lambda d: d.line)
        >>> defs                           # doctest: +NORMALIZE_WHITESPACE
        [<Definition module keyword>, <Definition class C>,
         <Definition instance D>, <Definition def f>]

        Finally, here is what you can get from :attr:`type`:

        >>> defs = [str(d.type) for d in defs]  # It's unicode and in Py2 has u before it.
        >>> defs[0]
        'module'
        >>> defs[1]
        'class'
        >>> defs[2]
        'instance'
        >>> defs[3]
        'function'

        FNZimport_fromT)
r4   	tree_nameget_definitiontypeis_definitionr5   r   ZSubModuleNameinferapi_type)r:   r=   Zresolve
definitionr   r   r   r   r?   T   s    4zBaseDefinition.typec                s    fdd}t t| S )z/The path to a module/class/function definition.c              3   s   j } | jdkr<yt|  d j} W n tk
r:   Y nX | jdkr|  }|r||\}x.t| dD ]
}|V  qlW q| j	V  d S n| j	V  | j
}xx|d k	ry
|j}W n8 tk
r   y|jj	V  W n tk
r   Y nX Y n"X xt| dD ]
} | V  qW |j
}qW d S )Nmoduler   r-   )r4   rB   listrA   r   
IndexErrorreversedZ
py__name__r/   r<   parent_contextAttributeError)r   Zmodule_contextsZmodule_contextr   rH   method)r:   r   r   
to_reverse   s6    



z(BaseDefinition._path.<locals>.to_reverse)rG   rE   )r:   rK   r   )r:   r   _path   s    $zBaseDefinition._pathc             C   s
   | j jjS )a'  
        The module name.

        >>> from jedi import Script
        >>> source = 'import json'
        >>> script = Script(source, path='example.py')
        >>> d = script.goto_definitions()[0]
        >>> print(d.module_name)                       # doctest: +ELLIPSIS
        json
        )r7   r   r<   )r:   r   r   r   module_name   s    zBaseDefinition.module_namec             C   s   t | jtjS )z!Whether this is a builtin module.)r5   r7   r   CompiledObject)r:   r   r   r   r8      s    z BaseDefinition.in_builtin_modulec             C   s   | j j}|dkrdS |d S )z7The line where the definition occurs (starting with 1).Nr   )r4   r   )r:   r   r   r   r   line   s    zBaseDefinition.linec             C   s   | j j}|dkrdS |d S )z9The column where the definition occurs (starting with 0).N   )r4   r   )r:   r   r   r   r   column   s    zBaseDefinition.columnFTc             C   s   t | jj||dS )aS  
        Return a document string for this completion object.

        Example:

        >>> from jedi import Script
        >>> source = '''\
        ... def f(a, b=1):
        ...     "Document for function f."
        ... '''
        >>> script = Script(source, 1, len('def f'), 'example.py')
        >>> doc = script.goto_definitions()[0].docstring()
        >>> print(doc)
        f(a, b=1)
        <BLANKLINE>
        Document for function f.

        Notice that useful extra information is added to the actual
        docstring.  For function, it is call signature.  If you need
        actual docstring, use ``raw=True`` instead.

        >>> print(script.goto_definitions()[0].docstring(raw=True))
        Document for function f.

        :param fast: Don't follow imports that are only one level deep like
            ``import foo``, but follow ``from foo import bar``. This makes
            sense for speed reasons. Completing `import a` is slow if you use
            the ``foo.docstring(fast=False)`` on every object, because it
            parses all libraries starting with ``a``.
        )fastraw)_Helpr4   	docstring)r:   rS   rR   r   r   r   rU      s    zBaseDefinition.docstringc             C   s   | j jS )z$A textual description of the object.)r4   r<   )r:   r   r   r   description  s    zBaseDefinition.descriptionc          	   C   s   t |  }|sdS tt | j|d  |d< W dQ R X xD| j D ]6\}}t|dt| |krF|g|t|d  }qFW d	|d r|n
|dd S )a  
        Dot-separated path of this object.

        It is in the form of ``<module>[.<submodule>[...]][.<object>]``.
        It is useful when you want to look up Python manual of the
        object at hand.

        Example:

        >>> from jedi import Script
        >>> source = '''
        ... import os
        ... os.path.join'''
        >>> script = Script(source, 3, len('os.path.join'), 'example.py')
        >>> print(script.goto_definitions()[0].full_name)
        os.path.join

        Notice that it returns ``'os.path.join'`` instead of (for example)
        ``'posixpath.join'``. This is not correct, since the modules name would
        be ``<module 'posixpath' ...>```. However most users find the latter
        more practical.
        Nr   r-   rP   )
rE   rL   r   KeyError_mapping_tuple_mappingitemsr.   lenjoin)r:   pathr   replr   r   r   	full_name  s    
zBaseDefinition.full_namec                s8    j jd kr S  j j j j j} fdd|D S )Nc                s   g | ]}t  j|qS r   )r   r3   )r   r   )r:   r   r   r   0  s    z3BaseDefinition.goto_assignments.<locals>.<listcomp>)r4   r=   r3   ZgotorH   )r:   r   r   )r:   r   goto_assignments+  s    zBaseDefinition.goto_assignmentsc                s    fdd j  D S )Nc                s   g | ]}t  j|jqS r   )r   r3   r   )r   d)r:   r   r   r   4  s    z4BaseDefinition._goto_definitions.<locals>.<listcomp>)r4   rA   )r:   r   )r:   r   _goto_definitions2  s    z BaseDefinition._goto_definitionsc                sR    fdd t j }|r,t|d ds4td|d }fdd |D S )z
        Raises an ``AttributeError``if the definition is not callable.
        Otherwise returns a list of `Definition` that represents the params.
        c                s   g }| j dkr4t|  }t| tjr|dd  }nt| tjtfrt| trTd}nd}| |}|sjg S |d 	 } t
t|}t| tr|dd  }|S t| tjrt|  S |S )NfunctionrP   r;   __call__r   )rB   rE   get_param_namesr5   r
   ZBoundMethodZAbstractInstanceContextr   Zget_function_slot_namesrA   r   iterr   rN   )r   Zparam_namessearchr   Zinferred)re   r   r   re   =  s(    



z.BaseDefinition.params.<locals>.get_param_namesr   Z
py__call__z$There are no params defined on this.c                s   g | ]}t  j|qS r   )r   r3   )r   r   )r:   r   r   r   \  s    z)BaseDefinition.params.<locals>.<listcomp>)rE   r4   rA   hasattrrI   )r:   Zfollowedr   r   )re   r:   r   params6  s    zBaseDefinition.paramsc             C   s2   | j j}|d krd S t|tr$|j}t| j|jS )N)r4   rH   r5   r   Zfunction_contextr   r3   r   )r:   r   r   r   r   parent^  s    
zBaseDefinition.parentc             C   s   dt | j| jf S )Nz<%s %s>)r?   __name__rV   )r:   r   r   r   __repr__g  s    zBaseDefinition.__repr__r   c             C   sP   |   rdS | j j}| jjd d }t|| d}d|||| d  S )aI  
        Returns the line of code where this object was defined.

        :param before: Add n lines before the current line to the output.
        :param after: Add n lines after the current line to the output.

        :return str: Returns the line(s) of code or an empty string if it's a
                     builtin.
        r&   r   rP   )r8   r4   r6   Z
code_linesr   maxr\   )r:   ZbeforeZafterlinesindexZstart_indexr   r   r   get_line_codej  s    
zBaseDefinition.get_line_codeN)FT)r   r   )rk   
__module____qualname__rX   dictrZ   rY   r;   propertyr   r?   rL   rM   r8   rO   rQ   rU   rV   r_   r`   rb   r   ri   rj   rl   rp   r   r   r   r   r"   %   s@   B(
!%'	r"   c                   sn   e Zd ZdZ fddZdd Zedd Zedd	 Zd fdd	Z	edd Z
dd Zedd Z  ZS )
Completionz
    `Completion` objects are returned from :meth:`api.Script.completions`. They
    provide additional information about a completion.
    c                s(   t t| || || _|| _g | _d S )N)superru   r;   _like_name_length_stackZ_same_name_completions)r:   r   r   stackZlike_name_length)	__class__r   r   r;     s    zCompletion.__init__c             C   sx   d}t jr| jdkrd}| jjdkrV| jd k	rVdd | jD }d|krVd|krV|d	7 }| jj}|rp|| jd  }|| S )
Nr&   ZFunction(paramc             S   s   g | ]
}|j qS r   )Znonterminal)r   Z
stack_noder   r   r   r     s    z(Completion._complete.<locals>.<listcomp>ZtrailerZargument=)r   Zadd_bracket_after_functionr?   r4   rB   rx   r<   rw   )r:   Z	like_nameappendZnonterminalsr   r   r   r   	_complete  s    
zCompletion._completec             C   s
   |  dS )a  
        Return the rest of the word, e.g. completing ``isinstance``::

            isinstan# <-- Cursor is here

        would return the string 'ce'. It also adds additional stuff, depending
        on your `settings.py`.

        Assuming the following function definition::

            def foo(param=0):
                pass

        completing ``foo(par`` would give a ``Completion`` which `complete`
        would be `am=`


        T)r   )r:   r   r   r   complete  s    zCompletion.completec             C   s
   |  dS )a@  
        Similar to :attr:`name`, but like :attr:`name` returns also the
        symbols, for example assuming the following function definition::

            def foo(param=0):
                pass

        completing ``foo(`` would give a ``Completion`` which
        ``name_with_symbols`` would be "param=".

        F)r   )r:   r   r   r   name_with_symbols  s    zCompletion.name_with_symbolsFTc                s"   | j dkrd}tt| j||dS )N   F)rS   rR   )rw   rv   ru   rU   )r:   rS   rR   )rz   r   r   rU     s    
zCompletion.docstringc             C   s   t j| S )z/Provide a description of the completion object.)r   rV   __get__)r:   r   r   r   rV     s    zCompletion.descriptionc             C   s   dt | j| jjf S )Nz<%s: %s>)r?   rk   r4   r<   )r:   r   r   r   rl     s    zCompletion.__repr__c                s    j  } fdd|D S )a  
        Return the original definitions. I strongly recommend not using it for
        your completions, because it might slow down |jedi|. If you want to
        read only a few objects (<=20), it might be useful, especially to get
        the original docstrings. The basic problem of this function is that it
        follows all results. This means with 1000 completions (e.g.  numpy),
        it's just PITA-slow.
        c                s   g | ]}t  j|jqS r   )r   r3   r   )r   ra   )r:   r   r   r     s    z0Completion.follow_definition.<locals>.<listcomp>)r4   rA   )r:   defsr   )r:   r   follow_definition  s    

zCompletion.follow_definition)FT)rk   rq   rr   __doc__r;   r   rt   r   r   rU   rV   rl   r   r   __classcell__r   r   )rz   r   ru   ~  s   
ru   c                   sd   e Zd ZdZ fddZedd Zedd Zedd	 Z	d
d Z
dd Zdd Zdd Z  ZS )r   z
    *Definition* objects are returned from :meth:`api.Script.goto_assignments`
    or :meth:`api.Script.goto_definitions`.
    c                s   t t| || d S )N)rv   r   r;   )r:   r   rC   )rz   r   r   r;     s    zDefinition.__init__c             C   s   | j }| jj}|dks|dkr:|dkr*d}|d | jj S |dkrbt|djddd}|d | S | pl|}|jdd	}td
d|}tdd|	 }|S )a  
        A description of the :class:`.Definition` object, which is heavily used
        in testing. e.g. for ``isinstance`` it returns ``def isinstance``.

        Example:

        >>> from jedi import Script
        >>> source = '''
        ... def f():
        ...     pass
        ...
        ... class C:
        ...     pass
        ...
        ... variable = f if random.choice([0,1]) else C'''
        >>> script = Script(source, column=3)  # line is maximum by default
        >>> defs = script.goto_definitions()
        >>> defs = sorted(defs, key=lambda d: d.line)
        >>> defs
        [<Definition def f>, <Definition class C>]
        >>> str(defs[0].description)  # strip literals in python2
        'def f'
        >>> str(defs[1].description)
        'class C'

        )rc   classrD   r
   Nrc   def r|   F)include_prefixZinclude_comma)r   z	#[^\n]+\nz\s+)
r?   r4   r=   r<   r   get_coder>   resubstrip)r:   typr=   coderC   Ztxtr   r   r   rV     s     
zDefinition.descriptionc             C   s&   | j r
dnd| j }d| j| j|f S )a1  
        In addition to the definition, also return the module.

        .. warning:: Don't use this function yet, its behaviour may change. If
            you really need it, talk to me.

        .. todo:: Add full path. This function is should return a
            `module.class.function` path.
        r&   z@%sz%s:%s%s)r8   rO   rM   rV   )r:   Zpositionr   r   r   desc_with_module  s    zDefinition.desc_with_modulec                s,    j  }tt fdd|D dd dS )zd
        List sub-definitions (e.g., methods in class).

        :rtype: list of Definition
        c             3   s   | ]}t  j|V  qd S )N)r!   r3   )r   ra   )r:   r   r   r2   4  s    z+Definition.defined_names.<locals>.<genexpr>c             S   s   | j jp
dS )N)r   r   )r4   r   )r   r   r   r   r   5  s    z*Definition.defined_names.<locals>.<lambda>)r   )r4   rA   r   r   )r:   r   r   )r:   r   r!   +  s    
zDefinition.defined_namesc             C   s    | j jdkrdS | j j S dS )z
        Returns True, if defined as a name in a statement, function or class.
        Returns False, if it's a reference to such a definition.
        NT)r4   r=   r@   )r:   r   r   r   r@   8  s    zDefinition.is_definitionc             C   s4   | j j|j jko2| j|jko2| j|jko2| j|jkS )N)r4   r   r9   r   r3   )r:   otherr   r   r   __eq__B  s    zDefinition.__eq__c             C   s   |  | S )N)r   )r:   r   r   r   r   __ne__H  s    zDefinition.__ne__c             C   s   t | jj| j| j| jfS )N)hashr4   r   r9   r   r3   )r:   r   r   r   __hash__K  s    zDefinition.__hash__)rk   rq   rr   r   r;   rt   rV   r   r   r!   r@   r   r   r   r   r   r   )rz   r   r     s   4
r   c                   sL   e Zd ZdZ fddZedd Zedd Zedd	 Zd
d Z	  Z
S )CallSignaturez
    `CallSignature` objects is the return value of `Script.function_definition`.
    It knows what functions you are currently in. e.g. `isinstance(` would
    return the `isinstance` function. without `(` it would return nothing.
    c                s(   t t| || || _|| _|| _d S )N)rv   r   r;   _index_key_name_str_bracket_start_pos)r:   r   Zexecutable_nameZbracket_start_posro   Zkey_name_str)rz   r   r   r;   U  s    zCallSignature.__init__c             C   s   | j dk	rfx&t| jD ]\}}| j |jkr|S qW | jrb| jd j}|jdk	rb|j jdkrb|S dS | jt	| jkrx8t| jD ]*\}}|jj}|dk	r| jdkr|S qW dS | jS )z|
        The Param index of the current call.
        Returns None if the index cannot be found in the curent call.
        N   rP   )
r   	enumerateri   r   r4   r=   r>   Z
star_countr   r[   )r:   ir|   Z
param_namer=   r   r   r   ro   [  s$    

zCallSignature.indexc             C   s   | j S )zc
        The indent of the bracket that is responsible for the last function
        call.
        )r   )r:   r   r   r   bracket_startv  s    zCallSignature.bracket_startc             C   s   d dd | jD S )Nz, c             S   s   g | ]}|j d d qS )   N)rV   )r   pr   r   r   r     s   z-CallSignature._params_str.<locals>.<listcomp>)r\   ri   )r:   r   r   r   _params_str~  s    
zCallSignature._params_strc             C   s   dt | j| jj| j| jf S )Nz<%s: %s index=%r params=[%s]>)r?   rk   r4   r<   r   r   )r:   r   r   r   rl     s
    zCallSignature.__repr__)rk   rq   rr   r   r;   rt   ro   r   r   rl   r   r   r   )rz   r   r   O  s   r   c               @   s.   e Zd ZdZdd Zedd Zd
ddZd	S )rT   zb
    Temporary implementation, will be used as `Script.help() or something in
    the future.
    c             C   s
   || _ d S )N)r4   )r:   rC   r   r   r   r;     s    z_Help.__init__c             C   s.   t | jtr|ri S | jjdkr$i S | j S )NZ	statement)r5   r4   r	   rB   rA   )r:   rR   r   r   r   _get_contexts  s
    z_Help._get_contextsTc             C   s&   x | j |dD ]}|j| dS W dS )za
        The docstring ``__doc__`` for any object.

        See :attr:`doc` for example.
        )rR   )Zinclude_call_signaturer&   )r   Z	py__doc__)r:   rR   rS   r   r   r   r   rU     s    z_Help.docstringN)TT)rk   rq   rr   r   r;   r   r   rU   r   r   r   r   rT     s   
rT   )r   r   Zparso.python.treer   Zjedir   Zjedi.evaluate.utilsr   r   Z
jedi.cacher   Zjedi.evaluater   r   Zjedi.evaluate.importsr	   Zjedi.evaluate.contextr
   r   r   Zjedi.api.keywordsr   r   r!   objectr"   ru   r   r   rT   r   r   r   r   <module>   s(     [cn=