U
    &cs                     @   s   d dl Z d dlZd dl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 ede
Zede
ZG dd	 d	eZdS )
    N)ArgumentParser)Enum)Path)AnyIterableNewTypeTupleUnion	DataClassDataClassTypec                       s~   e Zd ZU dZee ed< eeee f d fddZedddZ	de
edf dddZee
edf dddZ  ZS )HfArgumentParserae  
    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.
    dataclass_types)r   c                    s>   t  jf | t|r|g}|| _| jD ]}| | q*dS )a!  
        Args:
            dataclass_types:
                Dataclass type, or list of dataclass types for which we will "fill" instances
                with the parsed args.
            kwargs:
                (Optional) Passed to `argparse.ArgumentParser()` in the regular way.
        N)super__init__dataclassesZis_dataclassr   _add_dataclass_arguments)selfr   kwargsdtype	__class__ =/tmp/pip-unpacked-wheel-ymerj3tt/transformers/hf_argparser.pyr      s    	

zHfArgumentParser.__init__)r   c                 C   s6  t |D ]$}d|j }|j }t|jtr:tdt|j}t	t
tfD ]}|d|j dkrN||_qNt|jtrt|jtrt|j|d< |j|d< |jt jk	r|j|d< nn|jtkr|jdkrd	nd
|d< |jdkrd|j }|j|d< n,|j|d< |jt jk	r|j|d< nd|d< | j|f| q
d S )Nz--zThis implementation is not compatible with Postponed Evaluation of Annotations (PEP 563),which can be opted in from Python 3.7 with `from __future__ import annotations`.We will add compatibility when Python 3.9 is released.ztyping.Union[z, NoneType]choicestypedefaultTstore_false
store_trueactionz--no-destrequired)r   fieldsnamemetadatacopy
isinstancer   strImportErrorintfloat__name__
issubclassr   listr   MISSINGbooladd_argument)r   r   field
field_namer   Z
typestringxr   r   r   r   *   s4    





z)HfArgumentParser._add_dataclass_argumentsNFT.)returnc                    s   |rXt tjrXttjd d}| rX|  }|dk	rF|| n|tjdd  }| j|d\}}g }| j	D ]Z}	dd t
|	D   fdd	t| D }
 D ]}t|| q|	f |
}|| qrt |jdkr|| |r||fS |S d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.

        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.argsN   )argsc                 S   s   h | ]
}|j qS r   r"   .0fr   r   r   	<setcomp>u   s     z?HfArgumentParser.parse_args_into_dataclasses.<locals>.<setcomp>c                    s   i | ]\}}| kr||qS r   r   r8   kvkeysr   r   
<dictcomp>v   s       z@HfArgumentParser.parse_args_into_dataclasses.<locals>.<dictcomp>)lensysargvr   with_suffixexists	read_textsplitparse_known_argsr   r   r!   varsitemsdelattrappend__dict__)r   r5   Zreturn_remaining_stringsZlook_for_args_file	args_fileZfargs	namespaceremaining_argsoutputsr   inputsr<   objr   r>   r   parse_args_into_dataclassesL   s&    "



z,HfArgumentParser.parse_args_into_dataclasses)	json_filer3   c                    sf   t t| }g }| jD ]B}dd t|D   fdd| D }|f |}|| q|S )z
        Alternative helper method that does not use `argparse` at all,
        instead loading a json file and populating the dataclass types.
        c                 S   s   h | ]
}|j qS r   r6   r7   r   r   r   r:      s     z3HfArgumentParser.parse_json_file.<locals>.<setcomp>c                    s   i | ]\}}| kr||qS r   r   r;   r>   r   r   r@      s       z4HfArgumentParser.parse_json_file.<locals>.<dictcomp>)	jsonloadsr   rF   r   r   r!   rJ   rL   )r   rU   datarQ   r   rR   rS   r   r>   r   parse_json_file   s    

z HfArgumentParser.parse_json_file)NFT)r*   
__module____qualname____doc__r   r   __annotations__r	   r   r   r   r
   rT   r&   rY   __classcell__r   r   r   r   r      s   
	#     
7r   )r   rV   rB   argparser   enumr   pathlibr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   <module>   s   

