File: C:/Users/fred/anaconda3/Lib/site-packages/astropy/utils/tests/test_parsing.py
# Licensed under a 3-clause BSD style license - see LICENSE.rst
import importlib
import secrets
from py_compile import compile
from textwrap import dedent
import pytest
from astropy.utils.parsing import _TAB_HEADER
def _docstring_canary():
"""Docstring that's here just to check for -OO."""
@pytest.mark.skipif(not _docstring_canary.__doc__, reason="Test cannot be run with -OO")
def test_generate_parser(tmp_path, monkeypatch):
# Write Python code into the temporary directory, so that the
# generated tables will also go into the temporary directory.
# We use a unique suffix so that the test can be run multiple times
# without weirdness due to module caching.
suffix = secrets.token_hex(16)
lexer_file = tmp_path / f"test_parsing_lexer_{suffix}.py"
lexer_file.write_text(
dedent(
rf"""
from astropy.utils.parsing import lex
def make_lexer():
tokens = ('NUMBER', 'PLUS')
t_PLUS = r'\+'
def t_NUMBER(t):
r'\d+'
t.value = int(t.value)
return t
def t_error(t):
raise ValueError('Invalid character')
return lex('test_parsing_lextab_{suffix}', 'test_parsing_lexer_{suffix}')
"""
)
)
parser_file = tmp_path / f"test_parsing_parser_{suffix}.py"
parser_file.write_text(
dedent(
rf"""
from astropy.utils.parsing import yacc
def make_parser():
tokens = ('NUMBER', 'PLUS')
def p_expression_number(p):
'expression : NUMBER'
p[0] = p[1]
def p_expression_plus(p):
'expression : expression PLUS NUMBER'
p[0] = p[1] + p[3]
return yacc('test_parsing_parsetab_{suffix}', 'test_parsing_parser_{suffix}')
"""
)
)
monkeypatch.syspath_prepend(tmp_path)
lexer_mod = importlib.import_module(f"test_parsing_lexer_{suffix}")
lexer = lexer_mod.make_lexer()
parser_mod = importlib.import_module(f"test_parsing_parser_{suffix}")
parser = parser_mod.make_parser()
result = parser.parse("1+2+3", lexer=lexer)
assert result == 6
lextab_path = tmp_path / f"test_parsing_lextab_{suffix}.py"
lextab = lextab_path.read_text()
assert lextab.startswith(_TAB_HEADER.format(package=f"test_parsing_lexer_{suffix}"))
parsetab_path = tmp_path / f"test_parsing_parsetab_{suffix}.py"
parsetab = parsetab_path.read_text()
assert parsetab.startswith(
_TAB_HEADER.format(package=f"test_parsing_parser_{suffix}")
)
# Now test bytecode-only distribution of the parsetab and lextab
lexer_mod = importlib.reload(lexer_mod)
parser_mod = importlib.reload(parser_mod)
for path in lextab_path, parsetab_path:
compile(path, cfile=path.with_suffix(".pyc"), doraise=True)
path.unlink()
lexer = lexer_mod.make_lexer()
parser = parser_mod.make_parser()
result = parser.parse("1+2+3", lexer=lexer)
assert result == 6