
    c{V                    \   U d Z ddlmZ ddlZddlmZ ddlmZ ddlm	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 e	rddlmZ ddddddddddd
Zded<    ej        d          Z eddh          ZdZdZdZ ed          Zd7d$Zd8d(Z d9d*Z!d:d.Z"d;d0Z# G d1 d2e          Z$d<d6Z%dS )=zCheck for signs of poor design.    )annotationsN)defaultdict)Iterator)TYPE_CHECKING)nodes)BaseChecker)is_enumonly_required_for_messages)MessageDefinitionTuple)PyLinter)zToo many ancestors (%s/%s)too-many-ancestorsznUsed when class has too many parent classes, try to reduce this to get a simpler (and so easier to use) class.)z$Too many instance attributes (%s/%s)too-many-instance-attributeszsUsed when class has too many instance attributes, try to reduce this to get a simpler (and so easier to use) class.)zToo few public methods (%s/%s)too-few-public-methodszLUsed when class has too few public methods, so be sure it's really worth it.)zToo many public methods (%s/%s)too-many-public-methodsznUsed when class has too many public methods, try to reduce this to get a simpler (and so easier to use) class.)z"Too many return statements (%s/%s)too-many-return-statementszWUsed when a function or method has too many return statement, making it hard to follow.)zToo many branches (%s/%s)too-many-brancheszOUsed when a function or method has too many branches, making it hard to follow.)zToo many arguments (%s/%s)too-many-argumentsz8Used when a function or method takes too many arguments.)z Too many local variables (%s/%s)too-many-localsz<Used when a function or method has too many local variables.)zToo many statements (%s/%s)too-many-statementszpUsed when a function or method has too many statements. You should then split it in smaller functions / methods.)z4Too many boolean expressions in if statement (%s/%s)too-many-boolean-expressionsz@Used when an if statement contains too many boolean expressions.)
R0901R0902R0903R0904R0911R0912R0913R0914R0915R0916z!dict[str, MessageDefinitionTuple]MSGSz^_{2}[a-z]+_{2}$	dataclassattrsdataclassesztyping.NamedTupleztyping.TypedDict)Kzbuiltins.objectzbuiltins.tuplezbuiltins.dictzbuiltins.listzbuiltins.setzbulitins.frozensetzcollections.ChainMapzcollections.Counterzcollections.OrderedDictzcollections.UserDictzcollections.UserListzcollections.UserStringzcollections.defaultdictzcollections.dequezcollections.namedtuplez_collections_abc.Awaitablez_collections_abc.Coroutinez_collections_abc.AsyncIterablez_collections_abc.AsyncIteratorz_collections_abc.AsyncGeneratorz_collections_abc.Hashablez_collections_abc.Iterablez_collections_abc.Iteratorz_collections_abc.Generatorz_collections_abc.Reversiblez_collections_abc.Sizedz_collections_abc.Containerz_collections_abc.Collectionz_collections_abc.Setz_collections_abc.MutableSetz_collections_abc.Mappingz_collections_abc.MutableMappingz_collections_abc.MappingViewz_collections_abc.KeysViewz_collections_abc.ItemsViewz_collections_abc.ValuesViewz_collections_abc.Sequencez _collections_abc.MutableSequencez_collections_abc.ByteStringztyping.Tupleztyping.Listztyping.Dictz
typing.Setztyping.FrozenSetztyping.Dequeztyping.DefaultDictztyping.OrderedDictztyping.Counterztyping.ChainMapztyping.Awaitableztyping.Coroutineztyping.AsyncIterableztyping.AsyncIteratorztyping.AsyncGeneratorztyping.Iterableztyping.Iteratorztyping.Generatorztyping.Reversibleztyping.Containerztyping.Collectionztyping.AbstractSetztyping.MutableSetztyping.Mappingztyping.MutableMappingztyping.Sequenceztyping.MutableSequenceztyping.ByteStringztyping.MappingViewztyping.KeysViewztyping.ItemsViewztyping.ValuesViewztyping.ContextManagerztyping.AsyncContextManagerztyping.Hashableztyping.Sizednodeastroid.ClassDefreturnboolc                ^   |                                  D ]9}t          |          r dS |                                t          t          fv r dS :| j        sdS t          |                                 j                  }| j        j	        D ]}t          |t          j                  r|j        }t          |t          j        t          j        f          sJt          |t          j                  r|j        }n|j        }|t$          v r&|                    t$                    s	t(          |v r dS dS )z7Check if a class is exempt from too-few-public-methods.TF)	ancestorsr	   qnameTYPING_NAMEDTUPLETYPING_TYPEDDICT
decoratorssetrootlocalsr   
isinstanceastroidCallfuncName	AttributenameattrnameDATACLASSES_DECORATORSintersectionDATACLASS_IMPORT)r%   ancestorroot_locals	decoratorr8   s        ?lib/python3.11/site-packages/pylint/checkers/design_analysis.py_is_exempt_from_public_methodsrA      s;    NN$$  8 	44>> 13CDD 	44	 ? udiikk())K_*  	i.. 	'!I)glG4E%FGG 	i.. 	&>DD%D)) 	$$%;<<	;.	 445    bool_opnodes.BoolOpintc                    d}|                                  D ]4}t          |t          j                  r|t	          |          z  }/|dz  }5|S )zCounts the number of boolean expressions in BoolOp `bool_op` (recursive).

    example: a and (b or c or (d and e)) ==> 5 boolean expressions
    r      )get_childrenr2   r3   BoolOp_count_boolean_expressions)rC   nb_bool_expr	bool_exprs      r@   rJ   rJ      s_    
 L))++  	i00 	6yAAALLALLrB   nodes.ClassDefc                    t          d |                                 D                       }|                                 D ]1}t                              |j                  r|j        dk    r|dz  }2|S )Nc              3  N   K   | ] }|j                             d           dV  !dS _rG   Nr8   
startswith.0methods     r@   	<genexpr>z*_count_methods_in_class.<locals>.<genexpr>   s8      XXFFK<R<RSV<W<WXaXXXXXXrB   __init__rG   )summethods	mymethodsSPECIAL_OBJsearchr8   )r%   all_methodsrV   s      r@   _count_methods_in_classr_      sx    XXdllnnXXXXXK ..""  fk** 	v{j/H 	1KrB   ignored_parentsfrozenset[str]Iterator[nodes.ClassDef]c              #  Z  K   t                      }t          |                     d                    }|ru|                                }|                                |v r-||vrB|V  |                    |           |                    |                    d                     |sdS dS )a  Get parents of ``node``, excluding ancestors of ``ignored_parents``.

    If we have the following inheritance diagram:

             F
            /
        D  E
         \/
          B  C
           \/
            A      # class A(B, C): ...

    And ``ignored_parents`` is ``{"E"}``, then this function will return
    ``{A, B, C, D}`` -- both ``E`` and its ancestors are excluded.
    F)recursN)r/   listr*   popr+   addextend)r%   r`   parents
to_exploreparents        r@   _get_parents_iterrl      s      $ $'55GdnnEn2233J
 >!!<<>>_, 	  		> LLLKKf..e.<<===  > > > > >rB   set[nodes.ClassDef]c                <    t          t          | |                    S N)r/   rl   )r%   r`   s     r@   _get_parentsrp   	  s      77888rB   c                  4    e Zd ZdZdZeZddddddfd	d
ddddfddddddfddddddfddddddfddddddfddddddfddddddfd d!ddd"dfd#d$ddd%dfd&dddd'dfd(g d)d*d+dffZdW fd0ZdXd1Z	dYd3Z
 ed4d5d6d7          dZd:            Z ed6d7          dZd;            Z ed<d=d>d?d@dA          d[dC            ZeZ ed<d=d>d?d@          d[dD            ZeZd\dGZd]dIZd^dKZd_dMZ edNd=          d`dP            Zd`dQZdadSZeZdbdcdVZ xZS )dMisdesignCheckerzChecker of potential misdesigns.

    Checks for sign of poor/misdesign:
    * number of methods, attributes, local variables...
    * size, complexity of functions, methods
    designzmax-args   rE   z<int>z2Maximum number of arguments for function / method.)defaulttypemetavarhelpz
max-locals   z4Maximum number of locals for function / method body.zmax-returns   z<Maximum number of return / yield for function / method body.zmax-branches   z4Maximum number of branch for function / method body.zmax-statements2   z7Maximum number of statements in function / method body.zmax-parents   z<num>z2Maximum number of parents for a class (see R0901).zignored-parents csvz%<comma separated list of class names>zOList of qualified class names to ignore when counting class parents (see R0901)zmax-attributesz5Maximum number of attributes for a class (see R0902).zmin-public-methods   z9Minimum number of public methods for a class (see R0903).zmax-public-methods   z9Maximum number of public methods for a class (see R0904).zmax-bool-exprzEMaximum number of boolean expressions in an if statement (see R0916).zexclude-too-few-public-methods
regexp_csvz<pattern>[,<pattern>...]zfList of regular expressions of class ancestor names to ignore when counting public methods (see R0903)linterr   r'   Nonec                V    t                                          |           |  |  |  d S ro   )superrX   )selfr   	__class__s     r@   rX   zMisdesignChecker.__init__  s3        @rB   c                    | j         j                                         g | _        t	          t
                    | _        g | _        | j         j        j	        | _
        dS )zInitialize visit variables.N)r   statsreset_node_count_returnsr   rE   	_branches_stmtsconfigexclude_too_few_public_methods_exclude_too_few_public_methods)r   s    r@   openzMisdesignChecker.open  sO    **,,,$S))K= 	,,,rB   amountc                d    t          | j                  D ]\  }}| j        |xx         |z  cc<   d S ro   )	enumerater   )r   r   irQ   s       r@   _inc_all_stmtszMisdesignChecker._inc_all_stmts  sC    dk** 	% 	%DAqKNNNf$NNNN	% 	%rB   r   r   r   r   r%   rM   c                   t          |t                              | j        j        j                            }t          |          }|| j        j        j        k    r)|                     d||| j        j        j        f           t          |j	                  | j        j        j
        k    r=|                     d|t          |j	                  | j        j        j
        f           dS dS )zFCheck size of inheritance hierarchy and number of instance attributes.r   r%   argsr   N)rp   STDLIB_CLASSES_IGNORE_ANCESTORunionr   r   r`   lenmax_parentsadd_messageinstance_attrsmax_attributes)r   r%   ri   
nb_parentss       r@   visit_classdefzMisdesignChecker.visit_classdef  s     *001C1STT
 
 \\
*66 	$ $+"4"@A     t"##dk&8&GG 	.$-..0B0QR      	 	rB   c                H   t          d |                                D                       }|| j        j        j        k    r)|                     d||| j        j        j        f           |j        dk    rA| j        r:|                                D ]%t          fd| j        D                       r dS &|j        dk    st          |          rdS t          |          }|| j        j        j        k     r+|                     d||| j        j        j        f           dS dS )zCheck number of public methods.c              3  N   K   | ] }|j                             d           dV  !dS rP   rR   rT   s     r@   rW   z2MisdesignChecker.leave_classdef.<locals>.<genexpr>  sK       
 
FK4J4J34O4O

 
 
 
 
 
rB   r   r   classc              3  f   K   | ]+}|                                                               V  ,d S ro   )matchr+   )rU   patternr=   s     r@   rW   z2MisdesignChecker.leave_classdef.<locals>.<genexpr>  sM         MM(.."2"233     rB   Nr   )rY   r[   r   r   max_public_methodsr   rv   r   r*   anyrA   r_   min_public_methods)r   r%   
my_methodsr^   r=   s       @r@   leave_classdefzMisdesignChecker.leave_classdef  s     
 
 NN,,
 
 
 
 

 *== 	) $+"4"GH     9 	D$H 	 NN,,      #'#G      FF	 9 	#A$#G#G 	F
 .d33+>> 	(!4;#5#HI      	 	rB   r   r   r   r   r   zkeyword-arg-before-varargnodes.FunctionDefc                r   | j                             d           |j        j        }| j        j        j        |}d}rt          fd|D                       }t          |          |z
  }|| j        j        j        k    r6| 	                    d|t          |          | j        j        j        f           nd}t          |j
                  |z
  }d|j
        v r|dz  }|| j        j        j        k    r)| 	                    d||| j        j        j        f           | j                            d           dS )	zeCheck function name, docstring, arguments, redefinition,
        variable names, max locals.
        r   Nc              3  P   K   | ] }                     |j                  d V  !dS )rG   N)r   r8   )rU   argignored_argument_namess     r@   rW   z5MisdesignChecker.visit_functiondef.<locals>.<genexpr>  sM       ' ')?)E)Ech)O)O'' ' ' ' ' 'rB   r   r   rQ   rG   r   )r   appendr   r   r   r   rY   r   max_argsr   r1   
max_localsr   )r   r%   r   ignored_args_numargnumlocnumr   s         @r@   visit_functiondefz"MisdesignChecker.visit_functiondef  s}    	Qy~!%!3!J 	! % #& ' ' ' '!%' ' ' $ $  YY!11F*33   (d))T[%7%@A !     !T[!!$44 $+ 	aKFDK&11 	!dk0;<     	1rB   c                   | j                                         }|| j        j        j        k    r)|                     d||| j        j        j        f           | j        |         }|| j        j        j        k    r)|                     d||| j        j        j        f           | j                                        }|| j        j        j	        k    r+|                     d||| j        j        j	        f           dS dS )zlMost of the work is done here on close:
        checks for max returns, branch, return in __init__.
        r   r   r   r   N)
r   rf   r   r   max_returnsr   r   max_branchesr   max_statements)r   r%   returnsbranchesstmtss        r@   leave_functiondefz"MisdesignChecker.leave_functiondef!  s$    -##%%T['33 	,t{1=>    
 >$'dk(55 	# 2 ?@     !!4;%44 	%T[/>?      	 	rB   rQ   nodes.Returnc                B    | j         sdS | j         dxx         dz  cc<   dS )zCount number of returns.NrG   )r   )r   rQ   s     r@   visit_returnzMisdesignChecker.visit_returnE  s5    } 	FbQrB   nodes.NodeNGc                B    |j         r|                     d           dS dS )zXDefault visit method -> increments the statements counter if
        necessary.
        rG   N)is_statementr   r   r%   s     r@   visit_defaultzMisdesignChecker.visit_defaultK  s3      	#"""""	# 	#rB   nodes.TryExceptc                    t          |j                  }|j        r|dz  }|                     ||           |                     |           dS  Increments the branches counter.rG   N)r   handlersorelse_inc_branchr   r   r%   r   s      r@   visit_tryexceptz MisdesignChecker.visit_tryexceptR  sT    t}%%; 	MHx(((H%%%%%rB   nodes.TryFinallyc                \    |                      |d           |                     d           dS )r   r   N)r   r   r   s     r@   visit_tryfinallyz!MisdesignChecker.visit_tryfinallyZ  s2    q!!!ArB   r   nodes.Ifc                   |                      |           d}|j        rBt          |j                  dk    s%t          |j        d         t          j                  s|dz  }|                     ||           |                     |           dS )z?Increments the branches counter and checks boolean expressions.rG   r   N)_check_boolean_expressionsr   r   r2   r3   Ifr   r   r   s      r@   visit_ifzMisdesignChecker.visit_if_  s     	''---; 	q 	(24;q>7:(N(N	 MHx(((H%%%%%rB   c                    |j         }t          |t          j                  sdS t	          |          }|| j        j        j        k    r+|                     d||| j        j        j        f           dS dS )zvGo through "if" node `node` and count its boolean expressions
        if the 'if' node test is a BoolOp node.
        Nr   r   )	testr2   r3   rI   rJ   r   r   max_bool_exprr   )r   r%   	conditionrK   s       r@   r   z+MisdesignChecker._check_boolean_expressionsl  s     I	)W^44 	F1)<<$+,:: 	."DK$6$DE      	 	rB   nodes.Whilec                N    d}|j         r|dz  }|                     ||           dS r   )r   r   r   s      r@   visit_whilezMisdesignChecker.visit_while{  s6    ; 	MHx(((((rB   rG   branchesnumc                T    | j         |                                xx         |z  cc<   dS )r   N)r   scope)r   r%   r   s      r@   r   zMisdesignChecker._inc_branch  s.    tzz||$$$3$$$$$rB   r   r   r'   r   )r'   r   )r   rE   r'   r   )r%   rM   r'   r   )r%   r   r'   r   )rQ   r   r'   r   )r%   r   r'   r   )r%   r   r'   r   )r%   r   r'   r   )r%   r   r'   r   )r%   r   r'   r   )rG   )r%   r   r   rE   r'   r   )__name__
__module____qualname____doc__r8   r!   msgsoptionsrX   r   r   r
   r   r   r   visit_asyncfunctiondefr   leave_asyncfunctiondefr   r   r   r   r   r   r   	visit_forr   __classcell__)r   s   @r@   rr   rr     s         DD "L	 	
 "N	 	
 "	 		
 "N	 	
 "Q	 	
 "L	 	
 Bi	 	
 "	 		
 !"	 		
 !"	 		
 ")	 		
 -$5E	 		
SsGj     
 
 
 
% % % %  & !	    *   8:STT+ + + UT+Z  $# ' ' ' 'R /$    6 /   # # # #& & & &   
   >@STT
& 
& 
& UT
&   ) ) ) ) I4 4 4 4 4 4 4 4 4rB   rr   r   r   r   c                J    |                      t          |                      d S ro   )register_checkerrr   )r   s    r@   registerr     s%    
,V4455555rB   )r%   r&   r'   r(   )rC   rD   r'   rE   )r%   rM   r'   rE   )r%   rM   r`   ra   r'   rb   )r%   rM   r`   ra   r'   rm   r   )&r   
__future__r   recollectionsr   collections.abcr   typingr   r3   r   pylint.checkersr   pylint.checkers.utilsr	   r
   pylint.typingr   pylint.lintr   r!   __annotations__compiler\   	frozensetr:   r<   r,   r-   r   rA   rJ   r_   rl   rp   rr   r   r~   rB   r@   <module>r     s8  
 & % % " " " " " " 				 # # # # # # $ $ $ $ $ $                    ' ' ' ' ' ' E E E E E E E E 0 0 0 0 0 0 %$$$$$$


k: :  < < < <z bj+,,"K#9::   ' %  "+LN" N" b   @      !> !> !> !>H9 9 9 9w4 w4 w4 w4 w4{ w4 w4 w4t6 6 6 6 6 6rB   