a
    hq;                     @   sJ   d dl mZ d dlZd dlZddlmZmZmZmZm	Z	 G dd dZ
dS )    )contextmanagerN   )ParserElementParseExceptionKeyword__diag__
__compat__c                   @   s|   e Zd ZdZG dd dZG dd dZedd	dd
eej	e
 ej	e
 eeej	e ej	e ejee
f eed
ddZdS )pyparsing_testzB
    namespace class for classes useful in writing unit tests
    c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )z&pyparsing_test.reset_pyparsing_contexta?  
        Context manager to be used when writing unit tests that modify pyparsing config values:
        - packrat parsing
        - bounded recursion parsing
        - default whitespace characters
        - default keyword characters
        - literal string auto-conversion class
        - ``__diag__`` settings

        Example:

        .. testcode::

            ppt = pyparsing.pyparsing_test

            class MyTestClass(ppt.TestParseResultsAsserts):
                def test_literal(self):
                    with ppt.reset_pyparsing_context():
                        # test that literals used to construct
                        # a grammar are automatically suppressed
                        ParserElement.inline_literals_using(Suppress)

                        term = Word(alphas) | Word(nums)
                        group = Group('(' + term[...] + ')')

                        # assert that the '()' characters
                        # are not included in the parsed tokens
                        self.assertParseAndCheckList(
                            group,
                            "(abc 123 def)",
                            ['abc', '123', 'def']
                        )

                    # after exiting context manager, literals
                    # are converted to Literal expressions again
        c                 C   s
   i | _ d S N)_save_contextself r   ^/mounts/lovelace/software/anaconda3/envs/py39/lib/python3.9/site-packages/pyparsing/testing.py__init__<   s    z/pyparsing_test.reset_pyparsing_context.__init__c                 C   s   t j| jd< tj| jd< t j| jd< t j| jd< t j| jd< t jrRt jj	| jd< n
d | jd< t j
| jd< t j| jd< d	d
 tjD | jd< dtji| jd< | S )Ndefault_whitespacedefault_keyword_charsliteral_string_classverbose_stacktracepackrat_enabledpackrat_cache_sizepackrat_parserecursion_enabledc                 S   s   i | ]}|t t|qS r   )getattrr   ).0namer   r   r   
<dictcomp>U   s   z?pyparsing_test.reset_pyparsing_context.save.<locals>.<dictcomp>r   collect_all_And_tokensr   )r   DEFAULT_WHITE_CHARSr   r   DEFAULT_KEYWORD_CHARSZ_literalStringClassr   _packratEnabledZpackrat_cachesize_parse_left_recursion_enabledr   Z
_all_namesr   r   r   r   r   r   save?   s&    


z+pyparsing_test.reset_pyparsing_context.savec                 C   s   t j| jd kr t | jd  | jd t _| jd t_t | jd  | jd  D ]\}}|rht	j
nt	j| qVdt _| jd rt | jd  n| jd	 t _| jd
 t _| jd t_| S )Nr   r   r   r   r   Fr   r   r   r   r   )r   r   r   Zset_default_whitespace_charsr   r   r   ZinlineLiteralsUsingitemsr   enabledisabler    Zenable_packratr"   r#   r   r   )r   r   valuer   r   r   restore_   s.    
z.pyparsing_test.reset_pyparsing_context.restorec                 C   s   t |  }|j| j |S r
   )typer   update)r   retr   r   r   copy   s    
z+pyparsing_test.reset_pyparsing_context.copyc                 C   s   |   S r
   )r$   r   r   r   r   	__enter__   s    z0pyparsing_test.reset_pyparsing_context.__enter__c                 G   s   |    d S r
   )r)   )r   argsr   r   r   __exit__   s    z/pyparsing_test.reset_pyparsing_context.__exit__N)
__name__
__module____qualname____doc__r   r$   r)   r-   r.   r0   r   r   r   r   reset_pyparsing_context   s   % !r5   c                   @   sL   e Zd ZdZdddZdddZddd	Zdd
dZee	ddfddZ
dS )z&pyparsing_test.TestParseResultsAssertszk
        A mixin class to add parse results assertion methods to normal unittest.TestCase classes.
        Nc                 C   s<   |dur| j || |d |dur8| j || |d dS )z
            Unit test assertion to compare a :class:`ParseResults` object with an optional ``expected_list``,
            and compare any defined results names with an optional ``expected_dict``.
            Nmsg)ZassertEqualas_listas_dict)r   resultexpected_listexpected_dictr7   r   r   r   assertParseResultsEquals   s    z?pyparsing_test.TestParseResultsAsserts.assertParseResultsEqualsTc                 C   s@   |j |dd}|r t|  nt|  | j|||d dS )z
            Convenience wrapper assert to test a parser element and input string, and assert that
            the resulting :meth:`ParseResults.as_list` is equal to the ``expected_list``.
            T)Z	parse_all)r;   r7   Nparse_stringprintdumpr8   r=   )r   exprtest_stringr;   r7   verboser:   r   r   r   assertParseAndCheckList   s
    z>pyparsing_test.TestParseResultsAsserts.assertParseAndCheckListc                 C   s@   |j |dd}|r t|  nt|  | j|||d dS )z
            Convenience wrapper assert to test a parser element and input string, and assert that
            the resulting :meth:`ParseResults.as_dict` is equal to the ``expected_dict``.
            T)ZparseAll)r<   r7   Nr>   )r   rB   rC   r<   r7   rD   r:   r   r   r   assertParseAndCheckDict   s
    z>pyparsing_test.TestParseResultsAsserts.assertParseAndCheckDictc              	   C   sB  |\}}|du r.| j ||dur"|ndd dS dd t||D }|D ]\}}}	tdd |	D d}
tdd |	D d}|dur| j||
p|d	 t|tr|W d   n1 s0    Y  qFtd
d |	D d}tdd |	D d}||fdkr| j||||
p
|d qFtd| qF| j ||dur6|ndd dS )a2  
            Unit test assertion to evaluate output of
            :meth:`~ParserElement.run_tests`.

            If a list of list-dict tuples is given as the
            ``expected_parse_results`` argument, then these are zipped
            with the report tuples returned by ``run_tests()``
            and evaluated using :meth:`assertParseResultsEquals`.
            Finally, asserts that the overall
            `:meth:~ParserElement.run_tests` success value is ``True``.

            :param run_tests_report: the return value from :meth:`ParserElement.run_tests`
            :type run_tests_report: tuple[bool, list[tuple[str, ParseResults | Exception]]]
            :param expected_parse_results: (optional)
            :type expected_parse_results: list[tuple[str | list | dict | Exception, ...]]
            Nzfailed runTestsr6   c                 S   s   g | ]\}}g ||R qS r   r   )r   Zrptexpectedr   r   r   
<listcomp>   s   zOpyparsing_test.TestParseResultsAsserts.assertRunTestResults.<locals>.<listcomp>c                 s   s   | ]}t |tr|V  qd S r
   )
isinstancestrr   expr   r   r   	<genexpr>       zNpyparsing_test.TestParseResultsAsserts.assertRunTestResults.<locals>.<genexpr>c                 s   s&   | ]}t |trt|tr|V  qd S r
   )rI   r*   
issubclass	ExceptionrK   r   r   r   rM      s   )expected_exceptionr7   c                 s   s   | ]}t |tr|V  qd S r
   )rI   listrK   r   r   r   rM      rN   c                 s   s   | ]}t |tr|V  qd S r
   )rI   dictrK   r   r   r   rM      rN   )NN)r;   r<   r7   zno validation for )Z
assertTruezipnextassertRaisesrI   rP   r=   r@   )r   Zrun_tests_reportZexpected_parse_resultsr7   Zrun_test_successZrun_test_resultsZmergedrC   r:   rG   Zfail_msgrQ   r;   r<   r   r   r   assertRunTestResults   sP    
$z;pyparsing_test.TestParseResultsAsserts.assertRunTestResultsc                 c   s   |d urTt |trt|}| j|||d}|V  W d    q1 sH0    Y  n4| j||d}|V  W d    n1 s~0    Y  d S )Nr6   )rI   rJ   reescapeassertRaisesRegexrV   )r   exc_typeZexpected_msgr7   ctxr   r   r   assertRaisesParseException  s    

&zApyparsing_test.TestParseResultsAsserts.assertRaisesParseException)NNN)NT)NT)NN)r1   r2   r3   r4   r=   rE   rF   rW   r   r   r]   r   r   r   r   TestParseResultsAsserts   s    
 
 
 
Ir^   NT| )indentbase_1)
s
start_lineend_lineexpand_tabseol_markmark_spacesmark_controlra   rb   returnc             	      s  |r|   } ttrd   |durtt|}|dkrzdd ttddtdd	D }	d
|	d< t|	}
d n0t	|tfddt
tdddg D }
| |
} |dur|dkr|dkrtddd}
| |
} n| d|} |du rd}|du rt| }t|t| }ttd||}|dkrR|  || | }n dd | d|| | D }|s|dS tt|tdd |D }dd   }|dkr||rdnd ddd t|rdndt|d dD  d }nd}|rdnd| ddd t| d  D  d }d}||rDdnd || d    d }|| d fd dt||| d!D  d S )"u  
        Helpful method for debugging a parser - prints a string with line and column numbers.
        (Line and column numbers are 1-based by default - if debugging a parse action,
        pass base_1=False, to correspond to the loc value passed to the parse action.)

        :param s: string to be printed with line and column numbers
        :param start_line: starting line number in s to print (default=1)
        :param end_line: ending line number in s to print (default=len(s))
        :param expand_tabs: expand tabs to spaces, to match the pyparsing default
        :param eol_mark: string to mark the end of lines, helps visualize trailing spaces
        :param mark_spaces: special character to display in place of spaces
        :param mark_control: convert non-printing control characters to a placeholding
                             character; valid values:
                                 
                             - ``"unicode"`` - replaces control chars with Unicode symbols, such as "␍" and "␊"
                             - any single character string - replace control characters with given string
                             - ``None`` (default) - string is displayed as-is


        :param indent: string to indent with line and column numbers; if an int
                       is passed, converted to ``" " * indent``
        :param base_1: whether to label string using base 1; if False, string will be
                       labeled based at 0

        :returns: input string with leading line numbers and column number headers

        .. versionchanged:: 3.2.0
           New ``indent`` and ``base_1`` arguments.
         Nunicodec                 S   s   i | ]\}}||qS r   r   )r   cur   r   r   r   A  s   z4pyparsing_test.with_line_numbers.<locals>.<dictcomp>r   !   i $  i3$  i!$     r`   c                    s   i | ]
}| qS r   r   )r   rm   )ord_mark_controlr   r   r   J  rN       i	$  i#$  )	   rr   c                 S   s   g | ]}|d  qS )   ␊r   r   liner   r   r   rH   ]  s   z4pyparsing_test.with_line_numbers.<locals>.<listcomp>rt   c                 s   s   | ]}t |V  qd S r
   )lenru   r   r   r   rM   d  rN   z3pyparsing_test.with_line_numbers.<locals>.<genexpr>r   c   c                 s   s"   | ]}d  |d d  V  qdS )zc                                                                                                   r   d   Nr   r   ir   r   r   rM   j  s   ry   
c                 s   s    | ]}d |d d  V  qdS )z	         r   
   Nr   rz   r   r   r   rM   u  rN   r}   Z
12345678900c                 3   s0   | ](\}} | d d|   V  qdS )d:Nr   )r   r{   rv   )rg   ra   lineno_widthr   r   rM     s   )start)
expandtabsrI   inttypingcastrJ   rT   range	maketransordrR   	translatereplacerw   minmax
splitlinessplitjoin	enumerate)rc   rd   re   rf   rg   rh   ri   ra   rb   Ztranstable_mapZtblZs_linesZmax_line_lenZleadZheader0Zheader1digitsZheader2r   )rg   ra   r   rq   r   with_line_numbers  s    *

 






$z pyparsing_test.with_line_numbers)NNTr_   NN)r1   r2   r3   r4   r5   r^   staticmethodrJ   r   Optionalr   boolUnionr   r   r   r   r   r	      s4   u       	r	   )
contextlibr   rX   r   corer   r   r   r   r   r	   r   r   r   r   <module>   s   	