a
    Fb&                     @   s
  d 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
 edZeG dd	 d	ejZG d
d dejZdd Zdd Zdd ZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZg d ZdS )!a   A decorator-based method of constructing IPython magics with `argparse`
option handling.

New magic functions can be defined like so::

    from IPython.core.magic_arguments import (argument, magic_arguments,
        parse_argstring)

    @magic_arguments()
    @argument('-o', '--option', help='An optional argument.')
    @argument('arg', type=int, help='An integer positional argument.')
    def magic_cool(self, arg):
        """ A really cool magic command.

    """
        args = parse_argstring(magic_cool, arg)
        ...

The `@magic_arguments` decorator marks the function as having argparse arguments.
The `@argument` decorator adds an argument using the same syntax as argparse's
`add_argument()` method. More sophisticated uses may also require the
`@argument_group` or `@kwds` decorator to customize the formatting and the
parsing.

Help text for the magic is automatically generated from the docstring and the
arguments::

    In[1]: %cool?
        %cool [-o OPTION] arg
        
        A really cool magic command.
        
        positional arguments:
          arg                   An integer positional argument.
        
        optional arguments:
          -o OPTION, --option OPTION
                                An optional argument.

Here is an elaborated example that uses default parameters in `argument` and calls the `args` in the cell magic::

    from IPython.core.magic import register_cell_magic
    from IPython.core.magic_arguments import (argument, magic_arguments,
                                            parse_argstring)


    @magic_arguments()
    @argument(
        "--option",
        "-o",
        help=("Add an option here"),
    )
    @argument(
        "--style",
        "-s",
        default="foo",
        help=("Add some style arguments"),
    )
    @register_cell_magic
    def my_cell_magic(line, cell):
        args = parse_argstring(my_cell_magic, line)
        print(f"{args.option=}")
        print(f"{args.style=}")
        print(f"{cell=}")

In a jupyter notebook, this cell magic can be executed like this::

    %%my_cell_magic -o Hello
    print("bar")
    i = 42

Inheritance diagram:

.. inheritance-diagram:: IPython.core.magic_arguments
   :parts: 3

    N
UsageError)undoc)	arg_split)dedentz[a-zA-Z][a-zA-Z0-9_-]*$c                       s2   e Zd ZdZdd Zdd Zd	 fdd	Z  ZS )
MagicHelpFormatterz@A HelpFormatter with a couple of changes to meet our needs.
    c                 C   s   t j| t|||S N)argparseRawDescriptionHelpFormatter
_fill_textr   )selftextwidthindent r   ;lib/python3.9/site-packages/IPython/core/magic_arguments.pyr   e   s    zMagicHelpFormatter._fill_textc                 C   s   |j s| ||jd\}|S g }|jdkr:||j  nF|j }| ||}t|sbd| }|j D ]}|	d||f  qhd
|S d S )N   r   z<%s>z%s %sz, )Zoption_stringsZ_metavar_formatterdestnargsextendupperZ_format_argsNAME_REmatchappendjoin)r   actionmetavarpartsdefaultZargs_stringZoption_stringr   r   r   _format_action_invocationi   s    



z,MagicHelpFormatter._format_action_invocation::

  %c                    s   t t| |||| d S r   )superr   	add_usage)r   usageZactionsgroupsprefix	__class__r   r   r"      s    zMagicHelpFormatter.add_usage)r    )__name__
__module____qualname____doc__r   r   r"   __classcell__r   r   r&   r   r   `   s   r   c                
       sF   e Zd ZdZdddddeddddf
 fdd	Zdd	 Zd
d Z  ZS )MagicArgumentParserz: An ArgumentParser tweaked for use by IPython magics.
    N-errorFc                    s4   |d u rg }t t| j|||||||||	|
d
 d S )N)
progr#   descriptionepilogparentsformatter_classprefix_charsargument_defaultconflict_handleradd_help)r!   r-   __init__)r   r0   r#   r1   r2   r3   r4   r5   r6   r7   r8   r&   r   r   r9      s    zMagicArgumentParser.__init__c                 C   s   t |dS )z5 Raise a catchable error instead of exiting.
        Nr   )r   messager   r   r   r/      s    zMagicArgumentParser.errorc                 C   s   t |}| |S )zL Split a string into an argument list and parse that argument list.
        )r   
parse_args)r   	argstringargvr   r   r   parse_argstring   s    z#MagicArgumentParser.parse_argstring)	r(   r)   r*   r+   r   r9   r/   r>   r,   r   r   r&   r   r-      s   r-   c                 C   s|   t | di }d|vr$t | dd|d< t| }t|fi |}d}| jddd D ]}|||}|durP|}qP| | _|S )zB Construct an argument parser using the function decorations.
    argcmd_kwdsr1   r+   N)getattr	real_namer-   
decoratorsadd_to_parserZformat_helpr+   )
magic_funckwdsZarg_nameparsergroupZdecoresultr   r   r   construct_parser   s    
rJ   c                 C   s   | j |S )zA Parse the string of arguments for the given magic function.
    )rG   r>   )rE   r<   r   r   r   r>      s    r>   c                 C   s,   | j }|dr |tdd }t| d|S )z& Find the real name of the magic.
    Zmagic_Nargcmd_name)r(   
startswithlenrA   )rE   Z
magic_namer   r   r   rB      s    
rB   c                   @   s    e Zd ZdZdd Zdd ZdS )ArgDecoratorzN Base class for decorators to add ArgumentParser information to a method.
    c                 C   s(   t |ddsd|_g |_|j|  |S Nhas_argumentsFT)rA   rP   rC   r   r   funcr   r   r   __call__   s
    zArgDecorator.__call__c                 C   s   dS )zD Add this object's information to the parser, if necessary.
        Nr   r   rG   rH   r   r   r   rD      s    zArgDecorator.add_to_parserN)r(   r)   r*   r+   rS   rD   r   r   r   r   rN      s   rN   c                   @   s"   e Zd ZdZdddZdd ZdS )magic_argumentszS Mark the magic as having argparse arguments and possibly adjust the
    name.
    Nc                 C   s
   || _ d S r   )name)r   rV   r   r   r   r9      s    zmagic_arguments.__init__c                 C   s8   t |ddsd|_g |_| jd ur*| j|_t||_|S rO   )rA   rP   rC   rV   rK   rJ   rG   rQ   r   r   r   rS      s    

zmagic_arguments.__call__)N)r(   r)   r*   r+   r9   rS   r   r   r   r   rU      s   
rU   c                   @   s$   e Zd ZdZdZdd Zdd ZdS )ArgMethodWrapperz
    Base class to define a wrapper for ArgumentParser method.

    Child class must define either `_method_name` or `add_to_parser`.

    Nc                 O   s   || _ || _d S r   )argsrF   )r   rX   rF   r   r   r   r9      s    zArgMethodWrapper.__init__c                 C   s*   |dur|}t || j| ji | j dS )6 Add this object's information to the parser.
        N)rA   _method_namerX   rF   rT   r   r   r   rD     s    zArgMethodWrapper.add_to_parser)r(   r)   r*   r+   rZ   r9   rD   r   r   r   r   rW      s   rW   c                   @   s   e Zd ZdZdZdS )argumentzt Store arguments and keywords to pass to add_argument().

    Instances also serve to decorate command methods.
    add_argumentNr(   r)   r*   r+   rZ   r   r   r   r   r[     s   r[   c                   @   s   e Zd ZdZdZdS )defaultszt Store arguments and keywords to pass to set_defaults().

    Instances also serve to decorate command methods.
    Zset_defaultsNr]   r   r   r   r   r^     s   r^   c                   @   s   e Zd ZdZdd ZdS )argument_groupzz Store arguments and keywords to pass to add_argument_group().

    Instances also serve to decorate command methods.
    c                 C   s   |j | ji | jS )rY   )Zadd_argument_grouprX   rF   rT   r   r   r   rD   #  s    zargument_group.add_to_parserN)r(   r)   r*   r+   rD   r   r   r   r   r_     s   r_   c                       s(   e Zd ZdZdd Z fddZ  ZS )rF   z; Provide other keywords to the sub-parser constructor.
    c                 K   s
   || _ d S r   )rF   )r   rF   r   r   r   r9   ,  s    zkwds.__init__c                    s   t t| |}| j|_|S r   )r!   rF   rS   r?   rQ   r&   r   r   rS   /  s    zkwds.__call__)r(   r)   r*   r+   r9   rS   r,   r   r   r&   r   rF   )  s   rF   )rU   r[   r_   rF   r>   )r+   r	   reZIPython.core.errorr   ZIPython.utils.decoratorsr   ZIPython.utils.processr   ZIPython.utils.textr   compiler   r
   r   ArgumentParserr-   rJ   r>   rB   objectrN   rU   rW   r[   r^   r_   rF   __all__r   r   r   r   <module>   s*   T
("	