B
    de8                 @   s   d Z ddlZddlZddlmZ edddddd	hZG d
d dejZG dd dejZ	G dd dejZ
G dd dejZdd Zdd ZdS )a  This module provides argparse integration with absl.flags.

``argparse_flags.ArgumentParser`` is a drop-in replacement for
:class:`argparse.ArgumentParser`. It takes care of collecting and defining absl
flags in :mod:`argparse`.

Here is a simple example::

    # Assume the following absl.flags is defined in another module:
    #
    #     from absl import flags
    #     flags.DEFINE_string('echo', None, 'The echo message.')
    #
    parser = argparse_flags.ArgumentParser(
        description='A demo of absl.flags and argparse integration.')
    parser.add_argument('--header', help='Header message to print.')

    # The parser will also accept the absl flag `--echo`.
    # The `header` value is available as `args.header` just like a regular
    # argparse flag. The absl flag `--echo` continues to be available via
    # `absl.flags.FLAGS` if you want to access it.
    args = parser.parse_args()

    # Example usages:
    # ./program --echo='A message.' --header='A header'
    # ./program --header 'A header' --echo 'A message.'


Here is another example demonstrates subparsers::

    parser = argparse_flags.ArgumentParser(description='A subcommands demo.')
    parser.add_argument('--header', help='The header message to print.')

    subparsers = parser.add_subparsers(help='The command to execute.')

    roll_dice_parser = subparsers.add_parser(
        'roll_dice', help='Roll a dice.',
        # By default, absl flags can also be specified after the sub-command.
        # To only allow them before sub-command, pass
        # `inherited_absl_flags=None`.
        inherited_absl_flags=None)
    roll_dice_parser.add_argument('--num_faces', type=int, default=6)
    roll_dice_parser.set_defaults(command=roll_dice)

    shuffle_parser = subparsers.add_parser('shuffle', help='Shuffle inputs.')
    shuffle_parser.add_argument(
        'inputs', metavar='I', nargs='+', help='Inputs to shuffle.')
    shuffle_parser.set_defaults(command=shuffle)

    args = parser.parse_args(argv[1:])
    args.command(args)

    # Example usages:
    # ./program --echo='A message.' roll_dice --num_faces=6
    # ./program shuffle --echo='A message.' 1 2 3 4


There are several differences between :mod:`absl.flags` and
:mod:`~absl.flags.argparse_flags`:

1. Flags defined with absl.flags are parsed differently when using the
   argparse parser. Notably:

   1) absl.flags allows both single-dash and double-dash for any flag, and
      doesn't distinguish them; argparse_flags only allows double-dash for
      flag's regular name, and single-dash for flag's ``short_name``.
   2) Boolean flags in absl.flags can be specified with ``--bool``,
      ``--nobool``, as well as ``--bool=true/false`` (though not recommended);
      in argparse_flags, it only allows ``--bool``, ``--nobool``.

2. Help related flag differences:

   1) absl.flags does not define help flags, absl.app does that; argparse_flags
      defines help flags unless passed with ``add_help=False``.
   2) absl.app supports ``--helpxml``; argparse_flags does not.
   3) argparse_flags supports ``-h``; absl.app does not.
    N)flagshelpZ	helpshortZhelpfullZhelpxmlZflagfileundefokc                   s>   e Zd ZdZ fddZd fdd	Zdd Zd	d
 Z  ZS )ArgumentParserz:Custom ArgumentParser class to support special absl flags.c                s   | dd}|dkr"td||dtj| _tt| j	f | | j
rt| jddtjtjd | jdttjd	d | jr| jd
tjtjd | | j dS )a  Initializes ArgumentParser.

    Args:
      **kwargs: same as argparse.ArgumentParser, except:
          1. It also accepts `inherited_absl_flags`: the absl flags to inherit.
             The default is the global absl.flags.FLAGS instance. Pass None to
             ignore absl flags.
          2. The `prefix_chars` argument must be the default value '-'.

    Raises:
      ValueError: Raised when prefix_chars is not '-'.
    prefix_chars-zTargparse_flags.ArgumentParser only supports "-" as the prefix character, found "{}".Zinherited_absl_flagsz--helpshortr   )actiondefaultr   z
--helpfullzshow full help message and exitz	--undefok)r	   r   N)get
ValueErrorformatpopr   FLAGS_inherited_absl_flagssuperr   __init__add_helpadd_argumentargparseSUPPRESS_HelpFullAction_define_absl_flags)selfkwargsr   )	__class__ K/var/www/html/venv/lib/python3.7/site-packages/absl/flags/argparse_flags.pyr   p   s$    zArgumentParser.__init__Nc          
      s   |d krt jdd  }| jr,| jj|dd}t }t|d|}tt| ||\}}||k	rb||_	| jrt
|drt|j	|}|`	| j  y| j  W n2 tjk
r } z| t| W d d }~X Y nX ||fS )N   T)Z	force_gnur   )sysargvr   Zread_flags_from_filesobjectgetattrr   r   parse_known_argsr   hasattr_strip_undefok_argsZmark_as_parsedZvalidate_all_flagsr   ZIllegalFlagValueErrorerrorstr)r   args	namespaceZundefok_missingr   e)r   r   r   r"      s*    



 zArgumentParser.parse_known_argsc             C   sV   t |tjd }x<|D ]4}|tkr(q|| }||jkr||k}| || qW dS )zDefines flags from absl_flags.r   N)setZget_key_flags_for_moduler   r   _BUILT_IN_FLAGSname_define_absl_flag)r   
absl_flagsZ	key_flagsr,   flag_instancesuppressr   r   r   r      s    

z!ArgumentParser._define_absl_flagsc             C   s   |j }|j}d| g}|r*|dd|  |r6tj}n|jdd}|jrv|d|  | j	|t
||j  |d n| j	|t||j  |d dS )	z&Defines a flag from the flag_instance.z--r   r   %z%%z--no)r   r   metavarr/   N)r,   
short_nameinsertr   r   r   replacebooleanappendr   _BooleanFlagActionupper_FlagAction)r   r/   r0   Z	flag_namer3   Zargument_namesZhelptextr   r   r   r-      s$    
z ArgumentParser._define_absl_flag)NN)	__name__
__module____qualname____doc__r   r"   r   r-   __classcell__r   r   )r   r   r   m   s
   ))r   c                   s0   e Zd ZdZejf fdd	ZdddZ  ZS )r:   z*Action class for Abseil non-boolean flags.c                s&   ~|| _ tt| j|tj||d dS )a  Initializes _FlagAction.

    Args:
      option_strings: See argparse.Action.
      dest: Ignored. The flag is always defined with dest=argparse.SUPPRESS.
      help: See argparse.Action.
      metavar: See argparse.Action.
      flag_instance: absl.flags.Flag, the absl flag instance.
      default: Ignored. The flag always uses dest=argparse.SUPPRESS so it
          doesn't affect the parsing result.
    )option_stringsdestr   r2   N)_flag_instancer   r:   r   r   r   )r   r@   rA   r   r2   r/   r	   )r   r   r   r      s    
z_FlagAction.__init__Nc             C   s   | j | d| j _dS )zCSee https://docs.python.org/3/library/argparse.html#action-classes.FN)rB   parseusing_default_value)r   parserr(   valuesoption_stringr   r   r   __call__
  s    z_FlagAction.__call__)N)	r;   r<   r=   r>   r   r   r   rH   r?   r   r   )r   r   r:      s   	r:   c                   s0   e Zd ZdZejf fdd	ZdddZ  ZS )r8   z&Action class for Abseil boolean flags.c                sT   ~~|| _ | j jg}| j jr*|| j j t|| _tt| j|t	j
d||d dS )a  Initializes _BooleanFlagAction.

    Args:
      option_strings: See argparse.Action.
      dest: Ignored. The flag is always defined with dest=argparse.SUPPRESS.
      help: See argparse.Action.
      metavar: See argparse.Action.
      flag_instance: absl.flags.Flag, the absl flag instance.
      default: Ignored. The flag always uses dest=argparse.SUPPRESS so it
          doesn't affect the parsing result.
    r   )r@   rA   nargsr   r2   N)rB   r,   r3   r7   	frozenset_flag_namesr   r8   r   r   r   )r   r@   rA   r   r2   r/   r	   Z
flag_names)r   r   r   r     s    


z_BooleanFlagAction.__init__Nc             C   s   t |tr|rtd|dr.|dd }n|dd }|| jkrR| jd n4|drn|dd | jkrztd| | jd	 d
| j_dS )zCSee https://docs.python.org/3/library/argparse.html#action-classes.zvalues must be an empty list.z--   Nr   truenozinvalid option_string: falseF)
isinstancelistr   
startswithrK   rB   rC   rD   )r   rE   r(   rF   rG   optionr   r   r   rH   3  s    

z_BooleanFlagAction.__call__)N)	r;   r<   r=   r>   r   r   r   rH   r?   r   r   )r   r   r8     s   	r8   c                   s*   e Zd ZdZ fddZdddZ  ZS )r   z!Action class for --helpfull flag.c                s&   ~~t t| j|tjtjd|d dS )zInitializes _HelpFullAction.

    Args:
      option_strings: See argparse.Action.
      dest: Ignored. The flag is always defined with dest=argparse.SUPPRESS.
      default: Ignored.
      help: See argparse.Action.
    r   )r@   rA   r	   rI   r   N)r   r   r   r   r   )r   r@   rA   r	   r   )r   r   r   r   G  s    	
z_HelpFullAction.__init__Nc             C   sZ   |   |j}|rNt| }tjd }||kr:|| t|j|ddd |	  dS )zCSee https://docs.python.org/3/library/argparse.html#action-classes.r    T)prefixZinclude_special_flagsN)

print_helpr   sortedZflags_by_module_dictr   r   removeprintZ_get_help_for_modulesexit)r   rE   r(   rF   rG   r.   modulesZmain_moduler   r   r   rH   X  s    

z_HelpFullAction.__call__)N)r;   r<   r=   r>   r   rH   r?   r   r   )r   r   r   D  s   r   c                sH   | rDt dd | dD   t dd  D O   fdd|D }|S )z=Returns a new list of args after removing flags in --undefok.c             s   s   | ]}|  V  qd S )N)strip).0r,   r   r   r   	<genexpr>o  s    z&_strip_undefok_args.<locals>.<genexpr>,c             s   s   | ]}d | V  qdS )rN   Nr   )r]   r,   r   r   r   r^   p  s    c                s   g | ]}t | s|qS r   )_is_undefok)r]   arg)undefok_namesr   r   
<listcomp>r  s    z'_strip_undefok_args.<locals>.<listcomp>)r*   split)r   r'   r   )rb   r   r$   l  s
    r$   c             C   s`   |  dsdS |  dr&| dd }n| dd }d|krL|dd\}}n|}||kr\dS dS )	zGReturns whether we can ignore arg based on a set of undefok flag names.r   Fz--rL   Nr   =T)rR   rd   )ra   rb   Zarg_without_dashr,   _r   r   r   r`   v  s    

r`   )r>   r   r   Zabslr   rJ   r+   r   Actionr:   r8   r   r$   r`   r   r   r   r   <module>[   s    $4(
