
    ~h*                         d dl Z d dlZd dlmZ ddlmZmZmZ  e e	e            Z
 G d de j                        Zd
deddfd	Zy)    N)zip_longest   )BASE_BUILTIN_MODULES
get_sourceis_valid_namec                       e Zd ZdZddee   defdZd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)MethodCheckerz
    Checks that a method
    - only uses defined names
    - contains no local imports (e.g. numpy is ok but local_script is not)
    class_attributescheck_importsc                     t               | _        i | _        i | _        t               | _        t               | _        || _        g | _        || _        dh| _	        t               | _
        y )NAny)setundefined_namesimportsfrom_importsassigned_names	arg_namesr
   errorsr   typing_namesdefined_classes)selfr
   r   s      V/opt/mcp/mcp-sentiment/venv/lib/python3.12/site-packages/smolagents/tool_validation.py__init__zMethodChecker.__init__   sY    "u!e 0*"G"u    c                 N   |j                   D ch c]  }|j                   c}| _        |j                  r/| j                  j	                  |j                  j                         |j
                  r0| j                  j	                  |j
                  j                         yyc c}w )zCollect function argumentsN)argsargr   kwargaddvararg)r   noder   s      r   visit_argumentszMethodChecker.visit_arguments   sh    -1YY7c#''7::NNtzz~~.;;NNt{{/  8s   B"c                     |j                   D ]5  }|j                  xs |j                  }|j                  | j                  |<   7 y N)namesasnamenamer   )r   r!   r'   actual_names       r   visit_ImportzMethodChecker.visit_Import&   s9    JJ 	2D++2K(,		DLL%	2r   c                     |j                   xs d}|j                  D ]7  }|j                  xs |j                  }||j                  f| j                  |<   9 y )N )moduler%   r&   r'   r   )r   r!   r,   r'   r(   s        r   visit_ImportFromzMethodChecker.visit_ImportFrom+   sP    "JJ 	AD++2K.4dii-@Dk*	Ar   c                    |j                   D ]  }t        |t        j                        r&| j                  j                  |j                         Ct        |t        j                  t        j                  f      sn|j                  D ]B  }t        |t        j                        s| j                  j                  |j                         D  | j                  |j                         y r$   )targets
isinstanceastNamer   r   idTupleListeltsvisitvaluer   r!   targetelts       r   visit_AssignzMethodChecker.visit_Assign1   s    ll 	8F&#((+##''		2FSYY$9:!;; 8C!#sxx0++//78		8 	

4::r   c                 
   |j                   D ]c  }|j                  st        |j                  t        j                        s5| j
                  j                  |j                  j                         e | j                  |       y)z=Track aliases in 'with' statements (the 'y' in 'with X as y')N)	itemsoptional_varsr0   r1   r2   r   r   r3   generic_visit)r   r!   items      r   
visit_WithzMethodChecker.visit_With;   sd    JJ 	CD!!d00#((;''++D,>,>,A,AB	C 	4 r   c                     |j                   r%| j                  j                  |j                          | j                  |       y)z<Track exception aliases (the 'e' in 'except Exception as e')N)r'   r   r   r@   r   r!   s     r   visit_ExceptHandlerz!MethodChecker.visit_ExceptHandlerC   s/    99##DII.4 r   c                     t        |j                  t        j                        r/| j                  j                  |j                  j                         |j                  r| j                  |j                         yy)zTrack annotated assignments.N)	r0   r:   r1   r2   r   r   r3   r8   r7   rD   s     r   visit_AnnAssignzMethodChecker.visit_AnnAssignI   sL    dkk388,##DKKNN3::JJtzz" r   c                    |j                   }t        |t        j                        r&| j                  j                  |j                         nkt        |t        j                        rQ|j                  D ]B  }t        |t        j                        s| j                  j                  |j                         D | j                  |       y r$   )
r:   r0   r1   r2   r   r   r3   r4   r6   r@   r9   s       r   	visit_ForzMethodChecker.visit_ForP   s    fchh'##FII.		*{{ 4c388,''++CFF34 	4 r   c                    |D ]  }t        |j                  t        j                        r0| j                  j                  |j                  j                         Wt        |j                  t        j                        s||j                  j                  D ]B  }t        |t        j                        s| j                  j                  |j                         D  y)zAHelper method to handle generators in all types of comprehensionsN)	r0   r:   r1   r2   r   r   r3   r4   r6   )r   
generators	generatorr;   s       r    _handle_comprehension_generatorsz.MethodChecker._handle_comprehension_generatorsZ   s    # 	8I)**CHH5##''	(8(8(;(;<I,,cii8$++00 8C!#sxx0++//78		8r   c                 \    | j                  |j                         | j                  |       y)z&Track variables in list comprehensionsNrM   rK   r@   rD   s     r   visit_ListCompzMethodChecker.visit_ListCompd   "    --doo>4 r   c                 \    | j                  |j                         | j                  |       y)z,Track variables in dictionary comprehensionsNrO   rD   s     r   visit_DictCompzMethodChecker.visit_DictCompi   rQ   r   c                 \    | j                  |j                         | j                  |       y)z%Track variables in set comprehensionsNrO   rD   s     r   visit_SetCompzMethodChecker.visit_SetCompn   rQ   r   c                     t        |j                  t        j                        r|j                  j                  dk(  s| j                  |       y y Nr   )r0   r8   r1   r2   r3   r@   rD   s     r   visit_AttributezMethodChecker.visit_Attributes   s7    4::sxx0TZZ]]f5Lt$ 6Mr   c                 p    | j                   j                  |j                         | j                  |       y)zTrack class definitionsN)r   r   r'   r@   rD   s     r   visit_ClassDefzMethodChecker.visit_ClassDefw   s(      +4 r   c                 l   t        |j                  t        j                        r|j                  t
        v s|j                  t        v s|j                  | j                  v s|j                  dk(  s|j                  | j                  v s|j                  | j                  v s|j                  | j                  v su|j                  | j                  v s\|j                  | j                  v sC|j                  | j                  v s*| j                  j                  d|j                   d       y y y y y y y y y y y y Nr   zName 'z' is undefined.)r0   ctxr1   Loadr3   _BUILTIN_NAMESr   r   r
   r   r   r   r   r   r   appendrD   s     r   
visit_NamezMethodChecker.visit_Name|   s	   dhh)>)772277dnn,77f$77d33377dll*77d///77d11177d///77d222""VDGG9O#DE 3 0 2 0 + 4 % - 3 * *r   c                    t        |j                  t        j                        rR|j                  j                  t
        v s5|j                  j                  t        v s|j                  j                  | j                  v s|j                  j                  dk(  s|j                  j                  | j                  v s|j                  j                  | j                  v s|j                  j                  | j                  v sw|j                  j                  | j                  v sU|j                  j                  | j                  v s3| j                  j                  d|j                  j                   d       | j                  |       y r\   )r0   funcr1   r2   r3   r_   r   r   r
   r   r   r   r   r   r`   r@   rD   s     r   
visit_CallzMethodChecker.visit_Call   s    dii*		.99<<#7799<<4>>199<<6)99<<4#8#8899<<4<</99<<4#4#4499<<4#6#6699<<4#7#77""VDIILL>#IJ4 r   NT)__name__
__module____qualname____doc__r   strboolr   r"   r)   r-   r<   rB   rE   rG   rI   rM   rP   rS   rU   rX   rZ   ra   rd    r   r   r	   r	      sp    
%S 
%$ 
%02
A!!#!8!
!
!
%!
F !r   r	   r   returnc           	          G d dt         j                        } |       }t        |       }t        j                  |      }|j                  d   }t        |t         j                        st        d      |j                  |       g }|j                  r||j                  z  }|j                  r-|j                  ddj                  |j                                |j                  r-|j                  ddj                  |j                                |j                  r-|j                  ddj                  |j                                |j                  D ]r  }t        |t         j                        st!        |j"                  |	      }	|	j                  |       ||	j$                  D 
cg c]  }
d
|j&                   d|
  c}
z  }t |r+t        d| j(                   ddj                  |      z         yc c}
w )aa  
    Validates that a Tool class follows the proper patterns:
    0. Any argument of __init__ should have a default.
    Args chosen at init are not traceable, so we cannot rebuild the source code for them, thus any important arg should be defined as a class attribute.
    1. About the class:
        - Class attributes should only be strings or dicts
        - Class attributes cannot be complex attributes
    2. About all class methods:
        - Imports must be from packages, not local files
        - All methods must be self-contained

    Raises all errors encountered, if no error returns None.
    c                   $    e Zd Zd Zd Zd Zd Zy)3validate_tool_attributes.<locals>.ClassLevelCheckerc                     t               | _        t               | _        t               | _        t               | _        t               | _        d| _        g | _        y )NF)r   imported_namescomplex_attributesr
   non_defaultsnon_literal_defaults	in_methodinvalid_attributes)r   s    r   r   z<validate_tool_attributes.<locals>.ClassLevelChecker.__init__   sC    "%%D&)eD#$'ED! #D(+D%"DN&(D#r   c                     |j                   dk(  r| j                  |       | j                  }d| _        | j                  |       || _        y )Nr   T)r'   _check_init_function_parametersrv   r@   )r   r!   old_contexts      r   visit_FunctionDefzEvalidate_tool_attributes.<locals>.ClassLevelChecker.visit_FunctionDef   sA    yyJ&44T:..K!DNt$(DNr   c                    | j                   ry |j                  D ]B  }t        |t        j                        s| j
                  j                  |j                         D t        d t        j                  |j                        D              sQ|j                  D ]B  }t        |t        j                        s| j                  j                  |j                         D t        |j                  d   dd      dk(  rt        |j                  t        j                        s*| j                  j                  d|j                   d       y t        |j                  j                  t               s4| j                  j                  d|j                  j                   d       y t#        |j                  j                        s4| j                  j                  d	|j                  j                   d       y y y )
Nc           
   3      K   | ]j  }t        |t        j                  t        j                  t        j                  t        j
                  t        j                  t        j                  f       l y wr$   )r0   r1   StrNumConstantDictr5   Set).0vals     r   	<genexpr>zSvalidate_tool_attributes.<locals>.ClassLevelChecker.visit_Assign.<locals>.<genexpr>   sG       3#''3<<388UXU\U\ ]^s   A0A2r   r3   r+   r'   z2Class attribute 'name' must be a constant, found ''z0Class attribute 'name' must be a string, found 'z\Class attribute 'name' must be a valid Python identifier and not a reserved keyword, found ')rv   r/   r0   r1   r2   r
   r   r3   allwalkr8   rs   getattrr   rw   r`   rj   r   )r   r!   r:   s      r   r<   z@validate_tool_attributes.<locals>.ClassLevelChecker.visit_Assign   s   ~~,, 9fchh/))--fii89
  88DJJ/  #ll ?F!&#((3//33FII>?
 t||Ab1V;!$**cll;++225ghlhrhrgsst3uv#DJJ$4$4c:++22J4::K[K[J\\]^ 'tzz'7'78++22vw{  xB  xB  xH  xH  wI  IJ  K 9 <r   c           
      L   t        t        t        t        |j                  j                        t        |j                  j                                          D ]  \  }}|6|j
                  dk7  s| j                  j                  |j
                         >t        |t        j                  t        j                  t        j                  t        j                  t        j                  t        j                  f      r| j                   j                  |j
                          y rW   )reversedlistr   r   defaultsr   rt   r   r0   r1   r~   r   r   r   r5   r   ru   )r   r!   r   defaults       r   ry   zSvalidate_tool_attributes.<locals>.ClassLevelChecker._check_init_function_parameters   s     (k(499>>:RT\]a]f]f]o]oTp.q)r s ;W?ww&())--cgg6#GcggswwchhX[X`X`bebibi-jk--11#'':;r   N)rf   rg   rh   r   r{   r<   ry   rl   r   r   ClassLevelCheckerrp      s    	)	)	<	;r   r   r   zSource code must define a classzKComplex attributes should be defined in __init__, not as class attributes: z, zLParameters in __init__ must have default values, found required parameters: zUParameters in __init__ must have literal default values, found non-literal defaults: )r   z- z: zTool validation failed for z:

N)r1   NodeVisitorr   parsebodyr0   ClassDef
ValueErrorr7   rw   rs   r`   joinrt   ru   FunctionDefr	   r
   r   r'   rf   )clsr   r   class_level_checkersourcetree
class_noder   r!   method_checkererrors              r   validate_tool_attributesr      s   7;COO 7;r ,-_F99VD1Jj#,,/:;;j)F--%888--Yyy,??@AC	
 ''Zyy,99:;=	
 //cyy,AABCE	
  UdCOO,*+>+O+O_lmN  &n>S>STUDII;b0TTF	U 6s||nCH499U[K\\]]
	 Us   /G=re   )r1   builtins	itertoolsr   utilsr   r   r   r   varsr_   r   r	   rk   r   rl   r   r   <module>r      sM    
  ! B B T(^$O!COO O!dm m mr   