
    Eg                        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ZddZddZddZddZdS )z6
:func:`~pandas.eval` source string parsing functions
    )annotations)StringIO)	iskeywordN)TYPE_CHECKING)HashableIteratord   namestrreturnc                x   |                                  rt          |           s| S d t          j                                        D                                 dddddddd	d
           d                    f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                B    i | ]\  }}|d t           j        |          d S )_)tokentok_name).0chartokvals      T/var/www/sysmax/venv/lib/python3.11/site-packages/pandas/core/computation/parsing.py
<dictcomp>z2create_valid_python_identifier.<locals>.<dictcomp>,   sA     ' ' 'D& 	+%.(+++' ' '    r   _QUESTIONMARK__EXCLAMATIONMARK__DOLLARSIGN_
_EUROSIGN__DEGREESIGN__SINGLEQUOTE__DOUBLEQUOTE_) ?!$u   €   °'" c                <    g | ]}                     ||          S  )get)r   r   special_characters_replacementss     r   
<listcomp>z2create_valid_python_identifier.<locals>.<listcomp>@   s*    UUU377dCCUUUr   BACKTICK_QUOTED_STRING_zCould not convert 'z' to a valid Python identifier.)isidentifierr   tokenizeEXACT_TOKEN_TYPESitemsupdatejoinSyntaxError)r
   r*   s    @r   create_valid_python_identifierr4      s       9T?? 
' '%7==??' ' '# $**!$   	
 	
    77UUUUPTUUUVVD+T++D WUUUUVVVKr   toktuple[int, str]c                `    | \  }}|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.   NAMEr4   )r5   toknumr   s      r   clean_backtick_quoted_toksr;   I   s9    ( NFF'''}<VDDDD6>r   r   c                    	 t          d|  d          }t          |          d         }t          |          S # t          $ r | cY S w xY 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nextr4   r3   )r
   	tokenizedr   s      r   clean_column_namerB   c   s^    :#KKKK00	i#-f555   s   69 AAtoken_generatorIterator[tokenize.TokenInfo]sourcestring_startintc                Z    | D ]\  }}}}}|dk    r
|d         } n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).
    r=   r>   )r8   )rC   rE   rF   r   r   start
string_ends          r   tokenize_backtick_quoted_stringrK      sQ    4 #2  65!QS==qJE  "6,z*A#BBBr   Iterator[tuple[int, str]]c              #    K   t          |           j        }t          j        |          }|D ]Y\  }}}}}|dk    rE	 t	          || |d         dz             V  -# t
          $ r}t          d|  d          |d}~ww xY w||fV  Zd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]).
    r=   r>   )rF   zFailed to parse backticks in 'z'.N)r   readliner.   generate_tokensrK   	Exceptionr3   )rE   line_readerrC   r:   r   rI   r   errs           r   r?   r?      s       6""+K.{;;O (7 	! 	!#q!S==X5#V%(Q,        X X X!"M6"M"M"MNNTWWX &.    	! 	!s   A
A=$A88A=)r
   r   r   r   )r5   r6   r   r6   )r
   r   r   r   )rC   rD   rE   r   rF   rG   r   r6   )rE   r   r   rL   )__doc__
__future__r   ior   keywordr   r   r.   typingr   collections.abcr   r   r8   r4   r;   rB   rK   r?   r(   r   r   <module>rY      s    # " " " " "                                    0 0 0 0f   4" " " "JC C C CD! ! ! ! ! !r   