o
    g                     @   sR   d dl mZ d dlZd dlmZ d dlmZmZ d dlmZ G dd dej	Z
dS )    )ListN)nodes)checkers
interfaces)utilsc                   @   s   e Zd ZdZejfZdZddiZdZ	dZ
eddejd	d
fddZedejd	efddZeddejd	d
fddZedejd	eej fddZd
S )
LenCheckera   Checks for incorrect usage of len() inside conditions.
    Pep8 states:
    For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

        Yes: if not seq:
             if seq:

        No: if len(seq):
            if not len(seq):

    Problems detected:
    * if len(sequence):
    * if not len(sequence):
    * elif len(sequence):
    * elif not len(sequence):
    * while len(sequence):
    * while not len(sequence):
    * assert len(sequence):
    * assert not len(sequence):
    * bool(len(sequence))
    refactoringC1801)zQDo not use `len(SEQUENCE)` without comparison to determine if a sequence is emptylen-as-conditiona  Used when Pylint detects that len(sequence) is being used without explicit comparison inside a condition to determine if a sequence is empty. Instead of coercing the length to a boolean, either rely on the fact that empty sequences are false or compare the length against a scalar. r
   nodereturnNc                    s   t |dsd S |j}t|tjr|j}t|tjst ||s"d S |jd }tjtj	tj
tjf}t||r?| jd|d d S zt| }W n tjyR   Y d S w | | t fdddD }d v sn|rw| |sy| jd|d d S d S d S )	Nlenr   r
   r   c                 3   s    | ]}| v V  qd S )Nr   ).0tmother_classesr   e/home/ubuntu/cloudmapper/venv/lib/python3.10/site-packages/pylint/checkers/refactoring/len_checker.py	<genexpr>W   s    
z(LenChecker.visit_call.<locals>.<genexpr>)strtuplelistsetrange)r   is_call_of_nameparent
isinstancer   BoolOpis_test_conditionargsListCompSetCompDictCompGeneratorExpadd_messagenextinferastroidInferenceErrorbase_classes_of_nodeanyinstance_has_bool)selfr   r   len_arggenerator_or_comprehensioninstanceaffected_by_pep8r   r   r   
visit_call6   sB   


zLenChecker.visit_call	class_defc                 C   s(   z|  d W dS  tjy   Y dS w )N__bool__TF)getattrr)   AttributeInferenceError)r4   r   r   r   r-   _   s   
zLenChecker.instance_has_boolc                 C   sB   t |tjr|jdkrt|jdr| jd|d dS dS dS dS )z`not len(S)` must become `not S` regardless if the parent block
        is a test condition or something else (boolean expression)
        e.g. `if not len(S):`notr   r
   r   N)r   r   UnaryOpopr   r   operandr&   )r.   r   r   r   r   visit_unaryoph   s   

zLenChecker.visit_unaryopr1   c                 C   s8   z| j gdd |  D  W S  ty   | j g Y S w )zMReturn all the classes names that a ClassDef inherit from including 'object'.c                 S   s   g | ]}|j qS r   )name)r   xr   r   r   
<listcomp>x   s    z3LenChecker.base_classes_of_node.<locals>.<listcomp>)r=   	ancestors	TypeError)r1   r   r   r   r+   t   s
   zLenChecker.base_classes_of_node)__name__
__module____qualname____doc__r   IAstroidChecker__implements__r=   msgspriorityoptionsr   check_messagesr   Callr3   staticmethodClassDefboolr-   r9   r<   r   Namer+   r   r   r   r   r      s     ( r   )typingr   r)   r   pylintr   r   pylint.checkersr   BaseCheckerr   r   r   r   r   <module>   s   