o
    �¨Êhÿ  ã                   @  s’   d Z ddlmZ ddlmZ ddlmZ ddlZddlZddl	m
Z
 e
r,ddlmZmZ dZddd„Zd dd„Zd!dd„Zd"dd„Zd#dd„ZdS )$z6
:func:`~pandas.eval` source string parsing functions
é    )Úannotations)ÚStringIO)Ú	iskeywordN)ÚTYPE_CHECKING)ÚHashableÚIteratoréd   ÚnameÚstrÚreturnc                   s‚   |   ¡ r
t| ƒs
| S dd„ tj ¡ D ƒ‰ ˆ  ddddddd	d
dœ¡ d ‡ fdd„| D ƒ¡} d| › �} |   ¡ s?td| › d�ƒ‚| S )a=  
    Create valid Python identifiers from any string.

    Check if name contains any special characters. If it contains any
    special characters, the special characters will be replaced by
    a special string and a prefix is added.

    Raises
    ------
    SyntaxError
        If the returned name is not a Python valid identifier, raise an exception.
        This can happen if there is a hashtag in the name, as the tokenizer will
        than terminate and not find the backtick.
        But also for characters that fall out of the range of (U+0001..U+007F).
    c                 S  s$   i | ]\}}|d t j| › d �“qS )Ú_)ÚtokenÚtok_name)Ú.0ÚcharÚtokval© r   úQ/var/www/html/env/lib/python3.10/site-packages/pandas/core/computation/parsing.pyÚ
<dictcomp>,   s    ÿÿz2create_valid_python_identifier.<locals>.<dictcomp>r   Ú_QUESTIONMARK_Ú_EXCLAMATIONMARK_Ú_DOLLARSIGN_Ú
_EUROSIGN_Ú_DEGREESIGN_Ú_SINGLEQUOTE_Ú_DOUBLEQUOTE_)ú ú?ú!ú$u   â‚¬õ   Â°ú'ú"Ú c                   s   g | ]}ˆ   ||¡‘qS r   )Úget)r   r   ©Úspecial_characters_replacementsr   r   Ú
<listcomp>@   s    z2create_valid_python_identifier.<locals>.<listcomp>ÚBACKTICK_QUOTED_STRING_zCould not convert 'z' to a valid Python identifier.)Úisidentifierr   ÚtokenizeÚEXACT_TOKEN_TYPESÚitemsÚupdateÚjoinÚSyntaxError)r	   r   r%   r   Úcreate_valid_python_identifier   s*   þ÷ÿ
r0   Útokútuple[int, str]c                 C  s&   | \}}|t krtjt|ƒfS ||fS )a[  
    Clean up a column name if surrounded by backticks.

    Backtick quoted string are indicated by a certain tokval value. If a string
    is a backtick quoted token it will processed by
    :func:`_create_valid_python_identifier` so that the parser can find this
    string when the query is executed.
    In this case the tok will get the NAME tokval.

    Parameters
    ----------
    tok : tuple of int, str
        ints correspond to the all caps constants in the tokenize module

    Returns
    -------
    tok : Tuple[int, str]
        Either the input or token or the replacement values
    )ÚBACKTICK_QUOTED_STRINGr*   ÚNAMEr0   )r1   Útoknumr   r   r   r   Úclean_backtick_quoted_toksI   s   r6   r   c                 C  s>   zt d| › d�ƒ}t|ƒd }t|ƒW S  ty   |  Y S w )a¼  
    Function to emulate the cleaning of a backtick quoted name.

    The purpose for this function is to see what happens to the name of
    identifier if it goes to the process of being parsed a Python code
    inside a backtick quoted string and than being cleaned
    (removed of any special characters).

    Parameters
    ----------
    name : hashable
        Name to be cleaned.

    Returns
    -------
    name : hashable
        Returns the name after tokenizing and cleaning.

    Notes
    -----
        For some cases, a name cannot be converted to a valid Python identifier.
        In that case :func:`tokenize_string` raises a SyntaxError.
        In that case, we just return the name unmodified.

        If this name was used in the query string (this makes the query call impossible)
        an error will be raised by :func:`tokenize_backtick_quoted_string` instead,
        which is not caught and propagates to the user level.
    ú`é   )Útokenize_stringÚnextr0   r/   )r	   Ú	tokenizedr   r   r   r   Úclean_column_namec   s   
ÿr<   Útoken_generatorúIterator[tokenize.TokenInfo]ÚsourceÚstring_startÚintc                 C  s8   | D ]\}}}}}|dkr|d } nqt |||… fS )a»  
    Creates a token from a backtick quoted string.

    Moves the token_generator forwards till right after the next backtick.

    Parameters
    ----------
    token_generator : Iterator[tokenize.TokenInfo]
        The generator that yields the tokens of the source string (Tuple[int, str]).
        The generator is at the first token after the backtick (`)

    source : str
        The Python source code string.

    string_start : int
        This is the start of backtick quoted string inside the source string.

    Returns
    -------
    tok: Tuple[int, str]
        The token that represents the backtick quoted string.
        The integer is equal to BACKTICK_QUOTED_STRING (100).
    r7   r8   )r3   )r=   r?   r@   r   r   ÚstartÚ
string_endr   r   r   Útokenize_backtick_quoted_stringˆ   s   þrD   úIterator[tuple[int, str]]c                 c  sˆ   � t | ƒj}t |¡}|D ]4\}}}}}|dkr<zt|| |d d d�V  W q ty; } z	td| › d�ƒ|‚d}~ww ||fV  qdS )a$  
    Tokenize a Python source code string.

    Parameters
    ----------
    source : str
        The Python source code string.

    Returns
    -------
    tok_generator : Iterator[Tuple[int, str]]
        An iterator yielding all tokens with only toknum and tokval (Tuple[ing, str]).
    r7   r8   )r@   zFailed to parse backticks in 'z'.N)r   Úreadliner*   Úgenerate_tokensrD   Ú	Exceptionr/   )r?   Úline_readerr=   r5   r   rB   r   Úerrr   r   r   r9   ª   s   €

ÿ€ÿ÷r9   )r	   r
   r   r
   )r1   r2   r   r2   )r	   r   r   r   )r=   r>   r?   r
   r@   rA   r   r2   )r?   r
   r   rE   )Ú__doc__Ú
__future__r   Úior   Úkeywordr   r   r*   Útypingr   Úcollections.abcr   r   r3   r0   r6   r<   rD   r9   r   r   r   r   Ú<module>   s    

3

%"