U
    e(C                     @   s   d Z ddl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mZ ddlmZmZ dd	d
dgZdZdd Zdd ZdddZdd Zdd Zdd	 Zddd
Zdd Zdd ZdS )z^
Assembling
~~~~~~~~~~

Functions and classes to properly assemble your commands in a parser.
    N)OrderedDict)COMPLETION_ENABLED)ATTR_ALIASES	ATTR_ARGSATTR_EXPECTS_NAMESPACE_OBJECT	ATTR_NAMEDEFAULT_ARGUMENT_TEMPLATEDEST_FUNCTIONPARSER_FORMATTER)AssemblingError)get_arg_specget_subparsersSUPPORTS_ALIASESset_default_commandadd_commandsadd_subcommandsTc           
      #   s  t | tdrd S t| }ttdd |j|jp.g fD  }|t |dd pLi  t |dg }tdd | j	 D }dd |j| D tfd	dt
D  t fd
d D }|j| D ]}g }i }||kr||}	t|	trtdt |j|	d ||ks||krv||kr8|j||d n|jdd d|d d|f}||r||dd  }n|f}tdd |D }tf d|i|V  q|jrt|jgddV  d S )NFc                 S   s   g | ]}t |qS  )reversed.0xr   r   n/mounts/lovelace/software/anaconda3/envs/qiime2-amplicon-2023.9/lib/python3.8/site-packages/argh/assembling.py
<listcomp>;   s     z,_get_args_from_signature.<locals>.<listcomp>kwonlydefaults
kwonlyargsc                 s   s$   | ]\}}t |tr||fV  qd S N)
isinstancestr)r   kvr   r   r   	<genexpr>@   s    
 z+_get_args_from_signature.<locals>.<genexpr>c                 S   s   g | ]}|d  qS )r   r   )r   ar   r   r   r   F   s     c                 3   s   | ]}|  |fV  qd S r   )countr   char)charsr   r   r    G   s     c                 3   s   | ]}d  | k r|V  qdS )   Nr   r#   )char_countsr   r   r    H   s      zDefining argument help messages via annotations is deprecated and will be removed in Argh 0.30.  Please replace `f(a:"foo")` with `@arg("-a", help="foo")(a)`.help)defaultT)requiredz-{0}r   z--{0}r&   c                 s   s(   | ] }| d r|dd n|V  qdS )-_N)
startswithreplacer   r   r   r   r    j   s     option_strings*)r0   nargs)getattrr   r   dictzipargsdefaultsupdate__annotations__itemssettuplegetr   r   warningswarnDeprecationWarningformatr.   varargs)
functionspecr7   kwonlyannotationsZconflicting_optsnameflagsZakwargsvaluer   )r'   r%   r   _get_args_from_signature5   sF    "


rJ   c                 C   s   i }d}|  d}|dk	rnt|trD|  ddkrn|r:dnd|d< n*|  ddkrn|  dd|krnt||d< |  d	rdt|t|  krt| d	 d
 |d< t| f|S )z
    Adds types, actions, etc. to given argument specification.
    For example, ``default=3`` implies ``type=int``.

    :param arg: a :class:`argh.utils.Arg` instance
    )storeappendr*   Nactionstore_false
store_truetyperK   choicesr   )r=   r   boolrP   listr4   )kwargsZguessedZTYPE_AWARE_ACTIONSrI   r   r   r   _guesss   s    

rU   r,   c                 C   s6   | r| d st d| d d t|r.dS dS d S )Nr   zExpected at least one argumentFT)
ValueErrorr.   r<   )r6   prefix_charsr   r   r   _is_positional   s
    rX   c                 C   sN   |  }|d }t|| jdr&| j}n| j}|||}|d dd|d< |S )Nr0   )rW   destr,   r-   )copyrX   rW   _get_positional_kwargs_get_optional_kwargsr/   )parserargspecr6   Z
get_kwargsrT   r   r   r   _get_parser_param_kwargs   s    
r_   c                 C   s   t | |}|d S )NrY   )r_   )r]   r^   rT   r   r   r   	_get_dest   s    
r`   c                    sF  t |}t|tg }tt|}|r:|r:t  |D ]}t| |d }| |< q6|D ]}t| |}| krt|d }t | d }	||	krddd}
t	dj
|j||
|	 |
| d | jf | qVt|dt|d	g }|r| |< qV fd
d D }t	dj
d|d |jddd |D dqV  }|pB|}dd |D }|D ]}| }d|krx|jtd |d}| jrd|krdd |D }|dd}z"| j||}tr|r||_W nD tk
r } z$t|dj
d||j|dW 5 d}~X Y nX qV|jr2| js2|j| _| jf t|i dS )a  
    Sets default command (i.e. a function) for given parser.

    If `parser.description` is empty and the function has a docstring,
    it is used as the description.

    .. note::

       If there are both explicitly declared arguments (e.g. via
       :func:`~argh.decorators.arg`) and ones inferred from the function
       signature, declared ones will be merged into inferred ones.
       If an argument does not conform to the function signature,
       `AssemblingError` is raised.

    .. note::

       If the parser was created with ``add_help=True`` (which is by default),
       option name ``-h`` is silently removed from any argument.

    rY   r0   
positionaloptional)TFzc{func}: argument "{dest}" declared as {kind_i} (in function signature) and {kind_d} (via decorator))funcrY   Zkind_iZkind_dvarkwkeywordsc                 3   s   | ]} | d  V  qdS )r0   Nr   r   Zdestsr   r   r      s     z&set_default_command.<locals>.<genexpr>z?{func}: argument {flags} does not fit function signature: {sig}z, c                 s   s   | ]}d  |V  qdS )/N)joinr   r   r   r   r      s     )rH   rc   sigc                 S   s   g | ]}t |qS r   )rU   r   r   r   r   r     s     z'set_default_command.<locals>.<listcomp>r)   r(   -hc                 S   s   g | ]}|d kr|qS )rj   r   r   r   r   r   r     s      	completerNz${func}: cannot add arg {args}: {msg}rg   )r6   rc   msg)r   r3   r   rS   rJ   r   r_   r`   rX   r   rA   __name__r8   rh   valuesrZ   r   popadd_helpadd_argumentr   rk   	ExceptionrP   __doc__descriptionset_defaultsr	   )r]   rC   rD   Zdeclared_argsZinferred_argsr^   rY   Zdeclared_kwZdecl_positionalZinfr_positionalkindsrd   Zxscommand_argsZdraftZdest_or_opt_stringsrk   rM   er   rf   r   r      s    









   c                 C   s   |pi }|r t dt ||d< |r8t dt ||d< |rPt dt ||d< t| dd}|rd|di}	|j|f|	}
|
jf |}n|rtd	|D ]6}t|\}}|r|	| |j|f|}t
|| qd
S )ah
  
    Adds given functions as commands to given parser.

    :param parser:

        an :class:`argparse.ArgumentParser` instance.

    :param functions:

        a list of functions. A subparser is created for each of them.
        If the function is decorated with :func:`~argh.decorators.arg`, the
        arguments are passed to :meth:`argparse.ArgumentParser.add_argument`.
        See also :func:`~argh.dispatching.dispatch` for requirements
        concerning function signatures. The command name is inferred from the
        function name. Note that the underscores in the name are replaced with
        hyphens, i.e. function name "foo_bar" becomes command name "foo-bar".

    :param namespace:

        an optional string representing the group of commands. For example, if
        a command named "hello" is added without the namespace, it will be
        available as "prog.py hello"; if the namespace if specified as "greet",
        then the command will be accessible as "prog.py greet hello". The
        namespace itself is not callable, so "prog.py greet" will fail and only
        display a help message.

    :param func_kwargs:

        a `dict` of keyword arguments to be passed to each nested ArgumentParser
        instance created per command (i.e. per function).  Members of this
        dictionary have the highest priority, so a function's docstring is
        overridden by a `help` in `func_kwargs` (if present).

    :param namespace_kwargs:

        a `dict` of keyword arguments to be passed to the nested ArgumentParser
        instance under given `namespace`.

    Deprecated params that should be moved into `namespace_kwargs`:

    :param title:

        .. deprecated:: 0.26.0

           This argument will be removed in Argh v.0.30.
           Please use `namespace_kwargs` instead.

    :param description:

        .. deprecated:: 0.26.0

           This argument will be removed in Argh v.0.30.
           Please use `namespace_kwargs` instead.

    :param help:

        .. deprecated:: 0.26.0

           This argument will be removed in Argh v.0.30.
           Please use `namespace_kwargs` instead.

    .. note::

        This function modifies the parser object. Generally side effects are
        bad practice but we don't seem to have any choice as ArgumentParser is
        pretty opaque.
        You may prefer :meth:`~argh.helpers.ArghParser.add_commands` for a bit
        more predictable API.

    .. note::

       An attempt to add commands to a parser which already has a default
       function (e.g. added with :func:`~argh.assembling.set_default_command`)
       results in `AssemblingError`.

    zvArgument `title` is deprecated in add_commands(), it will be removed in Argh 0.30. Please use `parser_kwargs` instead.rt   zuArgument `help` is deprecated in add_commands(), it will be removed in Argh 0.30. Please use `parser_kwargs` instead.r)   z|Argument `description` is deprecated in add_commands(), it will be removed in Argh 0.30. Please use `parser_kwargs` instead.T)createtitlez2`parser_kwargs` only makes sense with `namespace`.N)r>   r?   r@   r   r=   
add_parseradd_subparsersrV   _extract_command_meta_from_funcr8   r   )r]   	functions	namespacenamespace_kwargsZfunc_kwargsrz   rt   r)   Zsubparsers_actionZsubsubparser_kwZsubsubparserrc   cmd_namefunc_parser_kwargsZcommand_parserr   r   r   r   4  sD    Z	 
c                 C   s:   t | t| jdd}| jtd}t | tg |d< ||fS )Nr-   r,   )r)   formatter_classaliases)r3   r   rm   r/   rs   r
   r   )rc   r   r   r   r   r   r}     s    r}   c                 K   s   t | |||d dS )a  
    A wrapper for :func:`add_commands`.

    These examples are equivalent::

        add_commands(parser, [get, put], namespace='db',
                     namespace_kwargs={
                         'title': 'database commands',
                         'help': 'CRUD for our silly database'
                     })

        add_subcommands(parser, 'db', [get, put],
                        title='database commands',
                        help='CRUD for our silly database')

    )r   r   N)r   )r]   r   r~   r   r   r   r   r     s       )r,   )NNNNNN)rs   r>   collectionsr   Zargh.completionr   Zargh.constantsr   r   r   r   r   r	   r
   Zargh.exceptionsr   Z
argh.utilsr   r   __all__r   rJ   rU   rX   r_   r`   r   r   r}   r   r   r   r   r   <module>
   s:   $		> 
	       
 