
    e44                     P   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 ddlm	Z	 ddl
mZmZmZmZ ej                  dk\  rddl
mZ nddlmZ ddlmZ dd	lmZ  ed
      Z ed      Z ed      Zej4                  Z ej8                  d       G d d             Zededefd       Zde dee ef   fdZ!de dede fdZ"de dee ee   f   fdZ#de de de fdZ$de dee ee   f   fdZ%de dee ee   f   fdZ&de dee   de fdZ'dejP                  deejR                     fd Z*d!eejP                     dee    fd"Z+ ej8                  d       G d# d$             Z, G d% d&ejZ                        Z. ej8                  d       G d' d(             Z/ G d) d*ejZ                        Z0y)+z)Functions to process IPython magics with.    N)	lru_cache)	find_spec)DictListOptionalTuple)   
   )	TypeGuard)out)NothingChanged)zget_ipython().run_cell_magiczget_ipython().systemzget_ipython().getoutputzget_ipython().run_line_magic)	ENDMARKERNLNEWLINECOMMENTDEDENTUNIMPORTANT_WS
ESCAPED_NL)captureprunpypypythonpython3timetimeitT)frozenc                   "    e Zd ZU eed<   eed<   y)ReplacementmasksrcN)__name__
__module____qualname__str__annotations__     ;/usr/lib/python3/dist-packages/black/handle_ipynb_magics.pyr   r   /   s    
I	Hr'   r   warnreturnc                 `    t        d      d uxr t        d      d u}|s| rd}t        |       |S )Ntokenize_rtIPythonz}Skipping .ipynb files as Jupyter dependencies are not installed.
You can fix this by running ``pip install "black[jupyter]"``)r   r   )r)   	installedmsgs      r(   "jupyter_dependencies_are_installedr0   5   sF     	- ,Q91ET1Q  K 	 	Cr'   r    c                     ddl m}m}m}  ||       }d} ||      D ]<  \  }}|j                  t
        v r|j                  dk(  r|j                  dk(  r||= d} n |s| dfS  ||      dfS )a  Remove trailing semicolon from Jupyter notebook cell.

    For example,

        fig, ax = plt.subplots()
        ax.plot(x_data, y_data);  # plot data

    would become

        fig, ax = plt.subplots()
        ax.plot(x_data, y_data)  # plot data

    Mirrors the logic in `quiet` from `IPython.core.displayhook`, but uses
    ``tokenize_rt`` so that round-tripping works fine.
    r   reversed_enumeratesrc_to_tokenstokens_to_srcFOP;T)r,   r3   r4   r5   nameTOKENS_TO_IGNOREr    )r    r3   r4   r5   tokenstrailing_semicolonidxtokens           r(   remove_trailing_semicolonr>   C   s      ML3F(0 
U::))::%))s"2s!% Ez $&&r'   has_trailing_semicolonc                     |s| S ddl m}m}m}  ||       } ||      D ];  \  }}|j                  t
        v r|j                  |j                  dz         ||<    n t        d      dt         ||            S )zPut trailing semicolon back if cell originally had it.

    Mirrors the logic in `quiet` from `IPython.core.displayhook`, but uses
    ``tokenize_rt`` so that round-tripping works fine.
    r   r2   r7   )r    z{INTERNAL ERROR: Was not able to reinstate trailing semicolon. Please report a bug on https://github.com/psf/black/issues.  N)
r,   r3   r4   r5   r8   r9   _replacer    AssertionErrorr$   )r    r?   r3   r4   r5   r:   r<   r=   s           r(   put_trailing_semicolon_backrC   c   s     "
LL3F(0 	
U::))nnSn9s		 L
 	 }V$%%r'   c                 |   g }	 t        j                  |        | |fS # t        $ r Y nw xY wddlm}  |       }|j                  |       }t        |      \  }}||z  }|j                  |      }t        |      \  }}t        |j                               t        | j                               k7  rt        ||z  }||fS )zMask IPython magics so content becomes parseable Python code.

    For example,

        %matplotlib inline
        'foo'

    becomes

        "25716f358c32750e"
        'foo'

    The replacements are returned, along with the transformed code.
    r   )TransformerManager)astparseSyntaxErrorIPython.core.inputtransformer2rE   transform_cellreplace_cell_magicsreplace_magicslen
splitlinesr   )r    replacementsrE   transformer_managertransformedcell_magic_replacementsmagic_replacementss          r(   	mask_cellrT   {   s     ')L!		# L     B,.%44S9K+>{+K(K(++L%44[AK&4[&A#K#
;!!#$CNN,<(==&&L$$s    	))magicc                     |sJ t        t        |      dz  dz
  d      }t        |      }d}|| v r)t        |      }|dz  }|dkD  rt        d|       d|| v r)t        |      dz   t        |      k  r| d}d| dS )	aD  Return randomly generated token to mask IPython magic with.

    For example, if 'magic' was `%matplotlib inline`, then a possible
    token to mask it with would be `"43fdd17f7e5ddc83"`. The token
    will be the same length as the magic, and we make sure that it was
    not already present anywhere else in the cell.
          r   d   zINTERNAL ERROR: Black was not able to replace IPython magic. Please report a bug on https://github.com/psf/black/issues.  The magic might be helpful: N.")maxrM   	TOKEN_HEXrB   )r    rU   nbytesr=   counters        r(   	get_tokenr`      s     L5Uq1$a(FfEG
3,&!1S= //4g7 		 3, 5zA~E
"'ugQ<r'   c                 <   g }t        j                  |       }t               }|j                  |       |j                  | |fS |j                  j
                  }t        | |      }|j                  t        ||             | d|j                  j                   |fS )aN  Replace cell magic with token.

    Note that 'src' will already have been processed by IPython's
    TransformerManager().transform_cell.

    Example,

        get_ipython().run_cell_magic('t', '-n1', 'ls =!ls\n')

    becomes

        "a794."
        ls =!ls

    The replacement, along with the transformed code, is returned.
    r   r    
)
rF   rG   CellMagicFindervisit
cell_magicheaderr`   appendr   body)r    rO   treecell_magic_finderrg   r   s         r(   rK   rK      s    " ')L99S>D')D!##+L  ))00FS&!D6:;V2'227789<GGr'   c                    g }t               }|j                  t        j                  |              g }t	        | j                         d      D ]  \  }}||j                  v rz|j                  |   }t        |      dk7  rt        d| d      |d   j                  |d   j                  }}t        | |      }	|j                  t        |	|             |d| |	z   }|j                  |        dj                  |      |fS )	ao  Replace magics within body of cell.

    Note that 'src' will already have been processed by IPython's
    TransformerManager().transform_cell.

    Example, this

        get_ipython().run_line_magic('matplotlib', 'inline')
        'foo'

    becomes

        "5e67db56d490fd39"
        'foo'

    The replacement, along with the transformed code, are returned.
    rX   )startz#Expecting one magic per line, got: z<
Please report a bug on https://github.com/psf/black/issues.r   rb   Nrc   )MagicFinderre   rF   rG   	enumeraterN   magicsrM   rB   
col_offsetrU   r`   rh   r   join)
r    rO   magic_findernew_srcsilineoffsets_and_magicsrq   rU   r   s
             r(   rL   rL      s   $ L=Lsyy~&HS^^-Q7 4###!-!4!4Q!7%&!+$9:L9M NR R 
 #1%00"1%++ J S%(D5 AB$t+D  99X,,r'   rO   c                 `    |D ](  }| j                  |j                  |j                        } * | S )zRemove replacements from cell.

    For example

        "9b20"
        foo = bar

    becomes

        %%time
        foo = bar
    )replacer   r    )r    rO   replacements      r(   unmask_cellr{     s2     $ =kk+**KOO<=Jr'   nodec                 ,   t        | t        j                        xry t        | j                  t        j                        xrS t        | j                  j
                  t        j                        xr# | j                  j
                  j                  dk(  S )zCheck if attribute is IPython magic.

    Note that the source of the abstract syntax tree
    will already have been processed by IPython's
    TransformerManager().transform_cell.
    get_ipython)
isinstancerF   	AttributevalueCallfuncNameid)r|   s    r(   _is_ipython_magicr     sf     	4' 	0tzz388,	0tzz1	0 JJOO-/	r'   argsc                     g }| D ]9  }t        |t        j                        sJ |j                  |j                         ; |S N)r   rF   Strrh   s)r   str_argsargs      r(   _get_str_argsr   &  sA    H #sww''' Or'   c                   H    e Zd ZU eed<   ee   ed<   eed<   edefd       Zy)	CellMagicr8   paramsri   r*   c                 p    | j                   rd| j                   d| j                    S d| j                   S )Nz%% )r   r8   selfs    r(   rg   zCellMagic.header4  s5    ;;		{!DKK=11DII;r'   N)r!   r"   r#   r$   r%   r   propertyrg   r&   r'   r(   r   r   .  s/    
ISM
I     r'   r   c                   L    e Zd ZdZddee   ddfdZdej                  ddfdZ	y)	rd   ag  Find cell magics.

    Note that the source of the abstract syntax tree
    will already have been processed by IPython's
    TransformerManager().transform_cell.

    For example,

        %%time

        foo()

    would have been transformed to

        get_ipython().run_cell_magic('time', '', 'foo()\n')

    and we look for instances of the latter.
    Nrf   r*   c                     || _         y r   )rf   )r   rf   s     r(   __init__zCellMagicFinder.__init__O  s	    $r'   r|   c                 h   t        |j                  t        j                        r}t	        |j                  j
                        r^|j                  j
                  j                  dk(  r;t        |j                  j                        }t        |d   |d   |d         | _
        | j                  |       y)z)Find cell magic, extract header and body.run_cell_magicr   rX   rW   )r8   r   ri   N)r   r   rF   r   r   r   attrr   r   r   rf   generic_visit)r   r|   r   s      r(   
visit_ExprzCellMagicFinder.visit_ExprR  sz     tzz388,!$**//2

$$(88 1D'T!WT!W4PQ7SDO4 r'   r   )
r!   r"   r#   __doc__r   r   r   rF   Exprr   r&   r'   r(   rd   rd   <  s6    $%8I#6 %$ %	!sxx 	!D 	!r'   rd   c                   "    e Zd ZU eed<   eed<   y)OffsetAndMagicrq   rU   N)r!   r"   r#   intr%   r$   r&   r'   r(   r   r   ^  s    OJr'   r   c                   `    e Zd ZdZddZdej                  ddfdZdej                  ddfdZ	y)	rn   a  Visit cell to look for get_ipython calls.

    Note that the source of the abstract syntax tree
    will already have been processed by IPython's
    TransformerManager().transform_cell.

    For example,

        %matplotlib inline

    would have been transformed to

        get_ipython().run_line_magic('matplotlib', 'inline')

    and we look for instances of the latter (and likewise for other
    types of magics).
    r*   Nc                 @    t        j                  t              | _        y r   )collectionsdefaultdictlistrp   r   s    r(   r   zMagicFinder.__init__y  s    7B7N7Nt7Tr'   r|   c                    t        |j                  t        j                        r%t	        |j                  j
                        rt        |j                  j                        }|j                  j
                  j                  dk(  r	d|d    }nj|j                  j
                  j                  dk(  rd|d    }|d   r:|d|d    z  }n.t        d|j                  j
                  j                  d	      d
| j                  |j                  j                     j                  t        |j                  j                  |             | j                  |       y
)a{  Look for system assign magics.

        For example,

            black_version = !black --version
            env = %env var

        would have been (respectively) transformed to

            black_version = get_ipython().getoutput('black --version')
            env = get_ipython().run_line_magic('env', 'var')

        and we look for instances of any of the latter.
        	getoutput!r   run_line_magic%rX   r   zUnexpected IPython magic zC found. Please report a bug on https://github.com/psf/black/issues.N)r   r   rF   r   r   r   r   r   r   rB   rp   linenorh   r   rq   r   r   r|   r   r    s       r(   visit_AssignzMagicFinder.visit_Assign|  s    djj#((+0A$**//0R 1Dzz##{2$q'm%%)99$q'm7QtAwi=(C$/

0D0D/G HR R  KK

))*11tzz44c: 	4 r'   c                    t        |j                  t        j                        rKt	        |j                  j
                        r+t        |j                  j                        }|j                  j
                  j                  dk(  r;|d   dk(  r	d|d    }n|d   dk(  r	d|d    }nwd|d    }|d   rj|d	|d    z  }n^|j                  j
                  j                  d
k(  r	d|d    }n2|j                  j
                  j                  dk(  r	d|d    }nt        | j                  |j                  j                     j                  t        |j                  j                  |             | j                  |       y)a  Look for magics in body of cell.

        For examples,

            !ls
            !!ls
            ?ls
            ??ls

        would (respectively) get transformed to

            get_ipython().system('ls')
            get_ipython().getoutput('ls')
            get_ipython().run_line_magic('pinfo', 'ls')
            get_ipython().run_line_magic('pinfo2', 'ls')

        and we look for instances of any of the latter.
        r   r   pinfo?rX   pinfo2z??r   r   systemr   r   z!!N)r   r   rF   r   r   r   r   r   r   r   rp   r   rh   r   rq   r   r   s       r(   r   zMagicFinder.visit_Expr  sD   & djj#((+0A$**//0R 1Dzz##'777g%d1gY-C!W(tAwi.Cd1gY-CAw47)},%%1$q'm%%447)n$$KK

))*11tzz44c: 	4 r'   )r*   N)
r!   r"   r#   r   r   rF   Assignr   r   r   r&   r'   r(   rn   rn   f  s<    $U! ! !B'!sxx '!D '!r'   rn   )1r   rF   r   dataclassessecretssys	functoolsr   importlib.utilr   typingr   r   r   r   version_infor   typing_extensionsblack.outputr   black.reportr   	frozensetTRANSFORMED_MAGICSr9   PYTHON_CELL_MAGICS	token_hexr]   	dataclassr   boolr0   r$   r>   rC   rT   r`   rK   rL   r{   exprr   r   r   r   NodeVisitorrd   r   rn   r&   r'   r(   <module>r      sO   / 
    
  $ . .w +  '              	 d#  $
 
 
 
 
'3 '5d+; '@&S &$ &3 &0%%3 %%5d;&7!78 %%P3 s s 4HS HU3[0A+A%B H>&- &-c4+<&< = &-RS [(9 c $CHH 3==)A SXX 49  d#	  	  $	 !coo !D d#  $^!#// ^!r'   