1  """
       2     Test cases for codeop.py
       3     Nick Mathewson
       4  """
       5  import unittest
       6  import warnings
       7  from test.support import warnings_helper
       8  
       9  from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT
      10  
      11  class ESC[4;38;5;81mCodeopTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      12  
      13      def assertValid(self, str, symbol='single'):
      14          '''succeed iff str is a valid piece of code'''
      15          expected = compile(str, "<input>", symbol, PyCF_DONT_IMPLY_DEDENT)
      16          self.assertEqual(compile_command(str, "<input>", symbol), expected)
      17  
      18      def assertIncomplete(self, str, symbol='single'):
      19          '''succeed iff str is the start of a valid piece of code'''
      20          self.assertEqual(compile_command(str, symbol=symbol), None)
      21  
      22      def assertInvalid(self, str, symbol='single', is_syntax=1):
      23          '''succeed iff str is the start of an invalid piece of code'''
      24          try:
      25              compile_command(str,symbol=symbol)
      26              self.fail("No exception raised for invalid code")
      27          except SyntaxError:
      28              self.assertTrue(is_syntax)
      29          except OverflowError:
      30              self.assertTrue(not is_syntax)
      31  
      32      def test_valid(self):
      33          av = self.assertValid
      34  
      35          # special case
      36          self.assertEqual(compile_command(""),
      37                              compile("pass", "<input>", 'single',
      38                                      PyCF_DONT_IMPLY_DEDENT))
      39          self.assertEqual(compile_command("\n"),
      40                              compile("pass", "<input>", 'single',
      41                                      PyCF_DONT_IMPLY_DEDENT))
      42  
      43          av("a = 1")
      44          av("\na = 1")
      45          av("a = 1\n")
      46          av("a = 1\n\n")
      47          av("\n\na = 1\n\n")
      48  
      49          av("def x():\n  pass\n")
      50          av("if 1:\n pass\n")
      51  
      52          av("\n\nif 1: pass\n")
      53          av("\n\nif 1: pass\n\n")
      54  
      55          av("def x():\n\n pass\n")
      56          av("def x():\n  pass\n  \n")
      57          av("def x():\n  pass\n \n")
      58  
      59          av("pass\n")
      60          av("3**3\n")
      61  
      62          av("if 9==3:\n   pass\nelse:\n   pass\n")
      63          av("if 1:\n pass\n if 1:\n  pass\n else:\n  pass\n")
      64  
      65          av("#a\n#b\na = 3\n")
      66          av("#a\n\n   \na=3\n")
      67          av("a=3\n\n")
      68          av("a = 9+ \\\n3")
      69  
      70          av("3**3","eval")
      71          av("(lambda z: \n z**3)","eval")
      72  
      73          av("9+ \\\n3","eval")
      74          av("9+ \\\n3\n","eval")
      75  
      76          av("\n\na**3","eval")
      77          av("\n \na**3","eval")
      78          av("#a\n#b\na**3","eval")
      79  
      80          av("\n\na = 1\n\n")
      81          av("\n\nif 1: a=1\n\n")
      82  
      83          av("if 1:\n pass\n if 1:\n  pass\n else:\n  pass\n")
      84          av("#a\n\n   \na=3\n\n")
      85  
      86          av("\n\na**3","eval")
      87          av("\n \na**3","eval")
      88          av("#a\n#b\na**3","eval")
      89  
      90          av("def f():\n try: pass\n finally: [x for x in (1,2)]\n")
      91          av("def f():\n pass\n#foo\n")
      92          av("@a.b.c\ndef f():\n pass\n")
      93  
      94      def test_incomplete(self):
      95          ai = self.assertIncomplete
      96  
      97          ai("(a **")
      98          ai("(a,b,")
      99          ai("(a,b,(")
     100          ai("(a,b,(")
     101          ai("a = (")
     102          ai("a = {")
     103          ai("b + {")
     104  
     105          ai("print([1,\n2,")
     106          ai("print({1:1,\n2:3,")
     107          ai("print((1,\n2,")
     108  
     109          ai("if 9==3:\n   pass\nelse:")
     110          ai("if 9==3:\n   pass\nelse:\n")
     111          ai("if 9==3:\n   pass\nelse:\n   pass")
     112          ai("if 1:")
     113          ai("if 1:\n")
     114          ai("if 1:\n pass\n if 1:\n  pass\n else:")
     115          ai("if 1:\n pass\n if 1:\n  pass\n else:\n")
     116          ai("if 1:\n pass\n if 1:\n  pass\n else:\n  pass")
     117  
     118          ai("def x():")
     119          ai("def x():\n")
     120          ai("def x():\n\n")
     121  
     122          ai("def x():\n  pass")
     123          ai("def x():\n  pass\n ")
     124          ai("def x():\n  pass\n  ")
     125          ai("\n\ndef x():\n  pass")
     126  
     127          ai("a = 9+ \\")
     128          ai("a = 'a\\")
     129          ai("a = '''xy")
     130  
     131          ai("","eval")
     132          ai("\n","eval")
     133          ai("(","eval")
     134          ai("(9+","eval")
     135          ai("9+ \\","eval")
     136          ai("lambda z: \\","eval")
     137  
     138          ai("if True:\n if True:\n  if True:   \n")
     139  
     140          ai("@a(")
     141          ai("@a(b")
     142          ai("@a(b,")
     143          ai("@a(b,c")
     144          ai("@a(b,c,")
     145  
     146          ai("from a import (")
     147          ai("from a import (b")
     148          ai("from a import (b,")
     149          ai("from a import (b,c")
     150          ai("from a import (b,c,")
     151  
     152          ai("[")
     153          ai("[a")
     154          ai("[a,")
     155          ai("[a,b")
     156          ai("[a,b,")
     157  
     158          ai("{")
     159          ai("{a")
     160          ai("{a:")
     161          ai("{a:b")
     162          ai("{a:b,")
     163          ai("{a:b,c")
     164          ai("{a:b,c:")
     165          ai("{a:b,c:d")
     166          ai("{a:b,c:d,")
     167  
     168          ai("a(")
     169          ai("a(b")
     170          ai("a(b,")
     171          ai("a(b,c")
     172          ai("a(b,c,")
     173  
     174          ai("a[")
     175          ai("a[b")
     176          ai("a[b,")
     177          ai("a[b:")
     178          ai("a[b:c")
     179          ai("a[b:c:")
     180          ai("a[b:c:d")
     181  
     182          ai("def a(")
     183          ai("def a(b")
     184          ai("def a(b,")
     185          ai("def a(b,c")
     186          ai("def a(b,c,")
     187  
     188          ai("(")
     189          ai("(a")
     190          ai("(a,")
     191          ai("(a,b")
     192          ai("(a,b,")
     193  
     194          ai("if a:\n pass\nelif b:")
     195          ai("if a:\n pass\nelif b:\n pass\nelse:")
     196  
     197          ai("while a:")
     198          ai("while a:\n pass\nelse:")
     199  
     200          ai("for a in b:")
     201          ai("for a in b:\n pass\nelse:")
     202  
     203          ai("try:")
     204          ai("try:\n pass\nexcept:")
     205          ai("try:\n pass\nfinally:")
     206          ai("try:\n pass\nexcept:\n pass\nfinally:")
     207  
     208          ai("with a:")
     209          ai("with a as b:")
     210  
     211          ai("class a:")
     212          ai("class a(")
     213          ai("class a(b")
     214          ai("class a(b,")
     215          ai("class a():")
     216  
     217          ai("[x for")
     218          ai("[x for x in")
     219          ai("[x for x in (")
     220  
     221          ai("(x for")
     222          ai("(x for x in")
     223          ai("(x for x in (")
     224  
     225      def test_invalid(self):
     226          ai = self.assertInvalid
     227          ai("a b")
     228  
     229          ai("a @")
     230          ai("a b @")
     231          ai("a ** @")
     232  
     233          ai("a = ")
     234          ai("a = 9 +")
     235  
     236          ai("def x():\n\npass\n")
     237  
     238          ai("\n\n if 1: pass\n\npass")
     239  
     240          ai("a = 9+ \\\n")
     241          ai("a = 'a\\ ")
     242          ai("a = 'a\\\n")
     243  
     244          ai("a = 1","eval")
     245          ai("]","eval")
     246          ai("())","eval")
     247          ai("[}","eval")
     248          ai("9+","eval")
     249          ai("lambda z:","eval")
     250          ai("a b","eval")
     251  
     252          ai("return 2.3")
     253          ai("if (a == 1 and b = 2): pass")
     254  
     255          ai("del 1")
     256          ai("del (1,)")
     257          ai("del [1]")
     258          ai("del '1'")
     259  
     260          ai("[i for i in range(10)] = (1, 2, 3)")
     261  
     262      def test_invalid_exec(self):
     263          ai = self.assertInvalid
     264          ai("raise = 4", symbol="exec")
     265          ai('def a-b', symbol='exec')
     266          ai('await?', symbol='exec')
     267          ai('=!=', symbol='exec')
     268          ai('a await raise b', symbol='exec')
     269          ai('a await raise b?+1', symbol='exec')
     270  
     271      def test_filename(self):
     272          self.assertEqual(compile_command("a = 1\n", "abc").co_filename,
     273                           compile("a = 1\n", "abc", 'single').co_filename)
     274          self.assertNotEqual(compile_command("a = 1\n", "abc").co_filename,
     275                              compile("a = 1\n", "def", 'single').co_filename)
     276  
     277      def test_warning(self):
     278          # Test that the warning is only returned once.
     279          with warnings_helper.check_warnings(
     280                  ('"is" with \'str\' literal', SyntaxWarning),
     281                  ("invalid escape sequence", SyntaxWarning),
     282                  ) as w:
     283              compile_command(r"'\e' is 0")
     284              self.assertEqual(len(w.warnings), 2)
     285  
     286          # bpo-41520: check SyntaxWarning treated as an SyntaxError
     287          with warnings.catch_warnings(), self.assertRaises(SyntaxError):
     288              warnings.simplefilter('error', SyntaxWarning)
     289              compile_command('1 is 1', symbol='exec')
     290  
     291          # Check SyntaxWarning treated as an SyntaxError
     292          with warnings.catch_warnings(), self.assertRaises(SyntaxError):
     293              warnings.simplefilter('error', SyntaxWarning)
     294              compile_command(r"'\e'", symbol='exec')
     295  
     296      def test_incomplete_warning(self):
     297          with warnings.catch_warnings(record=True) as w:
     298              warnings.simplefilter('always')
     299              self.assertIncomplete("'\\e' + (")
     300          self.assertEqual(w, [])
     301  
     302      def test_invalid_warning(self):
     303          with warnings.catch_warnings(record=True) as w:
     304              warnings.simplefilter('always')
     305              self.assertInvalid("'\\e' 1")
     306          self.assertEqual(len(w), 1)
     307          self.assertEqual(w[0].category, SyntaxWarning)
     308          self.assertRegex(str(w[0].message), 'invalid escape sequence')
     309          self.assertEqual(w[0].filename, '<input>')
     310  
     311  
     312  if __name__ == "__main__":
     313      unittest.main()