B
    S\k                 @   sD   d Z ddlZddlZddlmZ dd Zdd Zdd	 Zd
d ZdS )a  Contains logic for retrieving special methods.

This implementation does not rely on the dot attribute access
logic, found in ``.getattr()``. The difference between these two
is that the dunder methods are looked with the type slots
(you can find more about these here
http://lucumr.pocoo.org/2014/8/16/the-python-i-would-like-to-see/)
As such, the lookup for the special methods is actually simpler than
the dot attribute access.
    N)
exceptionsc                sV   | j  g }tj fdd| jddD }tt||}|sRtj | d|S )Nc             3   s   | ]}|j  g V  qd S )N)localsget).0Zancestor)name @lib/python3.7/site-packages/astroid/interpreter/dunder_lookup.py	<genexpr>   s    z!_lookup_in_mro.<locals>.<genexpr>T)Zrecurs)	attributetarget)	r   r   	itertoolschainfrom_iterableZ	ancestorslistr   AttributeInferenceError)noder   ZattrsZnodesvaluesr   )r   r   _lookup_in_mro   s    r   c             C   sf   t | tjtjtjtjtjfr(t| |S t | tjr>t	| |S t | tj
rTt| |S tj|| ddS )zLookup the given special method name in the given *node*

    If the special method was found, then a list of attributes
    will be returned. Otherwise, `astroid.AttributeInferenceError`
    is going to be raised.
    )r
   r   N)
isinstanceastroidZListZTupleZConstZDictSet_builtin_lookupZInstancer   ZClassDef_class_lookupr   r   )r   r   r   r   r   lookup"   s    


r   c             C   s(   |   }|d krtj|| dt||S )N)r
   r   )	metaclassr   r   r   )r   r   r   r   r   r   r   5   s    r   c             C   s$   | j |g }|s tj|| d|S )N)r
   r   )r   r   r   r   )r   r   r   r   r   r   r   =   s    r   )__doc__r   r   r   r   r   r   r   r   r   r   r   <module>   s   