
    v[                       S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKrSSKJr  SS/r " S S\5      r " S S\\R@                  5      r  " S S\\RB                  5      r" " S S\5      r#SyS jr$S r%Sr&Sr'Sr(S\(-  r)S\)-  r*S \*-  r+\(\)\*\+S!.r,SS"S#S$S%S&S"S#S$S%S&S'.r-S(S(S)S)S*S*S+S+S,S,S-.
r.S. r/S/ r0SzS0 jr1SzS1 jr2     S{S2 jr3S3 r4S|S4 jr5    S}S5 jr6     S~S6 jr7S7r8 " S8 S9\95      r: " S: S;\95      r; " S< S=\95      r< " S> S?\95      r= " S@ SA\95      r>   SSB jr?SC r@SD rASE rBSF rCSG rDSSH jrESI rFSySJ jrG " SK SL\95      rH " SM SN\R                  \H5      rJ SSO\KSP\KSQ\K4SR jjrLSS rMST rNSU rO " SV SW\R                  \H5      rP " SX SY\R                  \H5      rQSZ\RS[\RSQ\R4S\ jrS " S] S^\Q5      rT " S_ S`\T5      rU " Sa Sb\R                  5      rW " Sc Sd\W5      rX " Se Sf\R                  5      rZSSg jr[ " Sh Si\R                  5      r\Sj r] " Sk Sl\R                  5      r^Sm r_ " Sn So\R                  5      r` " Sp Sq\95      ra " Sr Ss\R                  5      rcSSt jrd " Su Sv\R                  5      re " Sw Sx\95      rfg)a  A module that provides parsing utilities for argparse.

For details of how argparse argument pasers work, see:

http://docs.python.org/dev/library/argparse.html#type

Example usage:

import argparse
import arg_parsers

parser = argparse.ArgumentParser()

parser.add_argument(
'--metadata',
type=arg_parsers.ArgDict())
parser.add_argument(
'--delay',
default='5s',
type=arg_parsers.Duration(lower_bound='1s', upper_bound='10s')
parser.add_argument(
'--disk-size',
default='10GB',
type=arg_parsers.BinarySize(lower_bound='1GB', upper_bound='10TB')

res = parser.parse_args(
'--names --metadata x=y,a=b,c=d --delay 1s --disk-size 10gb'.split())

assert res.metadata == {'a': 'b', 'c': 'd', 'x': 'y'}
assert res.delay == 1
assert res.disk_size == 10737418240

    )absolute_import)division)unicode_literalsN)tz)arg_parsers_usage_text)parser_errors)log)
properties)console_attr)
console_io)files)times)zipDuration
BinarySizec                       \ rS rSrSrSrg)ErrorM   z+Exceptions that are defined by this module. N__name__
__module____qualname____firstlineno____doc____static_attributes__r       *lib/googlecloudsdk/calliope/arg_parsers.pyr   r   M   s    3r   r   c                       \ rS rSrSrSrg)ArgumentTypeErrorQ   z7Exceptions for parsers that are used as argparse types.r   Nr   r   r   r   r    r    Q   s    ?r   r    c                       \ rS rSrSrSrg)ArgumentParsingErrorU   zRaised when there is a problem with user input.

argparse.ArgumentError takes both the action and a message as constructor
parameters.
r   Nr   r   r   r   r#   r#   U   s    r   r#   c                       \ rS rSrSrSrg)InvalidTypeError]   z=Error for when contributor provides incorrect type arguments.r   Nr   r   r   r   r&   r&   ]   s    Er   r&   c                 Z    Uc  U $ U(       d  U S-   $ Uc  U S-   U-   $ SR                  XUS9$ )a  Constructs an error message for an exception.

Args:
  error: str, The error message that should be displayed. This message should
    not end with any punctuation--the full error message is constructed by
    appending more information to error.
  user_input: str, The user input that caused the error.
  error_idx: int, The index at which the error occurred. If None, the index
    will not be printed in the error message.

Returns:
  str: The message to use for the exception.
z; received empty stringz; received: z2{error_message} at index {error_idx}: {user_input})error_message
user_input	error_idx)format)errorr*   r+   s      r   _GenerateErrorMessager.   a   sT     L,,,>!J..
>
E
EI F G Hr   c                 B    SR                  SR                  U 5      5      $ )zConstructs an error message for exception thrown invalid input.

Args:
  unit_scales: list, A list of strings with units that will be recommended to
    user.

Returns:
  str: The message to use for the exception.
zvgiven value must be of the form DECIMAL[UNITS] where units can be one of {0} and value must be a whole number of Bytes, )r,   join)unit_scaless    r   InvalidInputErrorMessager3   y   s$    DDJFii$E&'r   z
    ^                           # Beginning of input marker.
    (?P<amount>\d+\.?\d*)       # Amount.
    ((?P<suffix>[-/a-zA-Z]+))?  # Optional scale and type abbr.
    $                           # End of input marker.
z&^(?P<start>[0-9]+)(-(?P<end>[0-9]+))?$   <      )smhd   i   i   @l        l           ) KMGTPKiMiGiTiPiTiBGiBMiBKiBB)
PiBPBrG   TBrH   GBrI   MBrJ   KBc                    [         R                  " U 5      nUn[        U5      R                  5       (       dO  U(       aH  U[        ;   a>  US-  [        U   p2[        U5      R                  5       (       d  U(       a  U[        ;   a  M>  X#4$ )a  Convert input value and units to a whole number of a lower unit.

Args:
  amount: str, a number, for example '3.25'
  unit: str, a binary prefix, for example 'GB' or 'GiB'

Returns:
  (decimal.Decimal(), str), a tuple of number and suffix, converted such that
  the number returned is an integer, or the value, in Bytes, of the amount
  input. For example (23, 'MiB'). Note that IEC binary prefixes are always
  assumed and returned.
r;   )decimalDecimalfloat
is_integer_UnitToLowerUnitDict)amountunitreturn_amountreturn_units       r   ConvertToWholeNumberr\      sy     //&)-+=!,,..;	,	, 	[)  =!,,..;	,	,
 
	##r   c                    ^  U 4S jnU$ )zCreate a completer to handle completion for comma separated lists.

Args:
  individual_completer: A function that completes an individual element.

Returns:
  A function that completes the last element of the list.
c                    > SnU R                  SS5      n[        U5      S:  a  US   S-   nUS   n T" X40 UD6nU Vs/ s H  ocU-   PM	     sn$ s  snf )Nr<   ,r4   r   )rsplitlen)prefixparsed_argskwargsstartlstmatchesmatchindividual_completers          r   MultiCompleter)GetMultiCompleter.<locals>.MultiCompleter   sb    E
--Q
C
3x!|!fsle1vf"6A&AG'./weEMw///s   Ar   )ri   rj   s   ` r   GetMultiCompleterrl      s    0 
r   c                     U (       d  U $ U R                  5       n[        U5      n[        UR                  5       5       H  nU(       d    OX#S-
     U:X  d  M  US-  nM      U SU $ )z7Returns suffix with trailing type abbreviation deleted.r4   N)upperra   reversed)suffix	type_abbrr7   ics        r   _DeleteTypeAbbrrt      s^    	Mlln!	!f!IOO%&aQx1}1fa	 '
 
r   c                 `    [        U R                  5       U5      n[        R                  U5      $ )ac  Returns the binary size per unit for binary suffix string.

Args:
  suffix: str, A case insensitive unit suffix string with optional type
    abbreviation.
  type_abbr: str, The optional case insensitive type abbreviation following
    the suffix.

Raises:
  ValueError for unknown units.

Returns:
  The binary size per unit for a unit+type_abbr suffix.
)rt   rn   _BINARY_SIZE_SCALESget)rp   rq   rY   s      r   GetBinarySizePerUnitrx      s'     
	3$		 	 	&&r   c                    ^ ^^^^^^^^	^
^ SU U4S jjm	U	UU UUU4S jmTc  Sm
OT" T5      m
Tc  SmOT" T5      mUUU
UU4S jnU$ )a  A helper that returns a function that can parse values with units.

Casing for all units matters.

Args:
  scales: {str: int}, A dictionary mapping units to their magnitudes in
    relation to the lowest magnitude unit in the dict.
  default_unit: str, The default unit to use if the user's input is missing
    unit.
  lower_bound: str, An inclusive lower bound.
  upper_bound: str, An inclusive upper bound.
  strict_case: bool, whether to be strict on case-checking
  type_abbr: str, the type suffix abbreviation, e.g., B for bytes, b/s for
    bits/sec.
  suggested_binary_size_scales: list, A list of strings with units that will
    be recommended to user.

Returns:
  A function that can parse values.
Nc                    > [        [        R                  " T5      S S9nU c  U VVs/ s H
  u  p#UT-   PM     snn$ U VVs/ s H  u  p#UT-   U ;   d  M  UT-   PM     snn$ s  snnf s  snnf )z:Returns a list of the units in scales sorted by magnitude.c                     U S   U S   4$ )Nr4   r   r   )values    r   <lambda>8_ValueParser.<locals>.UnitsByMagnitude.<locals>.<lambda>)  s    %(E!H1Er   )key)sortedsix	iteritems)suggested_binary_size_scalesscale_itemsr   _scalesrq   s       r   UnitsByMagnitude&_ValueParser.<locals>.UnitsByMagnitude&  s    f#EGK#+,78K&#cIoK88 "!FC?:: 	i!  9s   A#A)	A)c           
      |  > [         R                  " [        U [         R                  5      nU(       d"  [	        [        [        T
" T5      5      U S95      eUR                  S5      =(       d    Sn[        UR                  S5      U5      u  p2[        U5      R                  5       (       d"  [	        [        [        T
" T5      5      U S95      e[        U5      n[        UT5      nT(       a  Un[        TT5      nTnOhUR                  5       n[        TR                  5       T5      n[        TR                  5        VV	s/ s H  u  pUR                  5       U	4PM     sn	n5      nU(       d  XB:X  a  X7U   -  $ XW;   a  X7U   -  $ [	        [        SR!                  SR#                  T
" 5       5      5      US95      es  sn	nf )z;Parses value that can contain a unit and type abbreviation.r*   rp   r<   rX   zunit must be one of {0}r0   )rerh   _VALUE_PATTERNVERBOSEr    r.   r3   groupr\   rU   rV   intrt   rn   dictitemsr,   r1   )r|   rh   rp   rX   rY   	unit_casedefault_unit_casescales_casekvr   default_unitr   strict_caser   rq   s             r   Parse_ValueParser.<locals>.Parse2  s   HH^UBJJ7E
&"#?@B ! !
 [["(bF)%++h*?HNF=##%%
&"#?@B ! !
 [F69-Di),	Bk**,i),*<*<*>	JV\\^D^TQ1779a.^DEkDN"3444		!),,,
'..tyy9I9K/LM    Es   =F8
c                    > U c  gT" U 5      nTb(  UT:  a"  [        [        SR                  T5      U S95      eTb(  UT:  a"  [        [        SR                  T5      U S95      eU$ z1Same as Parse except bound checking is performed.Nz*value must be greater than or equal to {0}r   z'value must be less than or equal to {0}r    r.   r,   r|   parsed_valuer   lower_boundparsed_lower_boundparsed_upper_boundupper_bounds     r   ParseWithBoundsChecking-_ValueParser.<locals>.ParseWithBoundsCheckingb  s    }5\l		'L;M,M!<CC! "# 	#
 )l=O.O!9@@M "# 	#
 r   Nr   )r   r   r   r   r   rq   r   r   r   r   r   r   s   ``````` @@@@r   _ValueParserr   
  s[    8
 
$  $ L {+{+ ( 
! r   c                    ^ ^ UU 4S jnU$ )a  Returns a function that validates a string against a regular expression.

For example:

>>> alphanumeric_type = RegexpValidator(
...   r'[a-zA-Z0-9]+',
...   'must contain one or more alphanumeric characters')
>>> parser.add_argument('--foo', type=alphanumeric_type)
>>> parser.parse_args(['--foo', '?'])
>>> # SystemExit raised and the error "error: argument foo: Bad value [?]:
>>> # must contain one or more alphanumeric characters" is displayed

Args:
  pattern: str, the pattern to compile into a regular expression to check
  description: an error message to show if the argument doesn't match

Returns:
  function: str -> str, usable as an argparse type
c                 |   > [         R                  " TS-   U 5      (       d  [        SR                  U T5      5      eU $ )N$Bad value [{0}]: {1})r   rh   r    r,   )r|   descriptionpatterns    r   r   RegexpValidator.<locals>.Parse  s6    88GcM5))4;;E;OPPLr   r   )r   r   r   s   `` r   RegexpValidatorr   y  s    *
 
,r   c                    ^ ^^ UU U4S jnU$ )a  Returns a function that validates the input by running it through fn.

For example:

>>> def isEven(val):
...   return val % 2 == 0
>>> even_number_parser = arg_parsers.CustomFunctionValidator(
      isEven, 'This is not even!', parser=arg_parsers.BoundedInt(0))
>>> parser.add_argument('--foo', type=even_number_parser)
>>> parser.parse_args(['--foo', '3'])
>>> # SystemExit raised and the error "error: argument foo: Bad value [3]:
>>> # This is not even!" is displayed

Args:
  fn: str -> boolean
  description: an error message to show if boolean function returns False
  parser: an arg_parser that is applied to to value before validation. The
    value is also returned by this parser.

Returns:
  function: str -> str, usable as an argparse type
c                    >  T(       a  T" U 5      OU nT" U5      (       a  U$  [        R                  " U 5      nSR                  UT5      n[        U5      e! [          a     N?f = f)zDValidates and returns a custom object from an argument string value.r   )r    r   SafeTextr,   )r|   r   encoded_valueformatted_errr   fnparsers       r   r   &CustomFunctionValidator.<locals>.Parse  sn    &,VE]%l 
L		 
 ))%0M*11-MM
M
**  
s   A 
A$#A$r   )r   r   r   r   s   ``` r   CustomFunctionValidatorr     s    0+ 
,r   c                 b   ^ ^^^^^^ U U4S jmT" T5      mTc  SmOT" T5      mUUUUU4S jnU$ )a  Returns a function that can parse time durations.

See times.ParseDuration() for details. If the unit is omitted, seconds is
assumed. The parsed unit is assumed to be seconds, but can be specified as
ms or us.
For example:

  parser = Duration()
  assert parser('10s') == 10
  parser = Duration(parsed_unit='ms')
  assert parser('10s') == 10000
  parser = Duration(parsed_unit='us')
  assert parser('10s') == 10000000

Args:
  default_unit: str, The default duration unit.
  lower_bound: str, An inclusive lower bound for values.
  upper_bound: str, An inclusive upper bound for values.
  parsed_unit: str, The unit that the result should be returned as. Can be
    's', 'ms', or 'us'.

Raises:
  ArgumentTypeError: If either the lower_bound or upper_bound
    cannot be parsed. The returned function will also raise this
    error if it cannot parse its input. This exception is also
    raised if the returned function receives an out-of-bounds
    input.

Returns:
  A function that accepts a single time duration as input to be
    parsed an returns an integer if the parsed value is not a fraction;
    Otherwise, a float value rounded up to 4 decimals places.
c           
        > T
S:X  a  SnO&T
S:X  a  SnOT
S:X  a  SnO[        [        S5      5      e [        R                  " U T	S9nUR                  U-  n[        U5      n[        US	5      nXT-
  nU(       a  U$ U$ ! [        R                   aK  n[        R                  " U5      R                  S
5      n[        [        SR                  XS95      5      eSnAff = f)z?Parses a duration from value and returns it in the parsed_unit.msi  usi@B r7   r4   z%parsed_unit must be one of s, ms, us.)default_suffix   .zFailed to parse duration: {0}r   N)r    r.   r   ParseDurationtotal_secondsr   roundr   r   	text_typerstripr,   )r|   
multiplierdurationr   parsed_int_valueparsed_rounded_valuefractionemessager   parsed_units            r   r   Duration.<locals>.Parse  s    dj		j		j
 G
HJ JN$$U<Hh++j8l\*"<3%8h	##;; Na '',g3
)
0
0
0
KM N NNs   AA< :A< <CACCNc                    > U c  gT" U 5      nTb(  UT:  a"  [        [        SR                  T5      U S95      eTb(  UT:  a"  [        [        SR                  T5      U S95      eU$ r   r   r   s     r   r   )Duration.<locals>.ParseWithBoundsChecking  s    }<L%,9K*K
:AA+N ! ! %,9K*K
7>>{K ! ! r   r   )r   r   r   r   r   r   r   r   s   ```` @@@r   r   r     s@    LN2 [){+ " 
! r   c           
      (    [        [        UU USUUS9$ )a  Returns a function that can parse binary sizes.

Binary sizes are defined as base-2 values representing number of
bytes.

Input to the parsing function must be a string of the form:

  DECIMAL[UNIT]

The amount must be non-negative. Valid units are "B", "KB", "MB",
"GB", "TB", "PB", "KiB", "MiB", "GiB", "TiB", "PiB".  If the unit is
omitted then default_unit is assumed.

The result is parsed in bytes. For example:

  parser = BinarySize()
  assert parser('10GB') == 1073741824

Another example:

  parser = BinarySize()
  assert parser('2.5KB') == 2560

Args:
  lower_bound: str, An inclusive lower bound for values.
  upper_bound: str, An inclusive upper bound for values.
  suggested_binary_size_scales: list, A list of strings with units that will
    be recommended to user.
  default_unit: str, unit used when user did not specify unit.
  type_abbr: str, the type suffix abbreviation, e.g., B for bytes, b/s for
    bits/sec.

Raises:
  ArgumentTypeError: If either the lower_bound or upper_bound
    cannot be parsed. The returned function will also raise this
    error if it cannot parse its input. This exception is also
    raised if the returned function receives an out-of-bounds
    input.

Returns:
  A function that accepts a single binary size as input to be
    parsed.
F)r   r   r   r   rq   r   )r   rv   )r   r   r   r   rq   s        r   r   r     s)    ` 
#?
A Ar   =c                   F    \ rS rSrSrS r\S 5       rS rS r	S r
S rS	rg
)RangeiU  zRange of integer values.c                     Xl         X l        g r   re   end)selfre   r   s      r   __init__Range.__init__X  s    JHr   c                 H   [         R                  " [        U 5      nU(       d  [        SR	                  U 5      5      e[        UR                  S5      5      nUR                  S5      nUc  UnO[        U5      nX2:  a  [        SR	                  X#U 5      5      e[        X#5      $ )z/Creates Range object out of given string value.zPExpected a non-negative integer value or a range of such values instead of "{0}"re   r   zCExpected range start {0} smaller or equal to range end {1} in "{2}")r   rh   _RANGE_PATTERNr    r,   r   r   r   )string_valuerh   re   r   s       r   r   Range.Parse\  s     HH^\2E228&2FH H G$%E
++e
C
{cHc
{ 77=v"'l8<= = r   c                 :   U R                   S-   UR                  :  d  U R                  UR                   S-   :  a  [        SR                  X5      5      e[	        [        U R                  UR                  5      [        U R                   UR                   5      5      $ )z>Combines two overlapping or adjacent ranges, raises otherwise.r4   zACannot combine non-overlapping or non-adjacent ranges {0} and {1})r   re   r   r,   r   minmaxr   others     r   CombineRange.Combinep  sp    xx!|ekk!TZZ%))a-%?   &t 35 5TZZ-s488UYY/GHHr   c                     [        U[        5      (       a9  U R                  UR                  :H  =(       a    U R                  UR                  :H  $ gNF)
isinstancer   re   r   r   s     r   __eq__Range.__eq__w  s7    %ZZ5;;&@488uyy+@@r   c                     U R                   UR                   :X  a  U R                  UR                  :  $ U R                   UR                   :  $ r   r   r   s     r   __lt__Range.__lt__|  s8    zzU[[ XX		!!::##r   c                     U R                   U R                  :X  a   [        R                  " U R                   5      $ SR	                  U R                   U R                  5      $ )Nz{0}-{1})re   r   r   r   r,   r   s    r   __str__Range.__str__  s@    zzTXX]]4::&&DJJ11r   )r   re   N)r   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   r   r   r   r   U  s3       &I
$
2r   r   c                   :    \ rS rSrSrSrSrS r\S	S j5       r	Sr
g)
HostPorti  z.A class for holding host and port information.z/^(?P<address>[\w\d\.-]+)?(:|:(?P<port>[\d]+))?$z2^(\[(?P<address>[\w\d:]+)\])(:|:(?P<port>[\d]+))?$c                     Xl         X l        g r   hostport)r   r   r   s      r   r   HostPort.__init__  s    IIr   c                    U (       d  [        SS5      $ [        R                  " [         R                  U [        R                  5      nU(       aV  U(       dO  [        R                  " [         R
                  U [        R                  5      nU(       d  [        [        SU S95      eOU(       d  [        [        SU S95      e[        UR                  S5      UR                  S5      5      $ )a  Parse the given string into a HostPort object.

This can be used as an argparse type.

Args:
  s: str, The string to parse. If ipv6_enabled and host is an IPv6 address,
  it should be placed in square brackets: e.g.
    [2001:db8:0:0:0:ff00:42:8329] or
    [2001:db8:0:0:0:ff00:42:8329]:8080
  ipv6_enabled: boolean, If True then accept IPv6 addresses.

Raises:
  ArgumentTypeError: If the string is not valid.

Returns:
  HostPort, The parsed object.
NzFailed to parse host and port. Expected format 

  IPv4_ADDRESS_OR_HOSTNAME:PORT

or

  [IPv6_ADDRESS]:PORT

(where :PORT is optional).r   zlFailed to parse host and port. Expected format 

  IPv4_ADDRESS_OR_HOSTNAME:PORT

(where :PORT is optional).addressr   )	r   r   rh   IPV4_OR_HOST_PATTERNUNICODEIPV6_PATTERNr    r.   r   )r7   ipv6_enabledrh   s      r   r   HostPort.Parse  s    & dD!!HHX22ArzzBEEhhx,,a<e!-
  	  
+ 	  EKK	*EKK,?@@r   r   NF)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s+    6KF, (A (Ar   r   c                   (    \ rS rSrSr\S 5       rSrg)Dayi  z9A class for parsing a datetime object for a specific day.c           
         U (       d  g  [         R                  " U S5      R                  5       $ ! [         R                   a;  n[	        [        SR                  [        R                  " U5      5      U S95      eS nAff = f)Nz%Y-%m-%dzFailed to parse date: {0}r   )	r   ParseDateTimedater   r    r.   r,   r   r   r7   r   s     r   r   	Day.Parse  sl      J/4466;; 
)00q1AB s   $/ A>6A99A>r   N)r   r   r   r   r   r   r   r   r   r   r   r  r    s    A	 	r   r  c                   8    \ rS rSrSr\S 5       r\S 5       rSrg)Datetimei  z&A class for parsing a datetime object.c           
          U (       d  g [         R                  " U 5      $ ! [         R                   a;  n[        [	        SR                  [        R                  " U5      5      U S95      eSnAff = f)z?Parses a string value into a Datetime object in local timezone.NzFailed to parse date/time: {0}r   )r   r  r   r    r.   r,   r   r   r  s     r   r   Datetime.Parse  sc       ##;; 
.55cmmA6FG s     A/6A**A/c           
         U (       d  g [         R                  " U [        R                  " 5       S9$ ! [         R                   a;  n[        [        SR                  [        R                  " U5      5      U S95      eSnAff = f)zBParses a string representing a time in UTC into a Datetime object.N)tzinfozFailed to parse UTC time: {0}r   )
r   r  r   tzutcr   r    r.   r,   r   r   r  s     r   ParseUtcTimeDatetime.ParseUtcTime  sk       288:66;; 
-44S]]15EF s   '2 B6A<<Br   N)	r   r   r   r   r   r   r   r  r   r   r   r   r	  r	    s+    .
 
 
 
r   r	  c                   0    \ rS rSrSr/ SQr\S 5       rSrg)	DayOfWeeki  z&A class for parsing a day of the week.)SUNMONTUEWEDTHUFRISATc           	          U (       d  gU R                  5       SS nU[        R                  ;  a?  [        [	        SR                  SR                  [        R                  5      5      U S95      eU$ )z7Validates and normalizes a string as a day of the week.N   z7Failed to parse day of week. Value should be one of {0}r0   r   )rn   r  DAYSr    r.   r,   r1   )r7   fixeds     r   r   DayOfWeek.Parse  sd     GGIbqMEINN"
GNN))INN+- 
 Lr   r   N)	r   r   r   r   r   r  r   r   r   r   r   r   r  r    s    .	:$ r   r  c                 $   ^ ^^^^ UU UUU4S jnU$ )a5  Returns a function that can parse given type within some bound.

Args:
  type_builder: A callable for building the requested type from the value
    string.
  type_description: str, Description of the requested type (for verbose
    messages).
  lower_bound: of type compatible with type_builder, The value must be >=
    lower_bound.
  upper_bound: of type compatible with type_builder, The value must be <=
    upper_bound.
  unlimited: bool, If True then a value of 'unlimited' means no limit.

Returns:
  A function that can parse given type within some bound.
c                 B  > T(       a  U S:X  a  g T" U 5      nTb(  UT:  a"  [        [        SR                  T5      U S95      eTb(  TU:  a"  [        [        SR                  T5      U S95      eU$ ! [          a#    [        [        SR                  T5      U S95      ef = f)zParses value as a type constructed by type_builder.

Args:
  value: str, Value to be converted to the requested type.

Raises:
  ArgumentTypeError: If the provided value is out of bounds or unparsable.

Returns:
  Value converted to the requested type.
	unlimitedNzValue must be {0}r   z*Value must be greater than or equal to {0}z'Value must be less than or equal to {0})
ValueErrorr    r.   r,   )r|   r   r   type_buildertype_descriptionr!  r   s     r   r   _BoundedType.<locals>.Parse  s     Uk)O
u
a 1{?
:AA+N ! !
 ;?
7>>{K ! !
 H#  O
!(()9:uNO OOs   A1 1-Br   )r#  r$  r   r   r!  r   s   ````` r   _BoundedTyper&     s    ," "H 
,r   c                  *    [        [        S/U Q70 UD6$ )Nz
an integer)r&  r   argsrd   s     r   
BoundedIntr*  =  s    	c<	9$	9&	99r   c                  *    [        [        S/U Q70 UD6$ )Nza floating point number)r&  rU   r(  s     r   BoundedFloatr,  A  s    	e6	H	H	HHr   c                 p    U (       d  / $ U R                  U5      (       d  X-  n U R                  U5      S S $ )N)endswithsplit)	arg_valuedelims     r   _SplitOnDelimr3  E  s9    	I			E	"	"I			$$r   c                 >   SSS.n[        UR                  5       5      n/ n[        [        U 5      5       H_  nUS:  a  XS-
     S:X  a  M  X   nXQ;   a(  X   nU(       a	  US   U:w  a    gUR	                  5         MG  XR;   d  MN  UR                  U5        Ma     U(       + $ )	z1Checks whether the string contains balanced json.{[)}]r   r4   \r.  F)setvaluesrangera   popappend)	str_valueclosing_bracketsopening_bracketscurrent_bracketsrr   chmatching_braces          r   _ContainsValidJSONrE  M  s    S))0023Y a1uq5!T)	B	'+n!1"!5!G		b! ! 	r   c                     / nSnU  H9  nU(       d  UnOXAU-   -  n[        U5      (       d  M&  UR                  U5        SnM;     U(       a  [        SR                  U5      5      eU$ )a  Rejoins json substrings that are part of the same json strings.

For example:
    [
        'key={"a":"b"',
        '"c":"d"}'
    ]

Is merged together into: ['key={"a":"b","c":"d"}']

Args:
  json_list: [str], list of json snippets
  delim: str, delim used to rejoin the json snippets
  arg_value: str, original value used to make json_list

Returns:
  list of strings containing balanced json
NzWInvalid entry "{}": missing opening brace ("{{" or "[") or closing brace ("}}" or "]").)rE  r>  r"  r,   )	json_listr2  r1  resultcurrent_substrtokens         r   _RejoinJSONStrsrK  d  sp    & &.en%n.))mmN#n  
	%vi02 2 
-r   c                 `    U (       d  / $ [        X5      nU(       a  US:w  a  U$ [        X1U 5      $ )a  Tokenize an argument into a list.

Deliminators that are inside json will not be split. Even when the
json is nested, we will not split on the delimitor until we reach the
json's closing bracket. For example:

  '{"a": [1, 2], "b": 3},{"c": 4}'

with default delim (',') will be split only on the `,` separating the 2
json strings i.e.

  [
      '{"a": [1, 2], "b": 3}',
      '{"c": 4}'
  ]

This also works for strings that contain dictionary pattern. For example:

  'key1={"a": [1, 2], "b": 3},key2={"c": 4}'

with default delim (',') will be split on the delim (',') separating the
two strings into

  [
      'key1={"a": [1, 2], "b": 3}',
      'key2={"c": 4}'
  ]


Args:
  arg_value: str, The raw argument.
  delim: str, The delimiter on which to split the argument string.
  includes_json: str, determines whether to ignore delimiter inside json

Returns:
  [str], The tokenized list.
r_   )r3  rK  )r1  r2  includes_jsonstr_lists       r   _TokenizeQuotedListrO    s2    L 
I9,(	%3,O	)	44r   c                     U c  / n [        U[        5      (       a  U H  n[        X5        M     U $ U R                  U5        U $ r   )r   list_ConcatListr>  )existing_values
new_values	new_values      r   rR  rR    sJ    O
D!!	/-   
 :&	r   c                 X    U(       a"  [         R                  " 5       (       d  SU SU  3$ U $ )zReturns a help text for universes.

Args:
  default: str, help text for argument.
  universe_help: str, additional specific help text for Universe.

Returns:
  [str], The help text for argument.
zUNIVERSE INFO: 

r
   IsDefaultUniverse)defaultuniverse_helps     r   UniverseHelpTextr\    s-     :7799]O4y99	.r   c                       \ rS rSrSrSrg)ArgTypei  zBase class for arg types.r   Nr   r   r   r   r^  r^    s    !r   r^  c                   T    \ rS rSrSr   SS jrS r\S 5       rS r	S r
SS	 jrS
rg)
ArgBooleani  zqInterpret an argument value as a bool.

This should only be used to define the spec of a key of an ArgDict flag.
Nc                 l    X0l         U(       a  Xl        O	SS/U l        U(       a  X l        g SS/U l        g )Ntrueyesfalseno)_case_sensitive_truthy_strings_falsey_strings)r   truthy_stringsfalsey_stringscase_sensitives       r   r   ArgBoolean.__init__  s4     *+$e_d+%t_dr   c           	         U R                   (       d  UR                  5       nOUnX R                  ;   a  gX R                  ;   a  g[	        SR                  USR                  U R                  U R                  -   5      5      5      e)NTFz/Invalid flag value [{0}], expected one of [{1}]r0   )rf  lowerrg  rh  r    r,   r1   )r   r1  normalized_arg_values      r   __call__ArgBoolean.__call__  sy    &__.&333333
9@@tyy!5!58L8L!LM	OP Pr   c                     gr   r   r   s    r   hiddenArgBoolean.hidden      r   c                     AU$ r   r   r   is_custom_metavarmetavars      r   GetUsageMetavarArgBoolean.GetUsageMetavar   
    Nr   c                     Ag)Nbooleanr   r   	shorthands     r   GetUsageExampleArgBoolean.GetUsageExample  s    r   c                 
    AAAg r   r   r   
field_namerequired	flag_names       r   GetUsageHelpTextArgBoolean.GetUsageHelpText      Hir   )rf  rh  rg  NNFr   )r   r   r   r   r   r   rp  propertyrs  rz  r  r  r   r   r   r   r`  r`    s@     #"#-P  r   r`  default_universenon_default_universereturnc                 >    [         R                  " 5       (       a  U $ U$ )aY  Determines if the arg is required based on the universe domain.

Args:
  default_universe: Whether the arg is required in the default universe.
    Defaults to False.
  non_default_universe: Whether the arg is required outside of the default
    universe. Defaults to True.

Returns:
  bool, whether the arg is required in the current universe.
rX  )r  r  s     r   ArgRequiredInUniverser    s     !!##	r   c                 0    [         R                  " SU 5      $ )N^\S*\.(yaml|json)$)r   rh   r1  s    r   _CheckIfJSONFileFormatr  !  s    	'	33r   c                 "    [        5       " U 5      $ r   )FileContentsr  s    r   	_LoadFiler  %  s    			""r   c                 0    SSK Jn  UR                  U 5      $ )Nr   yaml)googlecloudsdk.corer  load)r1  r  s     r   	_LoadJSONr  )  s    & 
9	r   c                   D    \ rS rSrSr\S 5       rS rS rS
S jr	S r
S	rg)ArgJSONi1  a  Parses inline JSON or from a file.

This is best for recursive values like struct fields
of when any value can be passed. ArgObject is better
for you want a specific format from the user.
ArgObjet helps validate if the user provided value
is valid and generates help text with examples.
c                     gr   r   r   s    r   rs  ArgJSON.hidden;  ru  r   c                     AU$ r   r   rw  s      r   rz  ArgJSON.GetUsageMetavar?  r|  r   c                     Ag)Nz{...}r   r  s     r   r  ArgJSON.GetUsageExampleC  s    r   Nc                 
    AAAg r   r   r  s       r   r  ArgJSON.GetUsageHelpTextG  r  r   c                     [        U[        5      (       d  [        SR                  U5      5      e[	        U5      (       a  [        U5      nOUn[        U5      $ )Nz4ArgJSON can only convert string values. Received {}.)r   strr"  r,   r  r  r  )r   r1  r*   s      r   rp  ArgJSON.__call__K  sT    i%%
@
G
G  i((Y'jjZ  r   r   r   )r   r   r   r   r   r  rs  rz  r  r  rp  r   r   r   r   r  r  1  s/      !r   r  c                   h    \ rS rSrSrSrSr       SS jrS rSr	\
S	 5       rS
 rS rSS jrSrg)ArgListiZ  a  Interpret an argument value as a list.

Intended to be used as the type= for a flag argument. Splits the string on
commas or another delimiter and returns a list.

By default, splits on commas:
    'a,b,c' -> ['a', 'b', 'c']
There is an available syntax for using an alternate delimiter:
    '^:^a,b:c' -> ['a,b', 'c']
    '^::^a:b::c' -> ['a:b', 'c']
    '^,^^a^,b,c' -> ['^a^', ',b', 'c']
r_   ^Nc                    ^ ^^ TT l         TT l        U=(       d    / T l        T(       a  UUU 4S jnUT l         UT l        UT l        UT l        UT l        g)a  Initialize an ArgList.

Args:
  element_type: (str)->str, A function to apply to each of the list items.
  min_length: int, The minimum size of the list.
  max_length: int, The maximum size of the list.
  choices: [element_type], a list of valid possibilities for elements. If
    None, then no constraints are imposed.
  custom_delim_char: char, A customized delimiter character.
  hidden_choices: [element_type], a subset of choices that should be hidden
    from documentation.
  includes_json: bool, whether the list contains any json

Returns:
  (str)->[str], A function to parse the list of values in the argument.

Raises:
  ArgumentTypeError: If the list is malformed.
c                    > T(       a	  T" U 5      nOU nUT;  aS  [        SR                  USR                  T Vs/ s H  o"TR                  ;  d  M  [	        U5      PM!     sn5      S95      eU$ s  snf )Nz"{value} must be one of [{choices}]r0   )r|   choices)r    r,   r1   hidden_choicesr  )	raw_valuetyped_valuers   r  element_typer   s      r   
ChoiceType$ArgList.__init__.<locals>.ChoiceType  s    $Y/+!+g%!"F"M"Mii#*K7at7J7J.J63q67KM #N #N O O  Ls   A/A/N)r  r  r  
min_length
max_lengthcustom_delim_charrM  )	r   r  r  r  r  r  r  rM  r  s	   ``  `    r   r   ArgList.__init__k  sQ    6 %DDL(.BD
 %d DO DO.D&Dr   c                    [        U[        5      (       a  UnO[        U[        R                  5      (       d.  [	        SR                  [        U5      R                  U5      5      eU R                  =(       d    U R                  nUR                  U R                  5      (       aF  U R                  USS  ;   a3  USS  R                  U R                  S5      u  p1U(       d  [	        S5      e[        XU R                  S9n[        U5      U R                   :  a  [	        S5      eU R"                  b$  [        U5      U R"                  :  a  [	        S5      eU R$                  (       a   U Vs/ s H  o@R%                  U5      PM     nnU$ s  snf )N%Invalid type [{}] for flag value [{}]r4   zInvalid delimeter. Please see `gcloud topic flags-file` or `gcloud topic escaping` for information on providing list or dictionary flag values with special characters.)r2  rM  znot enough argsztoo many args)r   rQ  r   string_typesr    r,   typer   r  DEFAULT_DELIM_CHAR
startswithALT_DELIM_CHARr0  rO  rM  ra   r  r  r  )r   r1  arg_listr2  args        r   rp  ArgList.__call__  sW   )T""h	3#3#344ELL
y/
"
"I/ 0 0 $$?(?(?e


t22
3
3


12
.$QR=..t/B/BAF!@A A %
0B0BDh 8}t&/00"s8}t'Fo..4<=HS##C(Hh=O >s   )F   c                     gr   r   r   s    r   rs  ArgList.hidden  ru  r   c                    AU R                   =(       d    U R                  nUR                  U/U R                  -  5      nU R                  (       a  U R                  U R                  -
  nOSnUS:X  a  SnOAUS:X  a  SR                  U5      nO)US:X  a  SR                  X#5      nOSR                  X#5      nUR                  XF4 Vs/ s H  ow(       d  M  UPM     sn5      n[        U5      U R                  :  a  U$ U R                  S:X  a  SR                  X#5      $ U R                  S:X  a  S	R                  X#5      $ S
R                  X#5      $ s  snf )a  Get a specially-formatted metavar for the ArgList to use in help.

An example is worth 1,000 words:

>>> ArgList().GetUsageMetavar('FOO')
'[FOO,...]'
>>> ArgList(min_length=1).GetUsageMetavar('FOO')
'FOO,[FOO,...]'
>>> ArgList(max_length=2).GetUsageMetavar('FOO')
'FOO,[FOO]'
>>> ArgList(max_length=3).GetUsageMetavar('FOO')  # One, two, many...
'FOO,[FOO,...]'
>>> ArgList(min_length=2, max_length=2).GetUsageMetavar('FOO')
'FOO,FOO'
>>> ArgList().GetUsageMetavar('REALLY_VERY_QUITE_LONG_METAVAR')
'REALLY_VERY_QUITE_LONG_METAVAR,[...]'

Args:
  is_custom_metavar: unused in GetUsageMetavar
  metavar: string, the base metavar to turn into an ArgList metavar

Returns:
  string, the ArgList usage metavar
Nr   r<   r4   z[{}]   z[{0}{1}[{0}]]z	[{}{}...]z	{}{}[...]z{0}{1}...{1}[...])r  r  r1   r  r  r,   ra   _MAX_METAVAR_LENGTH)	r   rx  ry  
delim_charr  num_optionaloptionalxmsgs	            r   rz  ArgList.GetUsageMetavar  s/   2 	''B4+B+BJy4??:;H__t6ll qh		w'h		 ''<h##G8h
//x&:@&:a1&:@
AC
3x$***j !44!44 ''<< As   
EEc                     Ag r   r   r  s     r   r  ArgList.GetUsageExample  s    r   c                 
    AAAg r   r   r  s       r   r  ArgList.GetUsageHelpText  r  r   )r  r  r  r  rM  r  r  )Nr   NNNNFr   )r   r   r   r   r   r  r  r   rp  r  r  rs  rz  r  r  r   r   r   r   r  r  Z  s`     . !!%""3'j<  8=tr   r  r|   charc                 r    U R                  U5      (       a  U SS n U R                  U5      (       a  U SS n U $ )z4Trims characters from the start and end of a string.r4   Nr.  )r  r/  )r|   r  s     r   _TrimCharacterr    s=    
d!"IE
^^D#2JE	,r   c                      ^  \ rS rSrSr          SU 4S jjrS rS rSS jrSS jr	S r
U 4S	 jr\S
 5       rU 4S jrS rSS jrSrU =r$ )ArgDicti  zInterpret an argument value as a dict.

Intended to be used as the type= for a flag argument. Splits the string on
commas to get a list, and then splits the items on equals to get a set of
key-value pairs to get a dict.
c                 >  > [         [        U ]  XEU	S9  U(       a  U(       a  [        S5      eXl        X l        X0l        X`l        U=(       d    / U l        Xl	        U(       d  SU0nUR                  5        H,  n[        U5      S:w  d  M  [        SR                  U5      5      e   SR                  [        R                   " U5      5      nSR                  ["        R$                  " U5      S9n["        R&                  " U["        R(                  5      U l        Xl        g	)
a  Initialize an ArgDict.

Args:
  key_type: (str)->str, A function to apply to each of the dict keys.
  value_type: (str)->str, A function to apply to each of the dict values.
  spec: {str: (str)->str}, A mapping of expected keys to functions. The
    functions are applied to the values. If None, an arbitrary set of keys
    will be accepted. If not None, it is an error for the user to supply a
    key that is not in the spec. If the function specified is None, then
    accept a key only without '=value'.
  min_length: int, The minimum number of keys in the dict.
  max_length: int, The maximum number of keys in the dict.
  allow_key_only: bool, Allow empty values.
  required_keys: [str], Required keys in the dict.
  operators: operator_char -> value_type, Define multiple single character
    operators, each with its own value_type converter. Use value_type==None
    for no conversion. The default value is {'=': value_type}
  includes_json: bool, whether string parsed includes json
  cleanup_input: bool, whether to clean up the input string

Returns:
  (str)->{str:str}, A function to parse the dict in the argument.

Raises:
  ArgumentTypeError: If the list is malformed.
  ValueError: If both value_type and spec are provided.
)r  r  rM  z"cannot have both spec and sub_typer   r4   z$Operator [{}] must be one character.r<   z([^{ops}]+)([{ops}]?)(.*))opsN)superr  r   r"  key_type
value_typespecallow_key_onlyrequired_keyscleanup_inputkeysra   r    r,   r1   r   iterkeysr   escapecompileDOTALLkey_op_value	operators)r   r  r  r  r  r  r  r  r  rM  r  opr  key_op_value_pattern	__class__s                 r   r   ArgDict.__init__  s    L 
'4!# " % 
;<<M OI(&,"D&
#inn	RA299"=? 	?  ''#,,y)
*C6==IIcN > 

#7CDNr   c                 R   XR                   ;   aG  U R                   U   c"  U(       a  [        SR                  U5      5      eg U R                   U   " U5      $ [        [        SR                  SR	                  [        U R                   R                  5       5      5      5      US95      e)NzKey [{0}] does not take a valuezvalid keys are [{0}]r0   r   )r  r    r,   r.   r1   r   r  r   r   r|   s      r   
_ApplySpecArgDict._ApplySpecU  s    
ii	3	!"C"J"J3"OP
PYYs^E""
$++DIIf)).."7$ -% & r   c                     U(       a&  U R                   (       a  [        U[        5      (       d  U$ UR                  5       n[	        US5      $ )N")r  r   r  stripr  )r   r|   removed_spaces      r   _CleanupInputArgDict._CleanupInputc  s6    ***UC2H2HlKKMM---r   c                 J   U(       a  Uc+  U R                   (       d  [        SR                  U5      5      eU R                  (       a   U R                  U5      nU R                   (       a  U R
                  R                  SS5      nOSnU R
                  R                  X45      nU(       a	   U" U5      nU R                  b  U R                  X5      nX4$ ! [         a    [        SR                  U5      5      ef = f! [         a    [        SR                  U5      5      ef = f);Converts and validates <key,value> and returns (key,value).NzBad syntax for dict arg: [{0}]. Please see `gcloud topic flags-file` or `gcloud topic escaping` for information on providing list or dictionary flag values with special characters.zInvalid key [{0}]r   zInvalid value [{0}])	r  r    r,   r  r"  r  rw   r  r  )r   r   r|   r  default_convertconvert_values         r   _ValidateKeyValueArgDict._ValidateKeyValuej  s   %-)<)<  !'s	- -
 }}AmmC  **35ooNN&&r;MEe$ yyooc)e:!  A 3 : :3 ?@@A  E 5 < <U CDDEs   C ,C= %C:=%D"c                 d    U R                  U5      U R                  U5      pTU R                  XEUS9$ )r  r  )r  r  )r   r   r|   r  r   r   s         r   _CleanupAndValidateKeyValue#ArgDict._CleanupAndValidateKeyValue  s5    c"D$6$6u$=q!!!2!..r   c                 h    U R                    H"  nX!;  d  M
  [        SR                  U5      5      e   g )Nz/Key [{0}] required in dict arg but not provided)r  r    r,   )r   arg_dictrequired_keys      r   _CheckRequiredKeysArgDict._CheckRequiredKeys  s6    **		%=DD 	 +r   c                   > [        U[        5      (       aO  Un[        R                  " 5       n[        R
                  " U5       H  u  pEU R                  XE5      u  pEXSU'   M     GO[        U[        R                  5      (       d.  [        SR                  [        U5      R                  U5      5      e[        [        U ];  U5      n[        R                  " 5       nU H  nU R                  R!                  U5      nU(       d  [        SR                  U5      5      eUR#                  S5      UR#                  S5      UR#                  S5      pYnU R                  XEU	S9u  pEXSU'   M     U R%                  U5        U$ )Nr  zInvalid flag value [{0}]r4   r  r  r   )r   r   collectionsOrderedDictr   r   r  r  r    r,   r  r   r  r  rp  r  rh   r   r  )r   r1  raw_dictr  r   r|   r  r  rh   r  r  s             r   rp  ArgDict.__call__  sA   )T""h((*hh/*#55cA
 0 	3#3#344ELL
y/
"
"I/ 0 0 w.y9h((*h#!!'',!"<"C"CC"HI
IQQQ55cR5H
  	H%Or   c                     gr   r   r   s    r   rs  ArgDict.hidden  ru  r   c                 8  > U R                   (       a  U(       a  [        [        U ]  X5      $ / n[	        [
        R                  " U R                   5      5      nU HF  u  pVUb  M
  U R                  (       d  [        SR                  U5      5      eUR                  U5        MH     U HY  u  pVU(       d  M  [        R                  " U5      (       a  M+  UR                  SR                  XUR                  5       5      5        M[     SSR                  U5      -   S-   nU$ )NzQKey [{0}] specified in spec without a function but allow_key_only is set to Falsez{0}={1}r6  z],[r8  )r  r  r  rz  r   r   r   r  r    r,   r>  
usage_textIsHiddenrn   r1   )	r   rx  ry  msg_list	spec_listspec_keyspec_functionr  r  s	           r   rz  ArgDict.GetUsageMetavar  s     99)7D12CMMHs}}TYY/0I $-		""!//5vh/?A A 	! $- $-	z22=AA	((>>3CDE $- 

8$
$s
*CJr   c                 `   AU R                   (       a9  SR                  S [        U R                   R                  5       5       5       5      $ U R                  (       a  U R
                  nOU R
                  =(       d    [        n[        R                  " U R                  =(       d    [        USS9$ )a  Returns a string of usage examples.

Generates an example of expected user input.
For example, an ArgDict with spec={'x': int, 'y': str} will generate

  x=int,y=string

An ArgDict with key_type=str and value_type=str will generate

  string=string

Args:
  shorthand: unused bool, whether to display in shorthand (ArgDict is
    always parsed as shorthand)

Returns:
  str, example text of usage
r_   c              3   P   #    U  H  u  p[         R                  " XS S9v   M     g7f)Tr  Nr  GetNestedKeyValueExample).0r   r|   s      r   	<genexpr>*ArgDict.GetUsageExample.<locals>.<genexpr>  s&      75jc 
-
-cD
I5s   $&T)r  r  r  )
r  r1   r   r   r  r  r  r  r  r  )r   r  r  s      r   r  ArgDict.GetUsageExample  s    & 	yyXX 7"499??#457 7 7 ??j??)cj..%# r   c                 
    AAAg r   r   r  s       r   r  ArgDict.GetUsageHelpText  r  r   )r  r  r  r  r  r  r  r  )
NNNr   NFNNFF)r   r   )r   r   r   r   r   r   r  r  r  r  r  rp  r  rs  rz  r  r  r   __classcell__r  s   @r   r  r    su     #!"";z.:/
6  4%N r   r  c                      ^  \ rS rSrSrSrS rS r     SU 4S jjr\	S 5       r
S rS	 rS
 rS rS rS rU 4S jrS rS rU 4S jrS rS r\	S 5       rU 4S jrS rS rS rS rSS jrSrU =r$ )	ArgObjecti  a$	  Catch all arg type that will accept a file, json, or ArgDict.

ArgObject is very similar to ArgDict with some extra functionality. ArgObject
will first try to parse a value as an arg_dict if string contains '='. The
type will then try to parse string as a file if string contains
.yaml or .json. Finally, parser will parse the string as json.

I. For example, with the following flag defintion:

  parser.add_argument(
      '--inputs',
      type=arg_parsers.ArgObject(key_type=str, value_type=int))

a caller can retrieve {"foo": 100} by specifying any of the following
on the command line.

  (1) --inputs=foo=100
  (2) --inputs='{"foo": 100}'
  (3) --inputs=path_to_json.(json|yaml)

II. If we need the type return a list of messages, use the repeated arg.
NOTE: when using repeated values, it is recommended to specify the
action as arg_parsers.FlattenAction()

For example, with the following flag defintion:

  parser.add_argument(
      '--inputs',
      type=arg_parsers.ArgObject(key_type=str, value_type=int),
      action=arg_parsers.FlattenAction()
      repeated=True)

a caller can retrieve [{"foo": 1, "bar": 2}, {"bax": 3}] by specifying any
of the following on the command line.

  (1) --inputs=foo=1,bar=2 --inputs=bax=3
  (2) --inputs='[{"foo": 1, "bar": 2}, {"bax": 3}]'
  (3) --inputs=path_to_json.(json|yaml)

III. If we need to parse non key-value pairs, do not provide key_type or spec.
For example, with the following flag defintion:

  parser.add_argument(
      '--inputs',
      type=arg_parsers.ArgObject(value_type=int))

a caller can retrieve 100 by specifying the following
on the command line.

  (1) --inputs=100
  (2) --inputs=path_to_json.(json|yaml)

IV. If we need to create nested objects, set value_type to another ArgObject
type. ArgDict syntax is automatically disabled for the nested ArgObject type
with enable_shorthand=False

For example, with the following flag defintion:

  parser.add_argument(
      '--inputs',
      type=arg_parsers.ArgObject(
          key_type=str,
          value_type=arg_parsers.ArgObject(
              key_type=str, value_type=int, enable_shorthand=False)))

a caller can retrieve {"foo": {"bar": 1}} by specifying any
of the following on the command line.

  (1) --inputs='foo={bar=1}'
  (2) --inputs='{"foo": {"bar": 1}}'
  (3) --inputs=path_to_json.(json|yaml)
r  c                 >    [        U[        5      (       a  SUl        g g r   )r   r%  
root_level)r   arg_types     r   _UpdateAsNestedArgObject._UpdateAsNestedC  s    (I&&!h 'r   c                 .    U[         :X  a
  [        5       $ U$ r   )boolr`  )r   r  s     r   _JSONValueTypeArgObject._JSONValueTypeG  s     T\r   c           
      n  > U(       a  U R                  U5        O/U(       a(  UR                  5        H  nU R                  U5        M     U=(       a4    UR                  5        VVs0 s H  u  pXR                  U5      _M     snnn[        [
        U ]  XR                  U5      XSSUS9  XPl        X`l        US L=(       d    US LU l	        Xpl
        Xl        Xl        Xl        Xl        U R                  (       a6  U R                  (       d$  [!        SR#                  U R                  5      5      eg g s  snnf )NT)r  r  r  r  rM  r  r  zArgObject type listed required keys as {}. Keys can only be listed as required if `spec` or `key_type` arguments are provided to the ArgObject type.)r)  r;  r   r-  r  r%  r   	help_textrepeated_keyed_values_hiddenenable_shorthandenable_file_upload_disable_key_descriptionr'  r  r&   r,   )r   r  r  r  r  r0  r1  rs  r4  r5  disable_key_descriptionr'  r  r|   r   	spec_typer  s                   r   r   ArgObject.__init__P  s    
:&	;;=%U# ! 	 	I;?::<H<ZS!!%(	(<H  
)T#&9&9*&E4> $ ; NM!-AT1ADL,0$;! O$"4"4,,2F43E3E,FH H #5 	Is   &D1c                 @    U R                   =(       a    U R                  $ r   )r4  r2  r   s    r   parse_as_arg_dictArgObject.parse_as_arg_dicts  s      7T%7%77r   c                    [        U[        5      (       a@  U R                  (       a/  / nU H%  nU R                  XB5      nUR	                  U5        M'     U$ [        U[
        5      (       aO  U R                  (       a>  [        R                  " 5       nUR                  5        H  u  pdU" Xd5      u  pdXEU'   M     U$ U" SU5      u  ptU$ )aQ  Applies callback for arg_value.

Arg_value can be a dictionary, list, or other value.

Args:
  arg_value: can be a dictionary, list, or other value,
  callback: (key, val) -> key, val, function that accepts key and value
    and returns transformed values.

Returns:
  dictionary, list, or value with callback operation performed on it.
N)
r   rQ  r1  _Mapr>  r   r2  r	  r
  r   )r   r1  callbackr  r|   r  r   r   s           r   r>  ArgObject._Mapw  s     )T""t}}h%		%*  o)T""t'9'9((*h!)*#c)
 * oi(HALr   c                    Uc+  U R                   (       a  [        SR                  U5      5      eUb   [        U[        5      (       d  [	        U5      nUb+  [        U[        5      (       d  [
        R                  " U5      nX4$ )z$Returns string version of arguments.z*Expecting {} to be json or arg_dict format)r2  r    r,   r   r  jsondumpsr  s      r   _StringifyValuesArgObject._StringifyValues  sp    
{t))
6
=
=e
DF F z#s33HcE3!7!7jje:r   c                 8    U R                  XR                  5      $ r   )r>  rD  r   r1  s     r   _StringifyDictValuesArgObject._StringifyDictValues  s     99Y 5 566r   c                 >    U R                   =(       a    [        U5      $ r   )r5  r  rG  s     r   _CheckIfFileFormatArgObject._CheckIfFileFormat  s    ""H'=i'HHr   c                 6   SSK Jn   UR                  U5      n[        U[        5      (       a  U(       a  UR                  5       nOUn[        U[        5      (       d  g[        S UR                  5        5       5      (       a  gg! UR                   a     gf = f)z5Checks if arg_value can be loaded into a json object.r   r  Fc              3   (   #    U  H  oS L v   M
     g 7fr   r   )r  vals     r   r  /ArgObject._CheckIfJSONObject.<locals>.<genexpr>  s     9&8sd{&8s   T)
r  r  r  r   rQ  r=  r   allr;  YAMLParseError)r   r1  r  parsed_json	json_dicts        r   _CheckIfJSONObjectArgObject._CheckIfJSONObject  s     )IIi(k	K	&	&;OO%			4((9i&6&6&8999 s   AB %B BBc                     U R                   (       d  U R                  (       a  [        U5      nOUnU R                  U5      $ )zLoads json string or file into a dictionary.

Args:
  arg_value: str, path to a json or yaml file or json string

Returns:
  Dictionary [str: str] where the value is a json string or other String
    value
)r2  r1  r  rH  )r   r1  
json_values      r   r  ArgObject._LoadJSON  s3     T]]Y'jj$$Z00r   c                    > [        U[        5      (       a  U H  n[        [        U ]  U5        M     g [        [        U ]  U5        g r   )r   rQ  r  r%  r  )r   r  r|   r  s      r   r  ArgObject._CheckRequiredKeys  s:    (D!!%i1%8  It/9r   c                     U R                  XR                  5      nU R                  (       a  U R                  U5        U$ r   )r>  r  r  r  )r   r1  rH  s      r   _ParseAndValidateJSONArgObject._ParseAndValidateJSON  s2    YYy"8"89F
f%Mr   c                     SR                  U R                  R                  5       5      n[        R                  " SU S3U5      =(       d    U R
                  $ )N|())r1   r  r  r   searchr  )r   r1  r  s      r   _ContainsArgDictArgObject._ContainsArgDict  sA    
((4>>&&(
)C99qQZ+Bt/B/BBr   c                   > UR                  5       nUR                  S5      (       ac  UR                  S5      (       aM  U R                  (       a<  [	        USS SS9nU Vs/ s H!  o@R                  UR                  5       5      PM#     sn$ UR                  S5      (       a  UR                  S5      (       a  USS nOUn[        [        U ]#  U5      $ s  snf )	Nr6  r8  r4   r.  T)rM  r5  r7  )	r  r  r/  r1  rO  _ParseArgDictr  r%  rp  )r   r1  stripped_valuer;  rO  arg_dict_strr  s         r   rg  ArgObject._ParseArgDict  s    __&N!!#&&>+B+B3+G+GMM">!B#7tLf9?@#  -@@  %%.*A*A#*F*F#Ab)llD*<88 As    (Cc                     U R                   (       d  gSnX:H  =(       d.    U R                  U5      =(       a    U R                  U5      (       + $ )NFr<   )r;  rd  rU  )r   r1  empty_obj_shorthands      r   _CheckIfArgDictFormatArgObject._CheckIfArgDictFormat  sH    !!+ i( 	3''	22r   c                    [        U[        5      (       d  [        SR                  U5      5      eU R	                  U5      (       a.  [        U5      nU R                  U5      nU R                  U5      nOJU R                  U5      (       a  U R                  U5      nO"U R                  U5      nU R                  U5      nU R                  (       a  [        U[        5      (       d  U/nU$ )Nz6ArgObject can only convert string values. Received {}.)r   r  r"  r,   rK  r  r  r]  rm  rg  r1  rQ  )r   r1  file_contentrT  r|   s        r   rp  ArgObject.__call__  s    i%%
B
I
I  y))y)l...i((3e		#	#I	.	.   +e ..+i((3e}}Zt44geLr   c                 8   U R                   b  U R                   $ U R                  (       a*  [        S U R                  R                  5        5       5      $ [        R
                  " U R                  5      =(       d     [        R
                  " U R                  5      $ )Nc              3   N   #    U  H  n[         R                  " U5      v   M     g 7fr   )r  r  )r  r|   s     r   r  #ArgObject.hidden.<locals>.<genexpr>  s      L9K$$U++9Ks   #%)r3  r  rQ  r;  r  r  r  r  r   s    r   rs  ArgObject.hidden  si    ||\\	L9I9I9KLLL!!$--0 3!!$//24r   c                 P   > U R                   (       a  [        [        U ]  X5      $ U$ r   )r2  r  r%  rz  )r   rx  ry  r  s      r   rz  ArgObject.GetUsageMetavar   s$    9d34EOOnr   c                 |  ^	 U R                   (       a  gU=(       a    U R                  nU R                  nU R                  nU=(       d    U(       + =(       d    Um	U R                  bQ  T	(       a  SOSnU	4S j[        U R                  R                  5       5       5       nUR                  S U 5       5      nO9[        R                  " U R                  U R                  =(       d    [        T	5      nU(       + =(       d    U R                  (       + nU(       a  U(       a  SU-   S-   nU(       a  U(       a  SU-   S	-   nU$ )
aB  Returns a string of usage examples.

Recursively generates an example of expected user input.
For example, an ArgObject with spec={'x': int, 'y': str} will generate...

  x=int,y=string (shorthand) and
  {"x": int, "y": "string"} (json)

An ArgObject with key_type=str and value_type=str will generate...

  string=string (shorthand) and
  {"string": "string"} (json)

An ArgObject with value_type=str will always generate...

  string (shorthand and json)

Args:
  shorthand: bool, whether to display in shorthand

Returns:
  str | None, example text of usage. None if hidden.
Nr_   r0   c              3   V   >#    U  H  u  p[         R                  " XT5      v   M      g 7fr   r  )r  r   r|   format_as_shorthands      r   r  ,ArgObject.GetUsageExample.<locals>.<genexpr>K  s+      75jc 
-
-c:M
N
N5s   &)c              3   .   #    U  H  oc  M  Uv   M     g 7fr   r   r  lines     r   r  r{  N  s     F'$'   	r5  r7  r6  r8  )rs  r4  r2  r1  r  r   r   r1   r  r  r  r  r  r'  )
r   r  shorthand_enabledis_json_objis_arraycommaexampleusageinclude_bracketsrz  s
            @r   r  ArgObject.GetUsageExample&  s    0 {{!;d&;&;$$K}}H  +6h7L;Lyy(cde7"499??#457g jjF'FFe 11
--/C1DFe %};DOO(;'EkCe$EkCeLr   c                 |   U R                  SS9nU R                  (       d  U R                  (       a
  SnU SU 3nOU R                  nUn[        R                  " UUUS9n[        R                  " XR                  SS9S9n[        R                  " USS9nXV:X  a  SR                  XW5      $ S	R                  XVU5      $ )
z(Returns a string of user input examples.Tr  Fr_   )arg_namer1  r>  )r  r1  zpath_to_file.(yaml|json)z)*Input Example:*

{}

*File Example:*

{}zB*Shorthand Example:*

{}

*JSON Example:*

{}

*File Example:*

{})r  r2  r1  r  FormatCodeSnippetr,   )r   r  shorthand_snippetr>  snippetshorthand_examplejson_examplefile_examples           r   _GetCodeExamplesArgObject._GetCodeExamples]  s    ,,t,< $--f$%Q'8&9:g }}f!g"44
 //&:&:U&:&KML //&@BL (&'-v.?'NO&'-v#<(AAr   c                 <   [         R                  " XU R                  S9nU R                  (       dV  U R                  (       dE  [        U R                  [         R                  5      (       a  U R                  R                  X5      nOSnU(       a  XC:w  a  U SU 3$ U$ )+Returns a string of help text for the flag.)r0  N )	r  FormatHelpTextr0  r  r  r   r  ArgTypeUsager  )r   r  r  root_help_textadditional_help_texts        r   _FormatRootHelpTextArgObject._FormatRootHelpText~  s    ..8NIIMM4??J$;$;<<!__==
  " 4 Fq!5 677r   c                   ^  / nT R                   (       a@  U 4S j[        T R                   R                  5       5       5       nUR                  U5        U$ T R                  (       am  UR                  [        R                  " ST R                  5      5        UR                  [        R                  " ST R                  =(       d    [        5      5        U$ )r  c              3   p   >#    U  H+  u  p[         R                  " XUTR                  ;   5      v   M-     g 7fr   )r  GetNestedUsageHelpTextr  )r  r   rO  r   s      r   r  6ArgObject._GetKeyValueUsageHelpText.<locals>.<genexpr>  s5      53hc 
+
+CcT=O=O6O
P
P3s   36KEYVALUE)
r  r   r   extendr  r>  r  r  r  r  )r   rH  r   s   `  r   _GetKeyValueUsageHelpText#ArgObject._GetKeyValueUsageHelpText  s    Fyy5 !235e mmE M 
 mm

+
+E4==
ACmm

+
+GT__5K
LN Mr   c                 j   U R                   (       a  g/ nUR                  U R                  X5      5        U R                  (       d  UR	                  U R                  5       5        U(       a1  UR                  [        R                  U R                  U5      -   5        SR                  S U 5       5      $ )a  Returns a string of usage help text.

Recursively generates usage help text to provide the user with
more information on valid flag values and the general schema.
For example, ArgObject with...

  spec={
      'x': int,
      'y': arg_parsers.ArgObject(help_text='Y help.', spec={'z': str}),
  }

will generate the following by default...

  ```
  *x*
    Sets `z` value.

  *y*
    Y help.

    *z*
      Sets `z` value.
  ```

Args:
  field_name: str | None, field the flag of this type is setting
  required: bool, whether the flag of this type is required
  flag_name: str | None, the name of the flag. If not none, will generate
    code examples.

Returns:
  str | None, help text with schema and examples. None if hidden.
NrW  c              3   .   #    U  H  oc  M  Uv   M     g 7fr   r   r}  s     r   r  -ArgObject.GetUsageHelpText.<locals>.<genexpr>  s     Cttr  )
rs  r>  r  r6  r  r  r  ASCII_INDENTr  r1   )r   r  r  r  rH  s        r   r  ArgObject.GetUsageHelpText  s    D {{F
MM$**:@A ((mmD2245 mmJ++d.C.CI.NNO;;CCCCr   )r6  r3  r2  r5  r4  r0  r1  r'  )NNNNNFNTTFTFr   ) r   r   r   r   r   _file_path_patternr)  r-  r   r  r;  r>  rD  rH  rK  rU  r  r  r]  rd  rg  rm  rp  rs  rz  r  r  r  r  r  r   r"  r#  s   @r   r%  r%    s    GP -" ;?<AFJ9=#	!HF 8 8<
7I.1":C90 4 45nAB"&2D 2Dr   r%  c            	       \   ^  \ rS rSrSrS
S jrSSSSSSSS\4	U 4S jjrS rSS jrS	r	U =r
$ )UpdateActioni  a  Create a single dict value from delimited or repeated flags.

This class is intended to be a more flexible version of
argparse._AppendAction.

For example, with the following flag definition:

    parser.add_argument(
      '--inputs',
      type=arg_parsers.ArgDict(),
      action='append')

a caller can specify on the command line flags such as:

  --inputs k1=v1,k2=v2

and the result will be a list of one dict:

  [{ 'k1': 'v1', 'k2': 'v2' }]

Specifying two separate command line flags such as:

  --inputs k1=v1 \
  --inputs k2=v2

will produce a list of dicts:

  [{ 'k1': 'v1'}, { 'k2': 'v2' }]

The UpdateAction class allows for both of the above user inputs to result
in the same: a single dictionary:

  { 'k1': 'v1', 'k2': 'v2' }

This gives end-users a lot more flexibility in constructing their command
lines, especially when scripting calls.

Note that this class will raise an exception if a key value is specified
more than once. To allow for a key value to be specified multiple times,
use UpdateActionWithAppend.
Nc                     Uc  S nO;SR                  [        R                  " U5      [        R                  " U5      /5      n[        R                  " U [        SR                  U5      US95      e)Nr0   z("{0}" cannot be specified multiple timesr   )r1   r   r   argparseArgumentErrorr.   r,   )r   r   existing_valuerU  r*   s        r   OnDuplicateKeyRaiseError%UpdateAction.OnDuplicateKeyRaiseError  sj    j 99
--
'y)AC Dj

 
 6==cB!	#$ $r   Fc                 6  > US:X  a  [        S5      eUb0  U[        R                  :w  a  [        S[        R                  -  5      eXpl        [	        U[
        5      (       a  [        UR                  5       5      n[        [        U ]+  UUUUUUUUU	U
S9
  Xl        g )Nr   znargs for append actions must be > 0; if arg strings are not supplying the value to append, the append const action may be more appropriatez nargs must be %r to supply const)
option_stringsdestnargsconstrZ  r  r  r  helpry  )r"  r  OPTIONALr  r   r   r   r  r  r  r   onduplicatekey_handlerr   r  r  r  r  rZ  r  r  r  r  ry  r  r  s               r   r   UpdateAction.__init__  s     z I J J Uh&7&779H<M<MMNNL'4  w||~&g	,&% ' 
 #9r   c                 J    [        XS 5      c  [        XU5        [        X5      $ r   )getattrsetattr)r   	namespacenamer|   s       r   _EnsureValueUpdateAction._EnsureValue6  s$    y%-iu%9##r   c                     [        U[        5      (       a  [        R                  " U R                  X R                  [
        R                  " 5       5      5      n[        R                  " U5       H#  u  pgXe;   a  U R                  XXV   U5      nXuU'   M%     Ob[        R                  " U R                  X R                  / 5      5      nU H,  nXe;   a  U R                  X5        M  UR                  U5        M.     [        X R                  U5        g r   )r   r   copyr  r  r	  r
  r   r   r  r>  r  )r   r   r  r;  option_stringr   r   r   s           r   rp  UpdateAction.__call__<  s    &$ii


Iyy+2I2I2K
LNe --'$!:))$58Q?!a ( ii)))YYCDe!:

%
%d
.
,,q/	  Iyy%(r   )r  r  NNr   )r   r   r   r   r   r  r   r  rp  r   r"  r#  s   @r   r  r    s@    (T$* 5!9F$) )r   r  c            	       L   ^  \ rS rSrSrSS jrSSSSSSSS\4	U 4S jjrSrU =r$ )	UpdateActionWithAppendiU  aP  Create a single dict value from delimited or repeated flags.

This class provides a variant of UpdateAction, which allows for users to
append, rather than reject, duplicate key values. For example, the user
can specify:

  --inputs k1=v1a --inputs k1=v1b --inputs k2=v2

and the result will be:

   { 'k1': ['v1a', 'v1b'], 'k2': 'v2' }
Nc                 F    Uc  U$ [        U[        5      (       a  X#/-   $ X#/$ r   )r   rQ  )r   r   r  rU  s       r   OnDuplicateKeyAppend+UpdateActionWithAppend.OnDuplicateKeyAppendc  s.    j	ND	)	)k))((r   Fc                 <   > [         [        U ]  UUUUUUUUU	U
US9  g )N)r  r  r  r  rZ  r  r  r  r  ry  r  )r  r  r   r  s               r   r   UpdateActionWithAppend.__init__k  s;     

 $0%5 1 7r   r   r  )	r   r   r   r   r   r  r   r   r"  r#  s   @r   r  r  U  s4    ) 17 7r   r  c                   >   ^  \ rS rSrSrU 4S jrS rS rS rSr	U =r
$ )RemainderActioni  a  An action with a couple of helpers to better handle --.

argparse on its own does not properly handle -- implementation args.
argparse.REMAINDER greedily steals valid flags before a --, and nargs='*' will
bind to [] and not  parse args after --. This Action represents arguments to
be passed through to a subcommand after --.

Primarily, this Action provides two utility parsers to help a modified
ArgumentParser parse -- properly.

There is one additional property kwarg:
  example: A usage statement used to construct nice additional help.
c                   > US   [         R                  La  [        S5      eSR                  US   S9U l        SU;   a6  US==   SU R                  -   -  ss'   SU;   a  US==   S	US   -   -  ss'   US	 [
        [        U ]  " U0 UD6  g )
Nr  zFThe RemainderAction should only be used when nargs=argparse.REMAINDER.zhThe '--' argument must be specified between gcloud specific args on the left and {metavar} on the right.ry  )ry  r  z
+
r  z Example:

)r  	REMAINDERr"  r,   explanationr  r  r   r   r)  rd   r  s      r   r   RemainderAction.__init__  s    gh000 3 4 4
	/069% 17 1' 	 Vn$"2"222n	f	v/F9,===9	/4)4:6:r   c                 <    UR                  S5      nUS U XS-   S  4$ )N--r4   )index)r   r)  split_indexs      r   _SplitOnDashRemainderAction._SplitOnDash  s,    **T"Kt!O$4555r   c                 P    SnSU;   a  U R                  U5      u  pU " SX#5        X!4$ )z)Binds all args after -- to the namespace.Nr  )r  )r   r)  r  remainder_argss       r   ParseKnownArgsRemainderAction.ParseKnownArgs  s5     Nt|!..t4dy)?r   c                    SU;   a  U R                  U5      u  p4Sn[        [        [        U5      [        U5      5      5       H  u  nu  pxXx:w  d  M  [	        U5      U-
  n  O   XS n	USU nU	(       aA  SU R
                  -   R                  SR                  U	5      S9n
[        R                  " U
5      eU " SX)5        X!4$ )a  Parses the unrecognized args from the end of the remaining_args.

This method identifies all unrecognized arguments after the last argument
recognized by a parser (but before --). It then either logs a warning and
binds them to the namespace or raises an error, depending on strictness.

Args:
  remaining_args: A list of arguments that the parsers did not recognize.
  namespace: The Namespace to bind to.
  original_args: The full list of arguments given to the top parser,

Raises:
  ArgumentError: If there were remaining arguments after the last recognized
  argument and this action is strict.

Returns:
  A tuple of the updated namespace and unrecognized arguments (before the
  last recognized argument).
r  r   Nzunrecognized args: {args}
r  )r)  )
r  	enumerater   ro   ra   r  r,   r1   r   UnrecognizedArgumentsError)r   remaining_argsr  original_argsr   r  rr   arg1arg2pass_through_argsr  s              r   ParseRemainingArgs"RemainderAction.ParseRemainingArgs  s    , }**=9mK$H^$h}&=>@<D	.)A-	@
 '|4#L[1N*%v3884E+FvG 
44S99y,$$r   )r  )r   r   r   r   r   r   r  r  r  r   r"  r#  s   @r   r  r    s!    ;"6
'% '%r   r  c                 @   ^   " U 4S jS[         R                  5      nU$ )zCreates an action that concats flag values.

Args:
  dedup: bool, determines whether values in generated list should be unique

Returns:
  A custom argparse action that flattens the values before adding
  to namespace
c                   *   > \ rS rSrSrSU 4S jjrSrg)FlattenAction.<locals>.Actioni  a  Create a single list from delimited flags.

For example, with the following flag defition:

    parser.add_argument(
        '--inputs',
        type=arg_parsers.ArgObject(repeated=True),
        action=FlattenAction(dedup=True))

a caller can specify on the command line flags such as:

    --inputs '["v1", "v2"]' --inputs '["v3", "v4"]'

and the result will be one list of non-repeating values:

    ["v1", "v2", "v3", "v4"]

Recommend using this action with ArgObject where `repeated` is set to True.
This allows users to set the list either with append action or with
one json list. For example, all below examples result
in ["v1", "v2", "v3", "v4"]

    1) --inputs v1 --inputs v2 --inputs v3 --inputs v4
    2) --inputs '["v1", "v2", "v3", "v4"]'
Nc                    > [        X R                  S 5      n[        XS5      nT	(       a%  / nU H  nX;  d  M
  UR                  U5        M     Un[	        X R                  U5        g r   )r  r  rR  r>  r  )
r   r   r  r;  r  rS  
all_valuesdeduped_valuesr|   dedups
            r   rp  &FlattenAction.<locals>.Action.__call__	  sX    	99d;o7j	E(!!%(   $
iJ/r   r   r   )r   r   r   r   r   rp  r   )r  s   r   Actionr    s    4
0 
0r   r  r  r  )r  r  s   ` r   FlattenActionr    s    %0x %0N 
-r   c                   <   ^  \ rS rSrSrS rU 4S jrSS jrSrU =r	$ )StoreOnceActioni	  a  Action that disallows repeating a flag.

When using action='store' (the default), argparse allows multiple instances of
a flag to be specified with the last one determining the value and the rest
silently dropped. This is often undesirable if the command accepts only one
value but users try to repeat the flag (either accidentally, or when
mistakenly expecting the repeated values to be appended or merged somehow).

In such cases, one can instead use StoreOnceAction which disallows specifying
the same flag multiple times. So for instance, providing:

  --foo 123 --foo 456

will result in an error stating that --foo cannot be specified more than once.
c                 t    [         R                  " U [        SR                  U R                  5      5      5      e)Nz1"{0}" argument cannot be specified multiple times)r  r  r.   r,   r  r   s    r   OnSecondArgumentRaiseError*StoreOnceAction.OnSecondArgumentRaiseError%	  s5    

 
 ?FF			 r   c                 <   > SU l         [        [        U ]  " U0 UD6  g r   )dest_is_populatedr  r  r   r  s      r   r   StoreOnceAction.__init__,	  s    "D	/4)4:6:r   c                     U R                   (       a  U R                  5         SU l         [        X R                  U5        g NT)r  r  r  r  r   r   r  r;  r  s        r   rp  StoreOnceAction.__call__1	  s-    
%%'!DIyy&)r   r  r   )
r   r   r   r   r   r  r   rp  r   r"  r#  s   @r   r  r  	  s     ;
* *r   r  c                 D   ^ ^  " UU 4S jS[         R                  5      mT$ )a  Emits a warning message when a flag is specified more than once.

The created action is similar to StoreOnceAction. The difference is that
this action prints a warning message instead of raising an exception when the
flag is specified more than once. Because it is a breaking change to switch an
existing flag to StoreOnceAction, StoreOnceWarningAction can be used in the
deprecation period.

Args:
  flag_name: The name of the flag to apply this action on.

Returns:
  An Action class.
c                   F   >^  \ rS rSrSrU4S jrUU 4S jrSS jrSrU =r	$ )&StoreOnceWarningAction.<locals>.ActioniI	  z@Emits a warning message when a flag is specified more than once.c                 P   > [         R                  " SR                  T5      5        g )Nzt"{0}" argument is specified multiple times which will be disallowed in future versions. Please only specify it once.)r	   warningr,   )r   r  s    r   OnSecondArgumentPrintWarningCStoreOnceWarningAction.<locals>.Action.OnSecondArgumentPrintWarningL	  s    	kk==CVI=NPr   c                 4   > SU l         [        TU ]
  " U0 UD6  g r   )r  r  r   r   r)  rd   r  r  s      r   r   /StoreOnceWarningAction.<locals>.Action.__init__Q	  s    $dFD"D3F3r   c                     U R                   (       a  U R                  5         SU l         [        X R                  U5        g r  )r  r  r  r  r  s        r   rp  /StoreOnceWarningAction.<locals>.Action.__call__U	  s-    			))+#diF+r   r  r   )
r   r   r   r   r   r  r   rp  r   r"  )r  r  r  s   @r   r  r  I	  s    JP
4, ,r   r  r  )r  r  s   `@r   StoreOnceWarningActionr  9	  s     , ,x ,& 
-r   c                   6   ^  \ rS rSrSrU 4S jrSS jrSrU =r$ )_HandleNoArgActioni_	  zFThis class should not be used directly, use HandleNoArgAction instead.c                 F   > [         [        U ]
  " S0 UD6  Xl        X l        g )Nr   )r  r  r   none_argdeprecation_message)r   r  r  rd   r  s       r   r   _HandleNoArgAction.__init__b	  s!    	
d,6v6M2r   c                     UcG  [         R                  " U R                  5        U R                  (       a  [	        X R                  S5        [	        X R
                  U5        g r  )r	   r  r  r  r  r  )r   r   r  r|   r  s        r   rp  _HandleNoArgAction.__call__g	  s<    }	kk$**+		==$/Iyy%(r   )r  r  r   	r   r   r   r   r   r   rp  r   r"  r#  s   @r   r  r  _	  s    N3
) )r   r  c                    ^ ^ UU 4S jnU$ )a  Creates an argparse.Action that warns when called with no arguments.

This function creates an argparse action which can be used to gracefully
deprecate a flag using nargs=?. When a flag is created with this action, it
simply log.warning()s the given deprecation_message and then sets the value of
the none_arg to True.

This means if you use the none_arg no_foo and attach this action to foo,
`--foo` (no argument), it will have the same effect as `--no-foo`.

Args:
  none_arg: a boolean argument to write to. For --no-foo use "no_foo"
  deprecation_message: msg to tell user to stop using with no arguments.

Returns:
  An argparse action.

c                     > [        TT40 U D6$ r   )r  )rd   r  r  s    r   HandleNoArgActionInit0HandleNoArgAction.<locals>.HandleNoArgActionInit	  s    h(;FvFFr   r   )r  r  r  s   `` r   HandleNoArgActionr  p	  s    (G 
r   c                   N    \ rS rSrSrSS jr\S 5       rS rS r	SS jr
S	 rS
rg)r  i	  aP  Creates an argparse type that reads the contents of a file or stdin.

This is similar to argparse.FileType, but unlike FileType it does not leave
a dangling file handle open. The argument stored in the argparse Namespace
is the file's contents.

Attributes:
  binary: bool, If True, the contents of the file will be returned as bytes.
  default_help_text_disabled: bool, If True, the autogenerated help text will
    include additional information about how to use this file flag type.

Returns:
  A function that accepts a filename, or "-" representing that stdin should be
  used as input.
c                     Xl         X l        g r   binarydefault_help_text_disabled)r   r   r!  s      r   r   FileContents.__init__	  s    K&@#r   c                     gr   r   r   s    r   rs  FileContents.hidden	  ru  r   c                 8    U(       d  U R                   (       d  gU$ )a  Provides a more user friendly metavar for file contents.

`PATH_TO_FILE` is used as the default metavar for file contents flags only
when (1) a custom metavar is not provided and (2) the default help text is
enabled.

Args:
  is_custom_metavar: bool, True if the user provided a custom metavar.
  metavar: str, the metavar to use if a custom metavar was not provided.
Returns:
  The metavar to use for this file contents flag.
PATH_TO_FILE)r!  rw  s      r   rz  FileContents.GetUsageMetavar	  s     T%D%Dnr   c                     Ag)a:  Generates a usage example for file contents flags.

This default usage example is used to generate example input values.
This is currently just used to generate ArgObject help text examples.

Args:
  shorthand: bool, unused for file contents flags.

Returns:
  The example input value for this file contents flag.
path_to_filer   r  s     r   r  FileContents.GetUsageExample	  s
     	r   Nc                 f    AAU R                   (       d  [        R                  " SSU5      nSU S3$ g)a  Autogenerates additional help text for file contents flags.

Additional help text is only added when the default help text is enabled.

Args:
  field_name: str, the name of the field this flag is associated with.
  required: bool, True if this flag is required.
  flag_name: str, the name of the flag this help text is associated with.

Returns:
  Additional help text for this file contents flag.
z_from_file$r<   zDUse a full or relative path to a local file containing the value of r   N)r!  r   sub)r   r  r  r  sub_field_names        r   r  FileContents.GetUsageHelpText	  s@     	)**vvmR<nq"# r   c                      [         R                  " XR                  S9$ ! [        R                   a  n[        U5      eSnAff = f)a3  Return the contents of the file with the specified name.

If name is "-", stdin is read until EOF. Otherwise, the named file is read.

Args:
  name: str, The file name, or '-' to indicate stdin.

Returns:
  The contents of the file.

Raises:
  ArgumentTypeError: If the file cannot be read or is too large.
r   N)r   ReadFromFileOrStdinr   r   r   r    r   r  r   s      r   rp  FileContents.__call__	  s;    !++DEE;; !a  !s     A?Ar  )FFr   )r   r   r   r   r   r   r  rs  rz  r  r  rp  r   r   r   r   r  r  	  s5     A  $,!r   r  c                   4    \ rS rSrSrS	S jrS rS rS rSr	g)
YAMLFileContentsi	  a  Creates an argparse type that reads the contents of a YAML or JSON file.

This is similar to argparse.FileType, but unlike FileType it does not leave
a dangling file handle open. The argument stored in the argparse Namespace
is the file's contents parsed as a YAML object.

Attributes:
  validator: function, Function that will validate the provided input file
    contents.

Returns:
  A function that accepts a filename that should be parsed as a YAML
  or JSON file.
Nc                 T    U(       a  [        U5      (       d  [        S5      eXl        g )NzValidator must be callable)callabler    	validator)r   r8  s     r   r   YAMLFileContents.__init__	  s     ),,:;;Nr   c                     SSK Jn  UR                  U5      (       d1  UR                  U5      (       d  [	        SR                  U5      5      eg g )Nr   r  zInvalid YAML/JSON Data [{}])r  r  	dict_like	list_liker    r,   )r   	yaml_datar  s      r   _AssertJSONLike YAMLFileContents._AssertJSONLike
  sB    (NN9%%	)B)B;BB9MNN *C%r   c                 8   SSK Jn  US:X  a'  [        R                  " 5       nUR	                  U5      nOUR                  U5      nU Vs/ s H	  oUc  M  UPM     nn[        U5      S:X  a  US   $ US:X  a  UR                  W5      $ UR                  U5      $ s  snf )aw  Returns the yaml data for a file or from stdin for a single document.

YAML allows multiple documents in a single file by using `---` as a
separator between documents. See https://yaml.org/spec/1.1/#id857577.
However, some YAML-generating tools generate a single document followed by
this separator before ending the file.

This method supports the case of a single document in a file that contains
superfluous document separators, but still throws if multiple documents are
actually found.

Args:
  name: str, The file path to the file or "-" to read from stdin.

Returns:
  The contents of the file parsed as a YAML data object.
r   r  -r4   )	r  r  r   	ReadStdinload_allload_all_pathra   r  	load_path)r   r  r  stdinr=  r:   s         r   _LoadSingleYamlDocument(YAMLFileContents._LoadSingleYamlDocument

  s    & )s{""$e--&i$$T*i%7IqII7 9~q\ s{YYu^^D!! 8s   	BBc                 8   SSK Jn   U R                  U5      nU R                  U5        U R                  (       a0  U R	                  U5      (       d  [        SR                  U5      5      eU$ ! UR                  UR                  4 a  n[        U5      eSnAff = f)a  Load YAML data from file path (name) or stdin.

If name is "-", stdin is read until EOF. Otherwise, the named file is read.
If self.validator is set, call it on the yaml data once it is loaded.

Args:
  name: str, The file path to the file.

Returns:
  The contents of the file parsed as a YAML data object.

Raises:
  ArgumentTypeError: If the file cannot be read or is not a JSON/YAML like
    object.
  ValueError: If file content fails validation.
r   r  zInvalid YAML/JSON content [{}]N)
r  r  rG  r>  r8  r"  r,   rR  FileLoadErrorr    )r   r  r  r=  r   s        r   rp  YAMLFileContents.__call__1
  s    $ )
!..t4i
9%	~~i((;BB9MN
N!3!34 !a  !s   A$A- -B	BB)r8  r   )
r   r   r   r   r   r   r>  rG  rp  r   r   r   r   r5  r5  	  s    
O%"N!r   r5  c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )StoreTrueFalseActioniR
  av  Argparse action that acts as a combination of store_true and store_false.

Calliope already gives any bool-type arguments the standard and `--no-`
variants. In most cases we only want to document the option that does
something---if we have `default=False`, we don't want to show `--no-foo`,
since it won't do anything.

But in some cases we *do* want to show both variants: one example is when
`--foo` means "enable," `--no-foo` means "disable," and neither means "do
nothing." The obvious way to represent this is `default=None`; however, (1)
the default value of `default` is already None, so most boolean actions would
have this setting by default (not what we want), and (2) we still want an
option to have this True/False/None behavior *without* the flag documentation.

To get around this, we have an opt-in version of the same thing that documents
both the flag and its inverse.
c                 2   > [         [        U ]
  " USS 0UD6  g )NrZ  )r  rM  r   r  s      r   r   StoreTrueFalseAction.__init__e
  s    	
.MdMfMr   r   )r   r   r   r   r   r   r   r"  r#  s   @r   rM  rM  R
  s    $N Nr   rM  c                 D   ^ ^  " UU 4S jS[         R                  5      mT$ )zReturns Action that stores both file content and file path.

Args:
 binary: boolean, whether or not this is a binary file.

Returns:
 An argparse action.
c                   @   >^  \ rS rSrSrUU 4S jrSU4S jjrSrU =r$ ).StoreFilePathAndContentsAction.<locals>.Actionis
  z}Stores both file content and file path.

Stores file contents under original flag DEST and stores file path under
DEST_path.
c                 &   > [         TU ]  " U0 UD6  g r   )r  r   r
  s      r   r   7StoreFilePathAndContentsAction.<locals>.Action.__init__z
  s    FD"D3F3r   c                    >  [         R                  " UTS9n[        X R                  U5        SR                  U R                  5      n[        X'U5        g! [        R                   a  n[	        U5      eSnAff = f)z?Stores the contents of the file and the file name in namespace.r0  Nz{}_path)r   r1  r   r   r    r  r  r,   )	r   r   r  r|   r  contentr   new_destr   s	           r   rp  7StoreFilePathAndContentsAction.<locals>.Action.__call__}
  si    #00vF iG,!!$)),hi5)	 [[ #""#s   A A:*A55A:r   r   r  )r  r  r   s   @r   r  rR  s
  s    4* *r   r  r  )r   r  s   `@r   StoreFilePathAndContentsActionrY  i
  s    * *x *( 
-r   c                   6   ^  \ rS rSrSrU 4S jrSS jrSrU =r$ )ExtendConstActioni
  z*Extends the dest arg with a constant list.c                 2   > [         [        U ]
  " USS0UD6  g )Nr  r   )r  r[  r   r  s      r   r   ExtendConstAction.__init__
  s    	
T+TEEfEr   c                 t    [        X R                  / 5      n[        X R                  XPR                  -   5        g)z%Extends the dest with the const list.N)r  r  r  r  )r   r   r  r|   r  curs         r   rp  ExtendConstAction.__call__
  s'    
$		2
&CIyy#

"23r   r   r   r  r#  s   @r   r[  r[  
  s    2F4 4r   r[  c                   (    \ rS rSrSrSS jrS rSrg)FilePathOrStdinContentsi
  a  Creates an argparse type that stores a file path or the contents of stdin.

This is similar to FileContents above but only reads content from stdin,
otherwise just stores the file/directory path.

Attributes:
  binary: bool, If True, the contents of the file will be returned as bytes.

Returns:
  A function that accepts a filename, or "-" representing that stdin should be
  used as input.
c                     Xl         g r   r0  )r   r   s     r   r    FilePathOrStdinContents.__init__
  s    Kr   c                      US:X  a  [         R                  " XR                  S9$ [        R                  " U5      $ ! [        R
                   a  n[        U5      eSnAff = f)aF  Return the contents of stdin or the filepath specified.

If name is "-", stdin is read until EOF. Otherwise, the named file path is
returned.

Args:
  name: str, The file name, or '-' to indicate stdin.

Returns:
  The contents of stdin or the file path.

Raises:
  ArgumentTypeError: If stdin cannot be read or is too large.
rA  r0  N)r   r1  r   r   ExpandHomeAndVarsr   r    r2  s      r   rp   FilePathOrStdinContents.__call__
  sS    !	--d;;GG$$T**;; !a  !s   #< < A AA r0  Nr   )r   r   r   r   r   r   rp  r   r   r   r   rb  rb  
  s    !r   rb  r  )rK   )NNTrK   Nr   )r7   0Nr7   )NNNr?   rK   r  )r_   F)FT)Tr   )gr   
__future__r   r   r   r  r	  r  rS   rB  r   dateutilr   googlecloudsdk.callioper   r  r   r  r	   r
   googlecloudsdk.core.consoler   r   googlecloudsdk.core.utilr   r   r   	six.movesr   __all__	Exceptionr   r    r  r#   r&   r.   r3   r   r   _SECOND_MINUTE_HOUR_DAY_DURATION_SCALESrv   rW   r\   rl   rt   rx   r   r   r   r   r   _KV_PAIR_DELIMITERobjectr   r   r  r	  r  r&  r*  r,  r3  rE  rK  rO  rR  r\  r^  r  r`  r,  r  r  r  r  r  r  r  r  r  r%  r  r  r  _StoreActionr  r  r  r  r  r  r  r5  _StoreTrueActionrM  rY  r[  rb  r   r   r   <module>rz     s   D '  '      	  H 1 # * 4 2 * * 
 |
$4I 4@x99 @5("8"8 Fu FH0' ;

w,
W	Ez
 
				  	
					




  




 $0,'* "!!.2l!^:%P W!t  ,0	7At  /2F /2d4Av 4An&  v < , "! 	:z:I%.%P-5` "f "/((' /f BF:>	(4#&!j%%w &!Rjj%%w jZ# S S eg eP\D \D~{)8?? {)|.7\ .7bV%h++ V%r2j"*hoo "*J#L) )"4a!:** a!Ha!v a!HN844 N.B	4 	4%!f %!r   