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