a
    Sic                     @   s   d Z ddlZddlZddlZddlZddlZddlmZmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZ ddlmZ ejeeje  ed	ZG d
d dZe ZG dd dee Zdd Zdd ZdS )zDefines the FlagValues class - registry of 'Flag' objects.

Do NOT import this module directly. Import the flags package and use the
aliases defined at the package level instead.
    N)GenericTypeVar)minidom)_exceptions)_flag)_helpers)_validators_classes_Tc                   @   s  e Zd ZdZdd ZdddZdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd d!Zdd"d#Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Z d>d? Z!d@dA Z"dBdC Z#dDdE Z$dFdG Z%ddIdJZ&dKdL Z'dMdN Z(dOdP Z)dQdR Z*dSdT Z+dUdV Z,dWdX Z-dYdZ Z.d[d\ Z/d]d^ Z0dd`daZ1dbdc Z2ddddeZ3ddfdgZ4ddhdiZ5djdk Z6dldm Z7ddodpZ8dqdr Z9dsdt Z:dudv Z;ddwdxZ<ddydzZ=d{d| Z>d}d~ Z?dddZ@dd ZAdS )
FlagValuesa  Registry of :class:`~absl.flags.Flag` objects.

  A :class:`FlagValues` can then scan command line arguments, passing flag
  arguments through to the 'Flag' objects that it owns.  It also
  provides easy access to the flag values.  Typically only one
  :class:`FlagValues` object is needed by an application:
  :const:`FLAGS`.

  This class is heavily overloaded:

  :class:`Flag` objects are registered via ``__setitem__``::

       FLAGS['longname'] = x   # register a new flag

  The ``.value`` attribute of the registered :class:`~absl.flags.Flag` objects
  can be accessed as attributes of this :class:`FlagValues` object, through
  ``__getattr__``.  Both the long and short name of the original
  :class:`~absl.flags.Flag` objects can be used to access its value::

       FLAGS.longname  # parsed flag value
       FLAGS.x  # parsed flag value (short name)

  Command line arguments are scanned and passed to the registered
  :class:`~absl.flags.Flag` objects through the ``__call__`` method.  Unparsed
  arguments, including ``argv[0]`` (e.g. the program name) are returned::

       argv = FLAGS(sys.argv)  # scan command line arguments

  The original registered :class:`~absl.flags.Flag` objects can be retrieved
  through the use of the dictionary-like operator, ``__getitem__``::

       x = FLAGS['longname']   # access the registered Flag object

  The ``str()`` operator of a :class:`absl.flags.FlagValues` object provides
  help for all of the registered :class:`~absl.flags.Flag` objects.
  c                 C   s   i | j d< t | j d< i | j d< i | j d< i | j d< d| j d< d| j d< d | j d	< ttt| j d
< d| j d< d| j d< d | j d< d S )N__flags__hiddenflags__flags_by_module__flags_by_module_id__key_flags_by_moduleF__flags_parsed__unparse_flags_called__set_unknown__banned_flag_namesT__use_gnu_getopt__use_gnu_getopt_explicitly_set__is_retired_flag_func)__dict__set	frozensetdirr
   self r   R/var/www/html/django/DPS/env/lib/python3.9/site-packages/absl/flags/_flagvalues.py__init__S   s    








zFlagValues.__init__Tc                 C   s   || j d< d| j d< dS )a  Sets whether or not to use GNU style scanning.

    GNU style allows mixing of flag and non-flag arguments. See
    http://docs.python.org/library/getopt.html#getopt.gnu_getopt

    Args:
      gnu_getopt: bool, whether or not to use GNU style scanning.
    r   Tr   Nr   )r   
gnu_getoptr   r   r   set_gnu_getopt   s    	
zFlagValues.set_gnu_getoptc                 C   s
   | j d S )Nr   r    r   r   r   r   is_gnu_getopt   s    zFlagValues.is_gnu_getoptc                 C   s
   | j d S Nr   r    r   r   r   r   _flags   s    zFlagValues._flagsc                 C   s
   | j d S )zReturns the dictionary of module_name -> list of defined flags.

    Returns:
      A dictionary.  Its keys are module names (strings).  Its values
      are lists of Flag objects.
    r   r    r   r   r   r   flags_by_module_dict   s    zFlagValues.flags_by_module_dictc                 C   s
   | j d S )zReturns the dictionary of module_id -> list of defined flags.

    Returns:
      A dictionary.  Its keys are module IDs (ints).  Its values
      are lists of Flag objects.
    r   r    r   r   r   r   flags_by_module_id_dict   s    z"FlagValues.flags_by_module_id_dictc                 C   s
   | j d S )zReturns the dictionary of module_name -> list of key flags.

    Returns:
      A dictionary.  Its keys are module names (strings).  Its values
      are lists of Flag objects.
    r   r    r   r   r   r   key_flags_by_module_dict   s    z#FlagValues.key_flags_by_module_dictc                 C   s   |   }||g | dS )a#  Records the module that defines a specific flag.

    We keep track of which flag is defined by which module so that we
    can later sort the flags by module.

    Args:
      module_name: str, the name of a Python module.
      flag: Flag, the Flag instance that is key to the module.
    N)r&   
setdefaultappend)r   module_nameflagflags_by_moduler   r   r   register_flag_by_module   s    
z"FlagValues.register_flag_by_modulec                 C   s   |   }||g | dS )zRecords the module that defines a specific flag.

    Args:
      module_id: int, the ID of the Python module.
      flag: Flag, the Flag instance that is key to the module.
    N)r'   r)   r*   )r   	module_idr,   Zflags_by_module_idr   r   r   register_flag_by_module_id   s    z%FlagValues.register_flag_by_module_idc                 C   s*   |   }||g }||vr&|| dS )zSpecifies that a flag is a key flag for a module.

    Args:
      module_name: str, the name of a Python module.
      flag: Flag, the Flag instance that is key to the module.
    N)r(   r)   r*   )r   r+   r,   Zkey_flags_by_module	key_flagsr   r   r   register_key_flag_for_module   s    z'FlagValues.register_key_flag_for_modulec                 C   sH   |   }|j}||d|kr"dS |j}|durD||d|krDdS dS )zChecks whether a Flag object is registered under long name or short name.

    Args:
      flag_obj: Flag, the Flag instance to check for.

    Returns:
      bool, True iff flag_obj is registered under long name or short name.
    NTF)r%   nameget
short_name)r   flag_obj	flag_dictr3   r5   r   r   r   _flag_is_registered   s    	zFlagValues._flag_is_registeredc                 C   sP   |  |rdS |  |  |  fD ]&}| D ]}||v r0|| q4q0q$dS )a  Cleans up unregistered flags from all module -> [flags] dictionaries.

    If flag_obj is registered under either its long name or short name, it
    won't be removed from the dictionaries.

    Args:
      flag_obj: Flag, the Flag instance to clean up for.
    N)r8   r&   r'   r(   valuesremove)r   r6   r&   Zflags_in_moduler   r   r   ,_cleanup_unregistered_flag_from_module_dicts   s    	
z7FlagValues._cleanup_unregistered_flag_from_module_dictsc                 C   s6   t |ts|j}|dkr"tjd }t|  |g S )a1  Returns the list of flags defined by a module.

    Args:
      module: module|str, the module to get flags from.

    Returns:
      [Flag], a new list of Flag instances.  Caller may update this list as
      desired: none of those changes will affect the internals of this
      FlagValue instance.
    __main__r   )
isinstancestr__name__sysargvlistr&   r4   )r   moduler   r   r   get_flags_for_module   s
    

zFlagValues.get_flags_for_modulec                 C   sX   t |ts|j}|dkr"tjd }| |}|  |g D ]}||vr<|| q<|S )a2  Returns the list of key flags for a module.

    Args:
      module: module|str, the module to get key flags from.

    Returns:
      [Flag], a new list of Flag instances.  Caller may update this list as
      desired: none of those changes will affect the internals of this
      FlagValue instance.
    r<   r   )	r=   r>   r?   r@   rA   rD   r(   r4   r*   )r   rC   r1   r,   r   r   r   get_key_flags_for_module  s    


z#FlagValues.get_key_flags_for_moduleNc                 C   sb   |   |}|du r|S |   D ]6\}}|D ](}|j|jkr2|j|jkr2|    S q2q&|S )a~  Return the name of the module defining this flag, or default.

    Args:
      flagname: str, name of the flag to lookup.
      default: Value to return if flagname is not defined. Defaults to None.

    Returns:
      The name of the module which registered the flag with this name.
      If no such module exists (i.e. no flag with this name exists),
      we return default.
    N)r%   r4   r&   itemsr3   r5   )r   flagnamedefaultregistered_flagrC   flagsr,   r   r   r   find_module_defining_flag(  s    
z$FlagValues.find_module_defining_flagc                 C   sb   |   |}|du r|S |   D ]6\}}|D ](}|j|jkr2|j|jkr2|    S q2q&|S )az  Return the ID of the module defining this flag, or default.

    Args:
      flagname: str, name of the flag to lookup.
      default: Value to return if flagname is not defined. Defaults to None.

    Returns:
      The ID of the module which registered the flag with this name.
      If no such module exists (i.e. no flag with this name exists),
      we return default.
    N)r%   r4   r'   rF   r3   r5   )r   rG   rH   rI   r/   rJ   r,   r   r   r   find_module_id_defining_flagA  s    
z'FlagValues.find_module_id_defining_flagc                 C   s   || j d< dS )zAllow set default values for undefined flags.

    Args:
      setter: Method(name, value) to call to __setattr__ an unknown flag. Must
        raise NameError or ValueError for invalid name/value.
    r   Nr    )r   setterr   r   r   _register_unknown_flag_setterZ  s    z(FlagValues._register_unknown_flag_setterc              	   C   sh   | j d }|rXz||| |W S  ttfyF   td||Y n tyV   Y n0 t||dS )a  Returns value if setting flag |name| to |value| returned True.

    Args:
      name: str, name of the flag to set.
      value: Value to set.

    Returns:
      Flag value on successful call.

    Raises:
      UnrecognizedFlagError
      IllegalFlagValueError
    r   z"{1}" is not valid for --{0}N)r   	TypeError
ValueErrorr   IllegalFlagValueErrorformat	NameErrorUnrecognizedFlagError)r   r3   valuerM   r   r   r   _set_unknown_flagc  s    


zFlagValues._set_unknown_flagc              	   C   sX   |   D ]F\}}||jkrz|| |< W q tjyP   tjj|| |dY q0 qdS )zAppends flags registered in another FlagValues instance.

    Args:
      flag_values: FlagValues, the FlagValues instance from which to copy flags.
    )other_flag_valuesN)r%   rF   r3   r   DuplicateFlagError	from_flag)r   flag_values	flag_namer,   r   r   r   append_flag_values}  s    
zFlagValues.append_flag_valuesc                 C   s   |D ]}|  | qdS )zRemove flags that were previously appended from another FlagValues.

    Args:
      flag_values: FlagValues, the FlagValues instance containing flags to
        remove.
    N)__delattr__)r   rZ   r[   r   r   r   remove_flag_values  s    zFlagValues.remove_flag_valuesc           	      C   s  |   }t|tjst|t|ts2td|s@tdd|v rRtd| || ||v r|j	s|| j	st
 \}}| ||krt|| |krdS tj|| |j}t }|dur||v r|j	s|| j	stj|| ||v r|| |kr|||  |||< ||vs<|| js<|jsj||v rb|| |krb|||  |||< |D ]}| | qndS )zRegisters a new flag variable.zFlag name must be a stringzFlag name cannot be empty z Flag name cannot contain a spaceN)r%   r=   r   Flagr   rQ   r>   Error_check_method_name_conflictsallow_overrider   "get_calling_module_object_and_namerK   idrL   rX   rY   r5   r   addusing_default_valuer;   )	r   r3   r,   flrC   r+   r5   Zflags_to_cleanupfr   r   r   __setitem__  sJ    






zFlagValues.__setitem__c                 C   s   t | jd S )zReturns list of names of all defined flags.

    Useful for TAB-completion in ipython.

    Returns:
      [str], a list of names of all defined flags.
    r   )sortedr   r   r   r   r   __dir__  s    zFlagValues.__dir__c                 C   s   |   | S )z,Returns the Flag object for the flag --name.r%   r   r3   r   r   r   __getitem__  s    zFlagValues.__getitem__c                 C   s   | j d | dS )z Marks the flag --name as hidden.r   N)r   rf   rn   r   r   r   
_hide_flag  s    zFlagValues._hide_flagc                 C   s^   |   }||vrt||| jd v r.t|| jd sB|| jrL|| jS td| dS )z3Retrieves the 'value' attribute of the flag --name.r   r   z4Trying to access flag --%s before flags were parsed.N)r%   AttributeErrorr   presentrU   r   UnparsedFlagAccessError)r   r3   rh   r   r   r   __getattr__  s    
zFlagValues.__getattr__c                 C   s   | j f i ||i |S )z.Sets the 'value' attribute of the flag --name.)_set_attributes)r   r3   rU   r   r   r   __setattr__  s    zFlagValues.__setattr__c                 K   s   |   }t }| D ]H\}}|| jd v r4t|||v rR||| _|| q| || q|D ]}| || j	 d|| _
qddS )zCSets multiple flag values together, triggers validators afterwards.r   FN)r%   r   rF   r   rq   rU   rf   rV   _assert_validators
validatorsrg   )r   
attributesrh   Zknown_flagsr3   rU   r   r   r   ru     s    
zFlagValues._set_attributesc                 C   s2   t  }|   D ]}||j q| | dS )zVerifies whether all flags pass validation.

    Raises:
      AttributeError: Raised if validators work with a non-existing flag.
      IllegalFlagValueError: Raised if validation fails for at least one
          validator.
    N)r   r%   r9   updaterx   rw   )r   Zall_validatorsr,   r   r   r   validate_all_flags  s    zFlagValues.validate_all_flagsc                 C   s   g }t  }t|dd dD ]}zHt|tjr<|j|v rZW qnt|tjrZ|t |j@ rZW q||  W q t	j
y } zbt|tjr||j nt|tjr|t |j || }|d|t|f  W Y d}~qd}~0 0 q|rt	d|dS )a  Asserts if all validators in the list are satisfied.

    It asserts validators in the order they were created.

    Args:
      validators: Iterable(validators.Validator), validators to be verified.

    Raises:
      AttributeError: Raised if validators work with a non-existing flag.
      IllegalFlagValueError: Raised if validation fails for at least one
          validator.
    c                 S   s   | j S N)Zinsertion_index)	validatorr   r   r   <lambda>      z/FlagValues._assert_validators.<locals>.<lambda>keyz%s: %sN
)r   rk   r=   r   ZSingleFlagValidatorr[   ZMultiFlagsValidator
flag_namesverifyr   ValidationErrorrf   rz   Zprint_flags_with_valuesr*   r>   rQ   join)r   rx   messagesZ	bad_flagsr}   emessager   r   r   rw     s,    


.zFlagValues._assert_validatorsc                 C   s4   |   }||vrt||| }||= | | dS )a  Deletes a previously-defined flag from a flag object.

    This method makes sure we can delete a flag by using

      del FLAGS.<flag_name>

    E.g.,

      flags.DEFINE_integer('foo', 1, 'Integer flag.')
      del flags.FLAGS.foo

    If a flag is also registered by its the other name (long name or short
    name), the other name won't be deleted.

    Args:
      flag_name: str, the name of the flag to be deleted.

    Raises:
      AttributeError: Raised when there is no registered flag named flag_name.
    N)r%   rq   r;   )r   r[   rh   r6   r   r   r   r]   '  s    zFlagValues.__delattr__c                 C   sB   |   }||vr | || dS || | | || j dS )a  Changes the default value of the named flag object.

    The flag's current value is also updated if the flag is currently using
    the default value, i.e. not specified in the command line, and not set
    by FLAGS.name = value.

    Args:
      name: str, the name of the flag to modify.
      value: The new default value.

    Raises:
      UnrecognizedFlagError: Raised when there is no registered flag named name.
      IllegalFlagValueError: Raised when value is not valid.
    N)r%   rV   _set_defaultrw   rx   )r   r3   rU   rh   r   r   r   set_defaultE  s    zFlagValues.set_defaultc                 C   s   ||   v S )z3Returns True if name is a value (flag) in the dict.rm   rn   r   r   r   __contains__[  s    zFlagValues.__contains__c                 C   s   t | jd S r$   )lenr   r   r   r   r   __len___  s    zFlagValues.__len__c                 C   s   t |  S r|   )iterr%   r   r   r   r   __iter__b  s    zFlagValues.__iter__Fc           
      C   s   t |ttfrtd|s"td|d }| j|dd dd}| ||\}}|D ](\}}t|t	| }	t
j|||	dqT|   |   |g| S )	aD  Parses flags from argv; stores parsed flags into this FlagValues object.

    All unparsed arguments are returned.

    Args:
       argv: a tuple/list of strings.
       known_only: bool, if True, parse and remove known flags; return the rest
         untouched. Unknown flags specified by --undefok are not returned.

    Returns:
       The list of arguments not parsed as options, including argv[0].

    Raises:
       Error: Raised on any parsing error.
       TypeError: Raised on passing wrong type of arguments.
       ValueError: Raised on flag value parsing error.
    z<argv should be a tuple/list of strings, not bytes or string.zUargv cannot be an empty list, and must contain the program name as the first element.r      NF)	force_gnu)suggestions)r=   r>   bytesrO   rP   read_flags_from_files_parse_argsr   get_flag_suggestionsrB   r   rT   mark_as_parsedr{   )
r   rA   
known_onlyprogram_nameargsunknown_flagsunparsed_argsr3   rU   r   r   r   r   __call__e  s&    zFlagValues.__call__c                 C   s   t dd S )Nzcan't pickle FlagValuesrO   r   r   r   r   __getstate__  s    zFlagValues.__getstate__c                 C   s   t dd S )Nz`FlagValues does not support shallow copies. Use absl.testing.flagsaver or copy.deepcopy instead.r   r   r   r   r   __copy__  s    zFlagValues.__copy__c                 C   s(   t t| }|jt| j| |S r|   )object__new__typer   rz   copydeepcopy)r   memoresultr   r   r   __deepcopy__  s    zFlagValues.__deepcopy__c                 C   s   || j d< dS )aL  Sets a function for checking retired flags.

    Do not use it. This is a private absl API used to check retired flags
    registered by the absl C++ flags library.

    Args:
      is_retired_flag_func: Callable(str) -> (bool, bool), a function takes flag
        name as parameter, returns a tuple (is_retired, type_is_bool).
    r   Nr    )r   Zis_retired_flag_funcr   r   r   _set_is_retired_flag_func  s    
z$FlagValues._set_is_retired_flag_funcc                    s  g }t  }| jd }|  }tD ]D d fdd} dsl|d f |  rfq(n qp dkr|r|d f  qp dr dd }n dd }d	|v r|d	d\}	n
|d }	|	s|d f |  rq(n qp|	d
kr>| |dd dD  |dd dD  q(|	|	}
|
durr|
j
rjdu rjdn| n\|	drt|	dkr|	|	dd }|dur|j
rΈdurt d |}
d|rD|
du rD||	\}}|s|	dr||	dd \}}|o|}|rD|s6du r6|  td|	 q(|
dur`|
 d|
_q(||	 f q(g }g }|D ]P\}	 |	du r|  n0|	|v rq|n |r|  n||	 f q||t ||fS )a  Helper function to do the main argument parsing.

    This function goes through args and does the bulk of the flag parsing.
    It will find the corresponding flag in our flag dictionary, and call its
    .parse() method on the flag value.

    Args:
      args: [str], a list of strings with the arguments to parse.
      known_only: bool, if True, parse and remove known flags; return the rest
        untouched. Unknown flags specified by --undefok are not returned.

    Returns:
      A tuple with the following:
          unknown_flags: List of (flag name, arg) for flags we don't know about.
          unparsed_args: List of arguments we did not parse.

    Raises:
       Error: Raised on any parsing error.
       ValueError: Raised on flag value parsing error.
    r   Nc                      s<   zd u rt nW S  ty6   td  Y n0 d S )NzMissing value for flag )nextStopIterationr   ra   r   argr   rU   r   r   	get_value  s    z)FlagValues._parse_args.<locals>.get_value---   r   =undefokc                 s   s   | ]}|  V  qd S r|   strip.0vr   r   r   	<genexpr>  r   z)FlagValues._parse_args.<locals>.<genexpr>,c                 s   s   | ]}d |   V  qdS )noNr   r   r   r   r   r     r   truer   z does not take an argumentfalsezGFlag "%s" is retired and should no longer be specified. See go/totw/90.F)r   r   r%   r   
startswithr*   r#   splitrz   r4   booleanr   rP   loggingerrorparserg   extendrB   )r   r   r   Zunparsed_names_and_argsr   Zretired_flag_funcr7   r   Zarg_without_dashesr3   r,   ZnoflagZ
is_retiredZis_boolr   r   r   r   r   r     s    













zFlagValues._parse_argsc                 C   s
   | j d S )z"Returns whether flags were parsed.r   r    r   r   r   r   	is_parsed1  s    zFlagValues.is_parsedc                 C   s   d| j d< dS )a  Explicitly marks flags as parsed.

    Use this when the caller knows that this FlagValues has been parsed as if
    a ``__call__()`` invocation has happened.  This is only a public method for
    use by things like appcommands which do additional command like parsing.
    Tr   Nr    r   r   r   r   r   5  s    zFlagValues.mark_as_parsedc                 C   s<   |    D ]}|  qtd d| jd< d| jd< dS )zBUnparses all flags to the point before any FLAGS(argv) was called.z;unparse_flags() called; flags access will now raise errors.Fr   Tr   N)r%   r9   unparser   infor   )r   ri   r   r   r   unparse_flags>  s
    


zFlagValues.unparse_flagsc                 C   s   dd |    D S )z9Returns a dictionary that maps flag names to flag values.c                 S   s   i | ]\}}||j qS r   )rU   )r   r3   r,   r   r   r   
<dictcomp>J  r   z/FlagValues.flag_values_dict.<locals>.<dictcomp>)r%   rF   r   r   r   r   flag_values_dictH  s    zFlagValues.flag_values_dictc                 C   s   |   S )z*Returns a help string for all known flags.)get_helpr   r   r   r   __str__L  s    zFlagValues.__str__ c                 C   s   |   }|rHt|}tjd }||v r:|| |g| }| |||S g }|   }|rrt	|t
j  }| ||| d|S dS )a  Returns a help string for all known flags.

    Args:
      prefix: str, per-line output prefix.
      include_special_flags: bool, whether to include description of
        SPECIAL_FLAGS, i.e. --flagfile and --undefok.

    Returns:
      str, formatted help message.
    r   r   N)r&   rk   r@   rA   r:   _get_help_for_modulesr%   r9   	itertoolschainr   SPECIAL_FLAGS_render_flag_listr   )r   prefixinclude_special_flagsr-   modulesZmain_moduleoutput_linesr9   r   r   r   r   P  s     


zFlagValues.get_helpc                 C   sD   g }|D ]}|  ||| q|r:| dtj  || d|S )ap  Returns the help string for a list of modules.

    Private to absl.flags package.

    Args:
      modules: List[str], a list of modules to get the help string for.
      prefix: str, a string that is prepended to each generated help line.
      include_special_flags: bool, whether to include description of
        SPECIAL_FLAGS, i.e. --flagfile and --undefok.
    z
absl.flagsr   )_render_our_module_flags_render_module_flagsr   r   r%   r9   r   )r   r   r   r   r   rC   r   r   r   r   n  s    z FlagValues._get_help_for_modulesc                 C   s8   t |ts|j}|d||f  | |||d  dS ))Returns a help string for a given module.z
%s%s:  N)r=   r>   r?   r*   r   )r   rC   rJ   r   r   r   r   r   r     s    
zFlagValues._render_module_flagsc                 C   s"   |  |}|r| |||| dS )r   N)rD   r   )r   rC   r   r   rJ   r   r   r   r     s    
z#FlagValues._render_our_module_flagsc                 C   s"   |  |}|r| |||| dS )aJ  Returns a help string for the key flags of a given module.

    Args:
      module: module|str, the module to render key flags for.
      output_lines: [str], a list of strings.  The generated help message lines
        will be appended to this list.
      prefix: str, a string that is prepended to each generated help line.
    N)rE   r   )r   rC   r   r   r1   r   r   r   _render_our_module_key_flags  s    	
z'FlagValues._render_our_module_key_flagsc                 C   s   g }|  || d|S )zDescribes the key flags of a module.

    Args:
      module: module|str, the module to describe the key flags for.

    Returns:
      str, describing the key flags of a module.
    r   )r   r   )r   rC   Zhelplistr   r   r   module_help  s    	zFlagValues.module_helpc                 C   s   |  tjd S )zvDescribes the key flags of the main module.

    Returns:
      str, describing the key flags of the main module.
    r   )r   r@   rA   r   r   r   r   main_module_help  s    zFlagValues.main_module_helpr   c           
      C   sB  |   }tj  }dd |D }|  i }|D ]
\}}||d |kr\||d |kr\q0||v rfq0d||< d}	|jr|	d|j 7 }	|jr|	d|j 7 }	n|	d|j 7 }	|	d7 }	|jr|	|j7 }	tj	|	|d	 |d
}	|j
r|	d7 }	|	tj	d|j
 |d	 d7 }	|jjr2|	d7 }	|	tj	d|jj |d	 d7 }	||	 q0d S )Nc                 S   s   g | ]}|j |fqS r   r3   )r   r,   r   r   r   
<listcomp>  r   z0FlagValues._render_flag_list.<locals>.<listcomp>r   r   z-%s,z	--[no]%s:z--%s:r_   r   )indentfirstline_indentr   z(default: %s))r   z(%s))r%   r   r   sortr4   r5   r   r3   help	text_wrapdefault_as_strparsersyntactic_helpr*   )
r   flaglistr   r   rh   Z
special_flZflagsetr3   r,   Zflaghelpr   r   r   r     sD    
 


zFlagValues._render_flag_listc                 C   s   |  |}|dur|S |S dS )zReturns the value of a flag (if not None) or a default value.

    Args:
      name: str, the name of a flag.
      default: Default value to use if the flag value is None.

    Returns:
      Requested flag value or default.
    N)rt   )r   r3   rH   rU   r   r   r   get_flag_value  s    
zFlagValues.get_flag_valuec                 C   sF   t |trB|drdS |dkr$dS |dr2dS |dkr>dS dS dS )z@Checks whether flag_string contain a --flagfile=<foo> directive.--flagfile=r   
--flagfile
-flagfile=	-flagfiler   )r=   r>   r   )r   Zflag_stringr   r   r   _is_flag_file_directive  s    


z"FlagValues._is_flag_file_directivec                 C   s^   | dr&tj|tdd  S | drLtj|tdd  S td| dS )a  Returns filename from a flagfile_str of form -[-]flagfile=filename.

    The cases of --flagfile foo and -flagfile foo shouldn't be hitting
    this function, as they are dealt with in the level above this
    function.

    Args:
      flagfile_str: str, the flagfile string.

    Returns:
      str, the filename from a flagfile_str of form -[-]flagfile=filename.

    Raises:
      Error: Raised when illegal --flagfile is provided.
    r   Nr   zHit illegal --flagfile type: %s)r   ospath
expanduserr   r   r   ra   )r   Zflagfile_strr   r   r   _extract_filename  s
    

zFlagValues._extract_filenamec           
   
   C   s&  |sg S |du rg }||v r2t jd|f  g S || g }g }zt|d}W n2 ty } ztd| W Y d}~n
d}~0 0 | | }W d   n1 s0    Y  |D ]b}|	 rq|
ds|
drq| |r
| |}| j||d}	||	 q||  q|  |S )a  Returns the useful (!=comments, etc) lines from a file with flags.

    Args:
      filename: str, the name of the flag file.
      parsed_file_stack: [str], a list of the names of the files that we have
        recursively encountered at the current depth. MUTATED BY THIS FUNCTION
        (but the original value is preserved upon successfully returning from
        function call).

    Returns:
      List of strings. See the note below.

    NOTE(springer): This function checks for a nested --flagfile=<foo>
    tag and handles the lower file recursively. It returns a list of
    all the lines that _could_ contain command flags. This is
    EVERYTHING except whitespace lines and comments (lines starting
    with '#' or '//').
    NzAWarning: Hit circular flagfile dependency. Ignoring flagfile: %s
rz#ERROR:: Unable to open flagfile: %s#z//)parsed_file_stack)r@   stderrwriter*   openIOErrorr   CantOpenFlagFileError	readlinesisspacer   r   r   _get_flag_file_linesr   r   pop)
r   filenamer   Z	line_listZflag_line_listfile_objZe_msglineZsub_filenameZincluded_flagsr   r   r   r     sD    
&
zFlagValues._get_flag_file_linesc           	      C   s*  |}g }|r|d }|dd }|  |r|dks<|dkrh|sJtdtj|d }|dd }n
| |}|| | q|	| |dkrq|
ds|s| jd	 sqqd
|vr|r|d 
ds|  }|d}||v r|| js|d }|dd }|	| q|r&|| |S )a  Processes command line args, but also allow args to be read from file.

    Args:
      argv: [str], a list of strings, usually sys.argv[1:], which may contain
        one or more flagfile directives of the form --flagfile="./filename".
        Note that the name of the program (sys.argv[0]) should be omitted.
      force_gnu: bool, if False, --flagfile parsing obeys the
        FLAGS.is_gnu_getopt() value. If True, ignore the value and always follow
        gnu_getopt semantics.

    Returns:
      A new list which has the original list combined with what we read
      from any flagfile(s).

    Raises:
      IllegalFlagValueError: Raised when --flagfile is provided with no
          argument.

    This function is called by FLAGS(argv).
    It scans the input list for a flag that looks like:
    --flagfile=<somefile>. Then it opens <somefile>, reads all valid key
    and value pairs and inserts them into the input list in exactly the
    place where the --flagfile arg is found.

    Note that your application's flags are still defined the usual way
    using absl.flags DEFINE_flag() type functions.

    Notes (assuming we're getting a commandline of some sort as our input):

    * For duplicate flags, the last one we hit should "win".
    * Since flags that appear later win, a flagfile's settings can be "weak"
        if the --flagfile comes at the beginning of the argument sequence,
        and it can be "strong" if the --flagfile comes at the end.
    * A further "--flagfile=<otherfile.cfg>" CAN be nested in a flagfile.
        It will be expanded in exactly the spot where it is found.
    * In a flagfile, a line beginning with # or // is a comment.
    * Entirely blank lines _should_ be ignored.
    r   r   Nr   r   z--flagfile with no argumentr   r   r   r   )r   r   rQ   r   r   r   r   r   r   r*   r   r   r%   lstripr   )	r   rA   r   Zrest_of_argsZnew_argvZcurrent_argZflag_filenamerh   r3   r   r   r   r   T  sB    '





z FlagValues.read_flags_from_filesc                 C   sZ   t |   }d}|D ]<\}}t |dd d}|D ]}|jdur4|| d 7 }q4q|S )a  Returns a string with the flags assignments from this FlagValues object.

    This function ignores flags whose value is None.  Each flag
    assignment is separated by a newline.

    NOTE: MUST mirror the behavior of the C++ CommandlineFlagsIntoString
    from https://github.com/gflags/gflags.

    Returns:
      str, the string with the flags assignments from this FlagValues object.
      The flags are ordered by (module_name, flag_name).
    r   c                 S   s   | j S r|   r   )ri   r   r   r   r~     r   z.FlagValues.flags_into_string.<locals>.<lambda>r   Nr   )rk   r&   rF   rU   	serialize)r   Zmodule_flagssZunused_module_namerJ   r,   r   r   r   flags_into_string  s    
zFlagValues.flags_into_stringc                 C   s<   t |d}||   W d   n1 s.0    Y  dS )a  Appends all flags assignments from this FlagInfo object to a file.

    Output will be in the format of a flagfile.

    NOTE: MUST mirror the behavior of the C++ AppendFlagsIntoFile
    from https://github.com/gflags/gflags.

    Args:
      filename: str, name of the file.
    aN)r   r   r  )r   r   out_filer   r   r   append_flags_into_file  s    z!FlagValues.append_flags_into_filec              
   C   s2  t  }|d}|| |t|dtjt	j
d  t	jd j}|s^dt	j
d  }n|dt	j
d }|t|d| | t	j
d }|  }t| }|  |D ]J}dd	 || D }	|	  |	D ]&\}
}||v }||j|||d
 qq|p
t	j}||jdddd |  dS )a  Outputs flag documentation in XML format.

    NOTE: We use element names that are consistent with those used by
    the C++ command-line flag library, from
    https://github.com/gflags/gflags.
    We also use a few new elements (e.g., <key>), but we do not
    interfere / overlap with existing XML elements used by the C++
    library.  Please maintain this consistency.

    Args:
      outfile: File object we write to.  Default None means sys.stdout.
    ZAllFlagsprogramr   r<   z
USAGE: %s [flags]
z%susagec                 S   s   g | ]}|j |fqS r   r   )r   ri   r   r   r   r     r   z7FlagValues.write_help_in_xml_format.<locals>.<listcomp>)is_keyr   zutf-8)r   encodingN)r   DocumentcreateElementappendChildr   create_xml_dom_elementr   r   basenamer@   rA   r   __doc__replacerE   r&   rB   keysr   _create_xml_dom_elementstdoutr   toprettyxmldecodeflush)r   outfiledocZall_flagZ	usage_docr1   r-   Zall_module_namesr+   Z	flag_listZunused_flag_namer,   r  r   r   r   write_help_in_xml_format  sH    

z#FlagValues.write_help_in_xml_formatc                 C   s\   |j r
d S |j}|d u r|hn||h}|D ],}|| jd v r*tdj|t| jdq*d S )Nr   zCannot define a flag named "{name}". It conflicts with a method on class "{class_name}". To allow defining it, use allow_using_method_names and access the flag value with FLAGS['{name}'].value. FLAGS.{name} returns the method, not the flag value.)r3   
class_name)allow_using_method_namesr5   r   r    FlagNameConflictsWithMethodErrorrR   r   r?   )r   r3   r,   r5   r   r[   r   r   r   rb     s    
z'FlagValues._check_method_name_conflicts)T)N)N)F)r   T)r   )r   )r   )r   )N)T)N)Br?   
__module____qualname__r  r   r"   r#   r%   r&   r'   r(   r.   r0   r2   r8   r;   rD   rE   rK   rL   rN   rV   r\   r^   rj   rl   ro   rp   rt   rv   ru   r{   rw   r]   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r	  r  rb   r   r   r   r   r
   '   s   +.
			


	
(
#
, 		





'
C
S
4r
   c                   @   s^   e Zd ZdZdddZdd Zdd ZeZed	d
 Z	edd Z
edd Zedd ZdS )
FlagHoldera  Holds a defined flag.

  This facilitates a cleaner api around global state. Instead of::

      flags.DEFINE_integer('foo', ...)
      flags.DEFINE_integer('bar', ...)

      def method():
        # prints parsed value of 'bar' flag
        print(flags.FLAGS.foo)
        # runtime error due to typo or possibly bad coding style.
        print(flags.FLAGS.baz)

  it encourages code like::

      _FOO_FLAG = flags.DEFINE_integer('foo', ...)
      _BAR_FLAG = flags.DEFINE_integer('bar', ...)

      def method():
        print(_FOO_FLAG.value)
        print(_BAR_FLAG.value)

  since the name of the flag appears only once in the source code.
  Fc                 C   s   || _ |j| _|| _dS )a  Constructs a FlagHolder instance providing typesafe access to flag.

    Args:
      flag_values: The container the flag is registered to.
      flag: The flag object for this flag.
      ensure_non_none_value: Is the value of the flag allowed to be None.
    N)_flagvaluesr3   _name_ensure_non_none_value)r   rZ   r,   ensure_non_none_valuer   r   r   r   ,  s    zFlagHolder.__init__c                 C   s    t dt| jt|jd S )Nz^unsupported operand type(s) for ==: '{0}' and '{1}' (did you mean to use '{0}.value' instead?)rO   rR   r   r?   )r   otherr   r   r   __eq__?  s
    zFlagHolder.__eq__c                 C   s   t dt| jd S )Nz[bool() not supported for instances of type '{0}' (did you mean to use '{0}.value' instead?)r(  r   r   r   r   __bool__E  s
    zFlagHolder.__bool__c                 C   s   | j S r|   )r%  r   r   r   r   r3   M  s    zFlagHolder.namec                 C   s0   t | j| j}| jr,|du r,td| j |S )a  Returns the value of the flag.

    If ``_ensure_non_none_value`` is ``True``, then return value is not
    ``None``.

    Raises:
      UnparsedFlagAccessError: if flag parsing has not finished.
      IllegalFlagValueError: if value is None unexpectedly.
    Nz!Unexpected None value for flag %s)getattrr$  r%  r&  r   rQ   )r   valr   r   r   rU   Q  s    zFlagHolder.valuec                 C   s   | j | j jS )z&Returns the default value of the flag.)r$  r%  rH   r   r   r   r   rH   b  s    zFlagHolder.defaultc                 C   s   t | j| j jS )z<Returns True if the flag was parsed from command-line flags.)boolr$  r%  rr   r   r   r   r   rr   g  s    zFlagHolder.presentN)F)r?   r!  r"  r  r   r*  r+  __nonzero__propertyr3   rU   rH   rr   r   r   r   r   r#    s   



r#  c                 C   s:   t | tr2| j}|tkr(||kr(td| j|fS | |fS )z9Helper to validate and resolve a flag reference argument.zAflag_values must not be customized when operating on a FlagHolder)r=   r#  r$  FLAGSrP   r3   )Zflag_refrZ   Znew_flag_valuesr   r   r   resolve_flag_refm  s    

r2  c                 C   s\   d}g }| D ]F}t |tr(|j}|j}n|}|}|rD||krDtd|}|| q||fS )z=Helper to validate and resolve flag reference list arguments.Nzmultiple FlagValues instances used in invocation. FlagHolders must be registered to the same FlagValues instance as do flag names, if provided.)r=   r#  r$  r3   rP   r*   )Z	flag_refsrZ   fvnamesrefZnewfvr3   r   r   r   resolve_flag_refsx  s    
r6  )r  r   r   r   r   r@   typingr   r   xml.domr   
absl.flagsr   r   r   r   disclaim_module_idsrf   re   r   r?   r	   r
   r1  r#  r2  r6  r   r   r   r   <module>   s6            q[