B
    S£†\.  ã               @   sN   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 G dd„ dƒZdS )	é    )Úbases)Úcontext)Ú
exceptions)Únodes)Úutilc               @   sN   e Zd ZdZddd„Zedd„ ƒZdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ ZdS )ÚCallSiteaS  Class for understanding arguments passed into a call site

    It needs a call context, which contains the arguments and the
    keyword arguments that were passed into a given call site.
    In order to infer what an argument represents, call
    :meth:`infer_argument` with the corresponding function node
    and the argument name.
    Nc             C   sj   |d kri }|| _ |j}|j}tƒ | _|  |¡| _|  |¡| _dd„ | jD ƒ| _	dd„ | j 
¡ D ƒ| _d S )Nc             S   s   g | ]}|t jk	r|‘qS © )r   ÚUninferable)Ú.0Úargr   r   ú0lib/python3.7/site-packages/astroid/arguments.pyú
<listcomp>'   s    z%CallSite.__init__.<locals>.<listcomp>c             S   s    i | ]\}}|t jk	r||“qS r   )r   r	   )r
   ÚkeyÚvaluer   r   r   ú
<dictcomp>)   s   z%CallSite.__init__.<locals>.<dictcomp>)Úargument_context_mapÚargsÚkeywordsÚsetÚduplicated_keywordsÚ_unpack_argsÚ_unpacked_argsÚ_unpack_keywordsÚ_unpacked_kwargsÚpositional_argumentsÚitemsÚkeyword_arguments)ÚselfÚcallcontextr   r   r   r   r   r   Ú__init__   s    zCallSite.__init__c             C   s   t  |j|j¡}| |ƒS )z/Get a CallSite object from the given Call node.)Ú
contextmodZCallContextr   r   )ÚclsZ	call_noder   r   r   r   Ú	from_call/   s    zCallSite.from_callc             C   s   t | jƒt | jƒkS )an  Check if in the current CallSite were passed *invalid* arguments

        This can mean multiple things. For instance, if an unpacking
        of an invalid object was passed, then this method will return True.
        Other cases can be when the arguments can't be inferred by astroid,
        for example, by passing objects which aren't known statically.
        )Úlenr   r   )r   r   r   r   Úhas_invalid_arguments5   s    zCallSite.has_invalid_argumentsc             C   s   t | jƒt | jƒkS )af  Check if in the current CallSite were passed *invalid* keyword arguments

        For instance, unpacking a dictionary with integer keys is invalid
        (**{1:2}), because the keys must be strings, which will make this
        method to return True. Other cases where this might return True if
        objects which can't be inferred were passed.
        )r#   r   r   )r   r   r   r   Úhas_invalid_keywords?   s    zCallSite.has_invalid_keywordsc       	   
   C   s@  i }t  ¡ }| j|_x$|D ]\}}|d kr0yt|j|dƒ}W n" tjk
rf   tj	||< wY nX t
|tjƒs€tj	||< qx¶|jD ]¢\}}yt|j|dƒ}W n" tjk
rÆ   tj	||< wˆY nX t
|tjƒsàtj	||< qˆt
|jtƒsøtj	||< qˆ|j|kr tj	||j< | j |j¡ qˆ|||j< qˆW q|||< qW |S )N)r   )r    ÚInferenceContextr   Úextra_contextÚnextÚinferr   ÚInferenceErrorr   r	   Ú
isinstancer   ÚDictr   ZConstr   Ústrr   Úadd)	r   r   Úvaluesr   Únamer   ÚinferredZdict_keyZ
dict_valuer   r   r   r   I   s@    





zCallSite._unpack_keywordsc          	   C   s¶   g }t  ¡ }| j|_xœ|D ]”}t|tjƒr¤yt|jj	|dƒ}W n$ t
jk
rd   | tj¡ wY nX |tjkr~| tj¡ qt|dƒs–| tj¡ q| |j¡ q| |¡ qW |S )N)r   Úelts)r    r&   r   r'   r+   r   ZStarredr(   r   r)   r   r*   Úappendr   r	   ÚhasattrÚextendr2   )r   r   r/   r   r   r1   r   r   r   r   q   s&    


zCallSite._unpack_argsc          	      s,  || j krtjd| |||d‚y| j|  |¡S  tk
rB   Y nX t| jƒt|jjƒkrv|jj	svtjd| |||d‚| jdt|jjƒ… }| jt|jjƒd… }|j 
|¡d }dd„ |jjD ƒ‰ ‡ fdd	„| j ¡ D ƒ}t|ƒt|jjƒk r(x4|jjD ](}|j|k rü| |j¡}	| |	¡  qüW |dk	r|dkrÚ|jd
krÚ|jdk	r\|j}
n
|j ¡ }
t|
tjƒr–|j ¡ }||
 ¡ kr–t|
fƒS |jdkrÄt|
tjƒsºt |
¡}
t|
fƒS |jdkrÚt|
fƒS |jd
krî|d8 }y| j|  |¡S  tk
r   Y nX |jj|kr†|  ¡ rJtjd| j| j| |||d‚tj |jj!|jj"|jd}| #dd„ | ¡ D ƒ¡ t|fƒS |jj	|krè|  $¡ rºtjd| j| j%| |||d‚tj&|jj!|jj"|jd}| #|¡ t|fƒS y|j '|¡ |¡S  tj(k
r   Y nX tjd| |||d‚dS )a  infer a function argument value according to the call context

        Arguments:
            funcnode: The function being called.
            name: The name of the argument whose value is being inferred.
            context: Inference context object
        z:The arguments passed to {func!r}  have duplicate keywords.)Ú	call_siteÚfuncr   r   zJToo many positional arguments passed to {func!r} that does not have *args.Nr   c             S   s   h | ]
}|j ’qS r   )r0   )r
   r   r   r   r   ú	<setcomp>¯   s    z*CallSite.infer_argument.<locals>.<setcomp>c                s   i | ]\}}|ˆ kr||“qS r   r   )r
   r   r   )Ú
kwonlyargsr   r   r   °   s   z+CallSite.infer_argument.<locals>.<dictcomp>)ÚmethodÚclassmethodr:   r;   é   z‡Inference failed to find values for all keyword arguments to {func!r}: {unpacked_kwargs!r} doesn't correspond to {keyword_arguments!r}.)r   Zunpacked_kwargsr6   r7   r   r   )ÚlinenoÚ
col_offsetÚparentc             S   s   g | ]\}}t  |¡|f‘qS r   )r   Zconst_factory)r
   r   r   r   r   r   r   ø   s    z+CallSite.infer_argument.<locals>.<listcomp>z‹Inference failed to find values for all positional arguments to {func!r}: {unpacked_args!r} doesn't correspond to {positional_arguments!r}.)r   Zunpacked_argsr6   r7   r   r   z.No value found for argument {name} to {func!r}))r   r   r*   r   r)   ÚKeyErrorr#   r   r   ÚvarargZfind_argnamer9   r   r0   Úpopr3   ÚtypeÚ	boundnoder?   Úframer+   r   ZClassDefZscopeÚ	metaclassÚiterr   ZInstanceÚ
IndexErrorÚkwargr%   r   r,   r=   r>   Zpostinitr$   r   ZTupleZdefault_valueZ	NoDefault)r   Zfuncnoder0   r   Z
positionalrA   ZargindexÚkwargsZfunc_argr   rD   Zmethod_scoperI   r   r   )r9   r   Úinfer_argumentˆ   s¼    















zCallSite.infer_argument)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r;   r"   r$   r%   r   r   rK   r   r   r   r   r      s   


(r   N)Zastroidr   r   r    r   r   r   r   r   r   r   r   Ú<module>   s
   