Lichen

pyparser/test/test_pyparse.py

904:938887b82033
2019-06-02 Paul Boddie Prevent "null" usage of assigned names from escaping via the exception handler.
     1 # -*- coding: utf-8 -*-     2 import py     3 from pyparser import pyparse     4 from pyparser.pygram import syms     5 from pyparser.error import SyntaxError, IndentationError     6 from pyparser import consts     7      8      9 class TestPythonParser:    10     11     def setup_class(self):    12         self.parser = pyparse.PythonParser()    13     14     def parse(self, source, mode="exec", info=None):    15         if info is None:    16             info = pyparse.CompileInfo("<test>", mode)    17         return self.parser.parse_source(source, info)    18     19     def test_with_and_as(self):    20         py.test.raises(SyntaxError, self.parse, "with = 23")    21         py.test.raises(SyntaxError, self.parse, "as = 2")    22     23     def test_dont_imply_dedent(self):    24         info = pyparse.CompileInfo("<test>", "single",    25                                    consts.PyCF_DONT_IMPLY_DEDENT)    26         self.parse('if 1:\n  x\n', info=info)    27         self.parse('x = 5 ', info=info)    28     29     def test_clear_state(self):    30         assert self.parser.root is None    31         tree = self.parse("name = 32")    32         assert self.parser.root is None    33     34     def test_encoding(self):    35         info = pyparse.CompileInfo("<test>", "exec")    36         tree = self.parse("""# coding: latin-1    37 stuff = "nothing"    38 """, info=info)    39         assert tree.type == syms["encoding_decl"]    40         assert tree.encoding == "iso-8859-1"    41         assert info.encoding == "iso-8859-1"    42         sentence = u"u'Die M??nner ??rgen sich!'"    43         input = (u"# coding: utf-7\nstuff = %s" % (sentence,)).encode("utf-7")    44         tree = self.parse(input, info=info)    45         assert info.encoding == "utf-7"    46         input = "# coding: iso-8859-15\nx"    47         self.parse(input, info=info)    48         assert info.encoding == "iso-8859-15"    49         input = "\xEF\xBB\xBF# coding: utf-8\nx"    50         self.parse(input, info=info)    51         assert info.encoding == "utf-8"    52         input = "# coding: utf-8\nx"    53         info.flags |= consts.PyCF_SOURCE_IS_UTF8    54         exc = py.test.raises(SyntaxError, self.parse, input, info=info).value    55         info.flags &= ~consts.PyCF_SOURCE_IS_UTF8    56         assert exc.msg == "coding declaration in unicode string"    57         input = "\xEF\xBB\xBF# coding: latin-1\nx"    58         exc = py.test.raises(SyntaxError, self.parse, input).value    59         assert exc.msg == "UTF-8 BOM with latin-1 coding cookie"    60         input = "# coding: not-here"    61         exc = py.test.raises(SyntaxError, self.parse, input).value    62         assert exc.msg == "Unknown encoding: not-here"    63         input = u"# coding: ascii\n\xe2".encode('utf-8')    64         exc = py.test.raises(SyntaxError, self.parse, input).value    65         assert exc.msg == ("'ascii' codec can't decode byte 0xc3 "    66                            "in position 16: ordinal not in range(128)")    67     68     def test_non_unicode_codec(self):    69         exc = py.test.raises(SyntaxError, self.parse, """\    70 # coding: string-escape    71 \x70\x72\x69\x6e\x74\x20\x32\x2b\x32\x0a    72 """).value    73         assert exc.msg == "codec did not return a unicode object"    74     75     def test_syntax_error(self):    76         parse = self.parse    77         exc = py.test.raises(SyntaxError, parse, "name another for").value    78         assert exc.msg == "invalid syntax"    79         assert exc.lineno == 1    80         assert exc.offset == 5    81         assert exc.text.startswith("name another for")    82         exc = py.test.raises(SyntaxError, parse, "x = \"blah\n\n\n").value    83         assert exc.msg == "EOL while scanning string literal"    84         assert exc.lineno == 1    85         assert exc.offset == 5    86         exc = py.test.raises(SyntaxError, parse, "x = '''\n\n\n").value    87         assert exc.msg == "EOF while scanning triple-quoted string literal"    88         assert exc.lineno == 1    89         assert exc.offset == 5    90         assert exc.lastlineno == 3    91         for input in ("())", "(()", "((", "))"):    92             py.test.raises(SyntaxError, parse, input)    93         exc = py.test.raises(SyntaxError, parse, "x = (\n\n(),\n(),").value    94         assert exc.msg == "parenthesis is never closed"    95         assert exc.lineno == 1    96         assert exc.offset == 5    97         assert exc.lastlineno == 5    98         exc = py.test.raises(SyntaxError, parse, "abc)").value    99         assert exc.msg == "unmatched ')'"   100         assert exc.lineno == 1   101         assert exc.offset == 4   102    103     def test_is(self):   104         self.parse("x is y")   105         self.parse("x is not y")   106    107     def test_indentation_error(self):   108         parse = self.parse   109         input = """   110 def f():   111 pass"""   112         exc = py.test.raises(IndentationError, parse, input).value   113         assert exc.msg == "expected an indented block"   114         assert exc.lineno == 3   115         assert exc.text.startswith("pass")   116         assert exc.offset == 0   117         input = "hi\n    indented"   118         exc = py.test.raises(IndentationError, parse, input).value   119         assert exc.msg == "unexpected indent"   120         input = "def f():\n    pass\n  next_stmt"   121         exc = py.test.raises(IndentationError, parse, input).value   122         assert exc.msg == "unindent does not match any outer indentation level"   123         assert exc.lineno == 3   124    125     def test_mac_newline(self):   126         self.parse("this_is\ra_mac\rfile")   127    128     def test_mode(self):   129         assert self.parse("x = 43*54").type == syms["file_input"]   130         tree = self.parse("43**54", "eval")   131         assert tree.type == syms["eval_input"]   132         py.test.raises(SyntaxError, self.parse, "x = 54", "eval")   133         tree = self.parse("x = 43", "single")   134         assert tree.type == syms["single_input"]   135    136     def test_multiline_string(self):   137         self.parse("''' \n '''")   138         self.parse("r''' \n '''")   139    140     def test_bytes_literal(self):   141         self.parse('b" "')   142         self.parse('br" "')   143         self.parse('b""" """')   144         self.parse("b''' '''")   145         self.parse("br'\\\n'")   146    147         py.test.raises(SyntaxError, self.parse, "b'a\\n")   148    149     def test_new_octal_literal(self):   150         self.parse('0777')   151         self.parse('0o777')   152         self.parse('0o777L')   153         py.test.raises(SyntaxError, self.parse, "0o778")   154    155     def test_new_binary_literal(self):   156         self.parse('0b1101')   157         self.parse('0b0l')   158         py.test.raises(SyntaxError, self.parse, "0b112")   159    160     def test_universal_newlines(self):   161         fmt = 'stuff = """hello%sworld"""'   162         expected_tree = self.parse(fmt % '\n')   163         for linefeed in ["\r\n","\r"]:   164             tree = self.parse(fmt % linefeed)   165             assert expected_tree == tree