U
    hg?                     @  s  d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	m
Z
mZmZ ddlmZ ddlmZ eeeef Zeeejeee	eegef f e
e ejejf Ze	egef Zddd	d
dZdddddZejddG dd dejZd(ddddddddZG dd dejZ G dd dejZ!G dd dejZ"ejddG d d! d!eZ#G d"d# d#e#Z$G d$d% d%eZ%ejddG d&d' d'eZ&dS ))aY  Classes that define arguments for populating ArgumentParser.

The argparse module's ArgumentParser.add_argument() takes several parameters and
is quite customizable. However this can lead to bugs where arguments do not
behave as expected.

For better ease-of-use and better testability, define a set of classes for the
types of flags used by LLM Magics.

Sample usage:

  str_flag = SingleValueFlagDef(name="title", required=True)
  enum_flag = EnumFlagDef(name="colors", required=True, enum_type=ColorsEnum)

  str_flag.add_argument_to_parser(my_parser)
  enum_flag.add_argument_to_parser(my_parser)
    )annotationsN)AnyCallableSequenceUnionTuple)llmfn_inputs_source)llmfn_outputs	type[Any]str)xreturnc                 C  s*   z| j W S  tk
r$   t|  Y S X d S N)__name__AttributeErrorr   r    r   I/tmp/pip-unpacked-wheel-doshhd5e/google/generativeai/notebook/flag_def.py_get_type_name?   s    r   )namer   c                 C  s$   | st d| d dkr t d| S )z.Validation for long and short names for flags.zCannot be emptyr   -zCannot start with dash)
ValueError)r   r   r   r   _validate_flag_nameF   s
    r   T)frozenc                   @  s   e Zd ZU dZded< dZded< dZded	< eZd
ed< dZ	ded< dZ
ded< dZded< dZded< ejdddddZejddddZddddZdddd Zd!d" ZdS )#FlagDefa  Abstract base class for flag definitions.

  Attributes:
    name: Long name, e.g. "colors" will define the flag "--colors".
    required: Whether the flag must be provided on the command line.
    short_name: Optional short name.
    parse_type: The type that ArgumentParser should parse the command line
      argument to.
    dest_type: The type that the parsed value is converted to. This is used when
      we want ArgumentParser to parse as one type, then convert to a different
      type. E.g. for enums we parse as "str" then convert to the desired enum
      type in order to provide cleaner help messages.
    parse_to_dest_type_fn: If provided, this function will be used to convert
      the value from `parse_type` to `dest_type`. This can be used for
      validation as well.
    choices: If provided, limit the set of acceptable values to these choices.
    help_msg: If provided, adds help message when -h is used in the command
      line.
  r   r   FboolrequiredN
str | None
short_nameztype[_PARSETYPES]
parse_typeztype[_DESTTYPES] | None	dest_typez_PARSEFN | Noneparse_to_dest_type_fnzlist[_PARSETYPES] | Nonechoiceshelp_msgargparse.ArgumentParserNoneparserr   c                 C  s   dS )zAdds this flag as an argument to `parser`.

    Child classes should implement this as a call to parser.add_argument()
    with the appropriate parameters.

    Args:
      parser: The parser to which this argument will be added.
    Nr   )selfr'   r   r   r   add_argument_to_parserq   s    zFlagDef.add_argument_to_parserr   c                 C  s   dS )z.For child classes to do additional validation.Nr   r(   r   r   r   _do_additional_validation|   s    z!FlagDef._do_additional_validationztype[_DESTTYPES]c                 C  s   | j dkr| jS | j S )z!Returns the final converted type.N)r    r   r+   r   r   r   _get_dest_type   s    zFlagDef._get_dest_type_PARSEFNc                 C  s2   | j dk	r| j S |  }|| jkr*dd S |S dS )z;Returns a function to convert from parse_type to dest_type.Nc                 S  s   | S r   r   r   r   r   r   <lambda>       z4FlagDef._get_parse_to_dest_type_fn.<locals>.<lambda>)r!   r-   r   )r(   r    r   r   r   _get_parse_to_dest_type_fn   s    

z"FlagDef._get_parse_to_dest_type_fnc                 C  s*   t | j | jd k	rt | j |   d S r   )r   r   r   r,   r+   r   r   r   __post_init__   s    


zFlagDef.__post_init__)r   
__module____qualname____doc____annotations__r   r   r   r   r    r!   r"   r#   abcabstractmethodr)   r,   r-   r1   r2   r   r   r   r   r   O   s    

r   Fargparse.Namespacer   r   )	namespacedesthas_defaultdefault_valuer   c                 C  s$   t | |sdS |sdS t| ||kS )a  Returns true if `namespace.dest` is set to a non-default value.

  Args:
    namespace: The Namespace that is populated by ArgumentParser.
    dest: The attribute in the Namespacde to be populated.
    has_default: "None" is a valid default value so we use an additional
      `has_default` boolean to indicate that `default_value` is present.
    default_value: The default value to use when `has_default` is True.

  Returns:
    Whether namespace.dest is set to something other than the default value.
  FT)hasattrgetattr)r:   r;   r<   r=   r   r   r   _has_non_default_value   s
    
r@   c                      s>   e Zd ZdZddd fddZddd	d
ddddZ  ZS )_SingleValueStoreActionz}Custom Action for storing a value in an argparse.Namespace.

  This action checks that the flag is specified at-most once.
  r
   r.   r    r!   c                   s"   t  j||f| || _|| _d S r   super__init__
_dest_type_parse_to_dest_type_fnr(   option_stringsr;   r    r!   kwargs	__class__r   r   rE      s    z _SingleValueStoreAction.__init__Nr$   r9   str | Sequence[Any] | Noner   r'   r:   valuesoption_stringc                 C  s   t |tst |trtt|| jt| dt| ddrHt	| d
|z| |d }W nD tk
r } z&t	| d
|d tt||W 5 d }~X Y nX t || jstd
t| jtt|t|| j| d S )Ndefaultr<   r=   Cannot set {} more than oncer   !Error with value "{}", got {}: {}+Converted to wrong type, expected {} got {})
isinstancer   bytesAssertionErrorr@   r;   r>   r?   argparseArgumentErrorformatrG   	Exceptionr   typerF   RuntimeErrorsetattr)r(   r'   r:   rO   rP   converted_valueer   r   r   __call__   s<    	  
 
z _SingleValueStoreAction.__call__)Nr   r3   r4   r5   rE   rb   __classcell__r   r   rK   r   rA      s    rA   c                      s>   e Zd ZdZddd fddZddd	d
ddddZ  ZS )_MultiValuesAppendActionz~Custom Action for appending values in an argparse.Namespace.

  This action checks that the flag is specified at-most once.
  r
   r.   rB   c                   s"   t  j||f| || _|| _d S r   rC   rH   rK   r   r   rE      s    z!_MultiValuesAppendAction.__init__Nr$   r9   rM   r   rN   c           	      C  s   t |tst |trtt|| j}|r:t| d||D ]}z| 	|}W nD t
k
r } z&t| d|d tt||W 5 d }~X Y nX t || jstd| jt|||krt| d||| q>d S )NrS   rT   r   rU   zDuplicate values "{}")rV   r   rW   rX   r?   r;   rY   rZ   r[   rG   r\   r   r]   rF   r^   append)	r(   r'   r:   rO   rP   Z
curr_valuevaluer`   ra   r   r   r   rb     s@    	  
   z!_MultiValuesAppendAction.__call__)Nrc   r   r   rK   r   re      s    re   c                      s6   e Zd ZdZ fddZdddddd	d
dZ  ZS )_BooleanValueStoreActionzCustom Action for setting a boolean value in argparse.Namespace.

  The boolean flag expects the default to be False and will set the value to
  True.
  This action checks that the flag is specified at-most once.
  c                   s   t  j||f| d S r   )rD   rE   )r(   rI   r;   rJ   rK   r   r   rE   5  s    z!_BooleanValueStoreAction.__init__Nr$   r9   rM   r   rN   c                 C  s6   t || jdddr$t| d|t|| jd d S )NTFrR   rS   )r@   r;   rY   rZ   r[   r_   )r(   r'   r:   rO   rP   r   r   r   rb   =  s     z!_BooleanValueStoreAction.__call__)Nrc   r   r   rK   r   rh   -  s    rh   c                   @  s^   e Zd ZU dZG dd dejZejZde	d< dddd	Z
d
ddddZddddZdS )SingleValueFlagDefa_  Definition for a flag that takes a single value.

  Sample usage:
    # This defines a flag that can be specified on the command line as:
    #   --count=10
    flag = SingleValueFlagDef(name="count", parse_type=int, required=True)
    flag.add_argument_to_parser(argument_parser)

  Attributes:
    default_value: Default value for optional flags.
  c                   @  s   e Zd ZdZdZdS )z SingleValueFlagDef._DefaultValuezSpecial value to represent "no value provided".

    "None" can be used as a default value, so in order to differentiate between
    "None" and "no value provided", create a special value for "no value
    provided".
    N)r   r3   r4   r5   NOT_SETr   r   r   r   _DefaultValue_  s   rk   z!_DESTTYPES | _DefaultValue | Noner=   r   r*   c                 C  s   | j tjjkS )z2Returns whether `default_value` has been provided.)r=   ri   rk   rj   r+   r   r   r   _has_default_valuek  s    z%SingleValueFlagDef._has_default_valuer$   r%   r&   c              	   C  s   d| j  g}| jd k	r&|d| j g7 }i }|  r<| j|d< | jd k	rP| j|d< | jd k	rd| j|d< |j|t| j| 	 | 
 | jdd| d S )N--r   rQ   r"   help   )actionr]   r    r!   r   nargs)r   r   rl   r=   r"   r#   add_argumentrA   r   r-   r1   r   r(   r'   argsrJ   r   r   r   r)   o  s*    





z)SingleValueFlagDef.add_argument_to_parserc                 C  sV   | j r|  r(tdn|  s(td|  rR| jd k	rRt| j|  sRtdd S )Nz(Required flags cannot have default valuez(Optional flags must have a default valuez>Default value must be of the same type as the destination type)r   rl   r   r=   rV   r-   r+   r   r   r   r,     s    
z,SingleValueFlagDef._do_additional_validationN)r   r3   r4   r5   enumEnumrk   rj   r=   r6   rl   r)   r,   r   r   r   r   ri   Q  s   

ri   c                      s&   e Zd ZdZdd fddZ  ZS )EnumFlagDefaF  Definition for a flag that takes a value from an Enum.

  Sample usage:
    # This defines a flag that can be specified on the command line as:
    #   --color=red
    flag = SingleValueFlagDef(name="color", enum_type=ColorsEnum,
                              required=True)
    flag.add_argument_to_parser(argument_parser)
  ztype[enum.Enum])	enum_typec             	     s   t |tjstdd|kr$tdt|d< d|kr<td||d< d|kr|d D ]6}z|| W qT tk
r   td|d Y qTX qTndd	 |D |d< t j|| d S )
Nz "enum_type" must be of type Enumr   z@Cannot set "parse_type" for EnumFlagDef; set "enum_type" insteadr    z?Cannot set "dest_type" for EnumFlagDef; set "enum_type" insteadr"   z Invalid value in "choices": "{}"c                 S  s   g | ]
}|j qS r   )rg   ).0r   r   r   r   
<listcomp>  s     z(EnumFlagDef.__init__.<locals>.<listcomp>)	
issubclassru   rv   	TypeErrorr   r   r[   rD   rE   )r(   rx   rt   rJ   r   rK   r   r   rE     s0    zEnumFlagDef.__init__)r   r3   r4   r5   rE   rd   r   r   rK   r   rw     s   
rw   c                   @  s.   e Zd ZdZdddddZdddd	Zd
S )MultiValuesFlagDefa*  Definition for a flag that takes multiple values.

  Sample usage:
    # This defines a flag that can be specified on the command line as:
    #   --colors=red green blue
    flag = MultiValuesFlagDef(name="colors", parse_type=str, required=True)
    flag.add_argument_to_parser(argument_parser)
  r$   r%   r&   c              
   C  s   d| j  g}| jd k	r&|d| j g7 }i }| jd k	r>| j|d< | jd k	rR| j|d< |j|t| j|  |  | j	g dd| d S )Nrm   r   r"   rn   +)rp   r]   r    r!   r   rQ   rq   )
r   r   r"   r#   rr   re   r   r-   r1   r   rs   r   r   r   r)     s(    




	z)MultiValuesFlagDef.add_argument_to_parserr*   c                 C  s   d S r   r   r+   r   r   r   r,     s    z,MultiValuesFlagDef._do_additional_validationN)r   r3   r4   r5   r)   r,   r   r   r   r   r}     s   	r}   c                   @  s.   e Zd ZdZddddZddddd	Zd
S )BooleanFlagDefzDefinition for a Boolean flag.

  A boolean flag is always optional with a default value of False. The flag does
  not take any values. Specifying the flag on the commandline will set it to
  True.
  r%   r*   c                 C  s:   | j d k	rtd| jd k	r$td| jd k	r6tdd S )Nz*dest_type cannot be set for BooleanFlagDefz6parse_to_dest_type_fn cannot be set for BooleanFlagDefz(choices cannot be set for BooleanFlagDef)r    r   r!   r"   r+   r   r   r   r,     s    


z(BooleanFlagDef._do_additional_validationr$   r&   c                 C  s^   d| j  g}| jd k	r&|d| j g7 }i }| jd k	r>| j|d< |j|ttdddd| d S )Nrm   r   rn   Fr   )rp   r]   r   rQ   rq   )r   r   r#   rr   rh   r   rs   r   r   r   r)     s     


z%BooleanFlagDef.add_argument_to_parserN)r   r3   r4   r5   r,   r)   r   r   r   r   r     s   r   )FN)'r5   
__future__r   r7   rY   Zdataclassesru   typingr   r   r   r   r   Z google.generativeai.notebook.libr   r	   r   intfloatZ_PARSETYPESrv   ZLLMFnInputsSourceZLLMFnOutputsSinkZ
_DESTTYPESr.   r   r   Z	dataclassABCr   r@   ActionrA   re   rh   ri   rw   r}   r   r   r   r   r   <module>   sF   	
L  ;<$
D+&
