o
    hP                     @   sF  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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 d dlmZmZmZmZmZmZmZ d dlZed	eZed
eZdd Zdedeegef fddZ dde j!e j!dddeeeee f  dee dedeg ef dee" de j#fddZ$G dd deZ%dS )    N)ArgumentDefaultsHelpFormatterArgumentParserArgumentTypeError)Iterable)copy)Enum)isclassPath)AnyCallableLiteralNewTypeOptionalUnionget_type_hints	DataClassDataClassTypec                 C   s>   t | tr| S |  dv rdS |  dv rdS td|  d)N)yestruety1T)nofalsefn0FzTruthy value expected: got zJ but expected one of yes/no, true/false, t/f, y/n, 1/0 (case insensitive).)
isinstanceboollowerr   )v r"   m/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/transformers/hf_argparser.pystring_to_bool$   s   

r$   choicesreturnc                    s   dd | D   fddS )aN  
    Creates a mapping function from each choices string representation to the actual value. Used to support multiple
    value types for a single argument.

    Args:
        choices (list): List of choices.

    Returns:
        Callable[[str], Any]: Mapping function from string representation to actual value for each choice.
    c                 S   s   i | ]}t ||qS r"   )str).0choicer"   r"   r#   
<dictcomp><   s    z-make_choice_type_function.<locals>.<dictcomp>c                    s     | | S N)get)argstr_to_choicer"   r#   <lambda>=   s    z+make_choice_type_function.<locals>.<lambda>r"   )r%   r"   r.   r#   make_choice_type_function1   s   r1   )aliaseshelpdefaultdefault_factorymetadatar2   r3   r4   r5   r6   c                 K   sD   |du ri }| dur| |d< |dur||d< t jd|||d|S )a  Argument helper enabling a concise syntax to create dataclass fields for parsing with `HfArgumentParser`.

    Example comparing the use of `HfArg` and `dataclasses.field`:
    ```
    @dataclass
    class Args:
        regular_arg: str = dataclasses.field(default="Huggingface", metadata={"aliases": ["--example", "-e"], "help": "This syntax could be better!"})
        hf_arg: str = HfArg(default="Huggingface", aliases=["--example", "-e"], help="What a nice syntax!")
    ```

    Args:
        aliases (Union[str, List[str]], optional):
            Single string or list of strings of aliases to pass on to argparse, e.g. `aliases=["--example", "-e"]`.
            Defaults to None.
        help (str, optional): Help string to pass on to argparse that can be displayed with --help. Defaults to None.
        default (Any, optional):
            Default value for the argument. If not default or default_factory is specified, the argument is required.
            Defaults to dataclasses.MISSING.
        default_factory (Callable[[], Any], optional):
            The default_factory is a 0-argument function called to initialize a field's value. It is useful to provide
            default values for mutable types, e.g. lists: `default_factory=list`. Mutually exclusive with `default=`.
            Defaults to dataclasses.MISSING.
        metadata (dict, optional): Further metadata to pass on to `dataclasses.field`. Defaults to None.

    Returns:
        Field: A `dataclasses.Field` with the desired properties.
    Nr2   r3   )r6   r4   r5   r"   )dataclassesfield)r2   r3   r4   r5   r6   kwargsr"   r"   r#   HfArg@   s   $r:   c                	       s  e Zd ZU dZee ed< ddeeeee f  f fddZ	e
dedejfdd	Zd
efddZ					ddeedf fddZddeeef dedeedf fddZ	ddeeejf dedeedf fddZ	ddeeejf dedeedf fddZ  ZS ) HfArgumentParsera  
    This subclass of `argparse.ArgumentParser` uses type hints on dataclasses to generate arguments.

    The class is designed to play well with the native argparse. In particular, you can add more (non-dataclass backed)
    arguments to the parser after initialization and you'll get the output back after parsing as an additional
    namespace. Optional: To create sub argument groups use the `_argument_group_name` attribute in the dataclass.

    Args:
        dataclass_types (`DataClassType` or `Iterable[DataClassType]`, *optional*):
            Dataclass type, or list of dataclass types for which we will "fill" instances with the parsed args.
        kwargs (`Dict[str, Any]`, *optional*):
            Passed to `argparse.ArgumentParser()` in the regular way.
    dataclass_typesNc                    st   |d u rg }nt |ts|g}d|vrt|d< t jdi | t|r(|g}t|| _| jD ]}| 	| q0d S )Nformatter_classr"   )
r   r   r   super__init__r7   is_dataclasslistr<   _add_dataclass_arguments)selfr<   r9   dtype	__class__r"   r#   r?      s   



zHfArgumentParser.__init__parserr8   c                 C   s  d|j  g}d|j v r|d|j dd  |j }t|jtr(td|	dg }t|tr6|g}t
|jd|j}|tu sMttdrt|tjrt|jjvrlt|jjdksctd |jjvrltd	|j  d
td |jjvr|jjd tu r|jjd n|jjd |_t
|jd|j}n$t|jjvrtd |jjd r|jjd n|jjd |_t
|jd|j}i }|tu st|jtrt|jtr|tu r|jj|d< n
dd |jD |d< t|d |d< |jtjur|j|d< nd|d< n|jtu s|jtt kr8t|}t|d< |jtu s|jd ur7|jtjur7|jtju r(dn|j}||d< d|d< d|d< nUt|rit|tri|jjd |d< d|d< |jtjur]| |d< n0|jtju rhd|d< n$|j|d< |jtjur{|j|d< n|jtjur| |d< nd|d< | jg ||R i | |jdu r|jtu s|jtt krd|d< | jd|j  d|j dd fd|j d| d S d S d S )Nz--_-zpUnresolved type detected, which should have been done with the help of `typing.get_type_hints` method by defaultr2   
__origin__	UnionType   zOnly `Union[X, NoneType]` (i.e., `Optional[X]`) is allowed for `Union` because the argument parser only supports one type per argument. Problem encountered in field 'z'.   r   r%   c                 S   s   g | ]}|j qS r"   )value)r(   xr"   r"   r#   
<listcomp>   s    z;HfArgumentParser._parse_dataclass_field.<locals>.<listcomp>typer4   TrequiredF?nargsconst+z--no_z--no-store_false)actiondest) nameappendreplacer6   r   r   rQ   r'   RuntimeErrorpopgetattrr   hasattrtypesrK   __args__len
ValueErrorr   r   
issubclassr   r1   r4   r7   MISSINGr   r$   r   rA   r5   add_argument)rG   r8   long_optionsr9   r2   origin_typebool_kwargsr4   r"   r"   r#   _parse_dataclass_field   s   


 *( 
&
(

z'HfArgumentParser._parse_dataclass_fieldrD   c              
   C   s   t |dr| |j}n| }zt|}W nC ty#   td| d tyW } z)tjd d dk rRdt	|v rRd
tt	tjd d }td| d	| d
| d }~ww t|D ]}|jscq]||j |_| || q]d S )N_argument_group_namezType resolution failed for z. Try declaring the class in global scope or removing line of `from __future__ import annotations` which opts in Postponed Evaluation of Annotations (PEP 563)rL   )   
   z!unsupported operand type(s) for |.rm   z on Python a6  . Try removing line of `from __future__ import annotations` which opts in union types as `X | Y` (PEP 604) via Postponed Evaluation of Annotations (PEP 563). To support Python versions that lower than 3.10, you need to use `typing.Union[X, Y]` instead of `X | Y` and `typing.Optional[X]` instead of `X | None`.)r`   add_argument_grouprl   r   	NameErrorr]   	TypeErrorsysversion_infor'   joinmapr7   fieldsinitrZ   rQ   rk   )rC   rD   rG   
type_hintsexpython_versionr8   r"   r"   r#   rB      s4   

z)HfArgumentParser._add_dataclass_argumentsFTr&   .c                    s  |s|s|r{t tjr{g }|r|t| n|r+t tjr+|ttjd d |rWt }|j|tdd |j	|d\}}t
||dd}	|	rW|dd	 |	D  g }
|D ]}| ri|
|  7 }
q[|durr|
| n|
tjd
d  }| j	|d\}}g }| jD ]/}dd t|D   fddt
| D } D ]}t|| q|di |}|| qt |jdkr|| |rg ||R S |rtd| g |R S )a'  
        Parse command-line args into instances of the specified dataclass types.

        This relies on argparse's `ArgumentParser.parse_known_args`. See the doc at:
        docs.python.org/3.7/library/argparse.html#argparse.ArgumentParser.parse_args

        Args:
            args:
                List of strings to parse. The default is taken from sys.argv. (same as argparse.ArgumentParser)
            return_remaining_strings:
                If true, also return a list of remaining argument strings.
            look_for_args_file:
                If true, will look for a ".args" file with the same base name as the entry point script for this
                process, and will append its potential content to the command line args.
            args_filename:
                If not None, will uses this file instead of the ".args" file specified in the previous argument.
            args_file_flag:
                If not None, will look for a file in the command-line args specified with this flag. The flag can be
                specified multiple times and precedence is determined by the order (last one wins).

        Returns:
            Tuple consisting of:

                - the dataclass instances in the same order as they were passed to the initializer.abspath
                - if applicable, an additional namespace for more (non-dataclass backed) arguments added to the parser
                  after initialization.
                - The potential list of remaining argument strings. (same as argparse.ArgumentParser.parse_known_args)
        r   z.argsr[   )rQ   rX   )argsrI   Nc                 S   s   g | ]}t |qS r"   r	   )r(   pr"   r"   r#   rP   U  s    z@HfArgumentParser.parse_args_into_dataclasses.<locals>.<listcomp>rM   c                 S      h | ]}|j r|jqS r"   rx   rZ   r(   r   r"   r"   r#   	<setcomp>b      z?HfArgumentParser.parse_args_into_dataclasses.<locals>.<setcomp>c                       i | ]\}}| v r||qS r"   r"   r(   kr!   keysr"   r#   r*   c      z@HfArgumentParser.parse_args_into_dataclasses.<locals>.<dictcomp>z?Some specified arguments are not used by the HfArgumentParser: r"   )rc   rs   argvr[   r
   with_suffixr   rg   r'   parse_known_argsvarsr,   lstripextendexists	read_textsplitr<   r7   rw   itemsdelattr__dict__rd   )rC   r|   return_remaining_stringslook_for_args_fileargs_filenameargs_file_flag
args_filesargs_file_parsercfgcmd_args_file_paths	file_args	args_file	namespaceremaining_argsoutputsrD   inputsr   objr"   r   r#   parse_args_into_dataclasses  sF   %"


z,HfArgumentParser.parse_args_into_dataclassesr|   allow_extra_keysc                    s   t | }g }| jD ]*}dd t|D   fdd| D }||  |di |}|| q|sC|rCtdt	| t
|S )a<  
        Alternative helper method that does not use `argparse` at all, instead uses a dict and populating the dataclass
        types.

        Args:
            args (`dict`):
                dict containing config values
            allow_extra_keys (`bool`, *optional*, defaults to `False`):
                Defaults to False. If False, will raise an exception if the dict contains keys that are not parsed.

        Returns:
            Tuple consisting of:

                - the dataclass instances in the same order as they were passed to the initializer.
        c                 S   r~   r"   r   r   r"   r"   r#   r     r   z.HfArgumentParser.parse_dict.<locals>.<setcomp>c                    r   r"   r"   r   r   r"   r#   r*     r   z/HfArgumentParser.parse_dict.<locals>.<dictcomp>z0Some keys are not used by the HfArgumentParser: Nr"   )setr   r<   r7   rw   r   difference_updater[   rd   sortedtuple)rC   r|   r   unused_keysr   rD   r   r   r"   r   r#   
parse_dicts  s   
zHfArgumentParser.parse_dict	json_filec                 C   sT   t t|dd}t| }W d   n1 sw   Y  | j||d}t|S )at  
        Alternative helper method that does not use `argparse` at all, instead loading a json file and populating the
        dataclass types.

        Args:
            json_file (`str` or `os.PathLike`):
                File name of the json file to parse
            allow_extra_keys (`bool`, *optional*, defaults to `False`):
                Defaults to False. If False, will raise an exception if the json file contains keys that are not
                parsed.

        Returns:
            Tuple consisting of:

                - the dataclass instances in the same order as they were passed to the initializer.
        zutf-8)encodingNr   )openr
   jsonloadsreadr   r   )rC   r   r   open_json_filedatar   r"   r"   r#   parse_json_file  s
   z HfArgumentParser.parse_json_file	yaml_filec                 C   s$   | j tt| |d}t|S )at  
        Alternative helper method that does not use `argparse` at all, instead loading a yaml file and populating the
        dataclass types.

        Args:
            yaml_file (`str` or `os.PathLike`):
                File name of the yaml file to parse
            allow_extra_keys (`bool`, *optional*, defaults to `False`):
                Defaults to False. If False, will raise an exception if the json file contains keys that are not
                parsed.

        Returns:
            Tuple consisting of:

                - the dataclass instances in the same order as they were passed to the initializer.
        r   )r   yaml	safe_loadr
   r   r   )rC   r   r   r   r"   r"   r#   parse_yaml_file  s   z HfArgumentParser.parse_yaml_filer+   )NFTNN)F)__name__
__module____qualname____doc__r   r   __annotations__r   r   r?   staticmethodr   r7   Fieldrk   rB   r   r   r   dictr'   r   r   r   osPathLiker   r   __classcell__r"   r"   rE   r#   r;   o   s@   
 $i$

(V


r;   )&r7   r   r   rs   ra   argparser   r   r   collections.abcr   r   enumr   inspectr   pathlibr
   typingr   r   r   r   r   r   r   r   r   r   r$   rA   r'   r1   rf   r   r   r:   r;   r"   r"   r"   r#   <module>   sH   $



/