/Lib/lib2to3/tests/test_parser.py

http://unladen-swallow.googlecode.com/ · Python · 202 lines · 140 code · 34 blank · 28 comment · 10 complexity · cbd31809d8ce5f34919c9cc1e562af92 MD5 · raw file

  1. #!/usr/bin/env python2.5
  2. """Test suite for 2to3's parser and grammar files.
  3. This is the place to add tests for changes to 2to3's grammar, such as those
  4. merging the grammars for Python 2 and 3. In addition to specific tests for
  5. parts of the grammar we've changed, we also make sure we can parse the
  6. test_grammar.py files from both Python 2 and Python 3.
  7. """
  8. # Author: Collin Winter
  9. # Testing imports
  10. from . import support
  11. from .support import driver, test_dir
  12. # Python imports
  13. import os
  14. import os.path
  15. # Local imports
  16. from ..pgen2.parse import ParseError
  17. class GrammarTest(support.TestCase):
  18. def validate(self, code):
  19. support.parse_string(code)
  20. def invalid_syntax(self, code):
  21. try:
  22. self.validate(code)
  23. except ParseError:
  24. pass
  25. else:
  26. raise AssertionError("Syntax shouldn't have been valid")
  27. class TestRaiseChanges(GrammarTest):
  28. def test_2x_style_1(self):
  29. self.validate("raise")
  30. def test_2x_style_2(self):
  31. self.validate("raise E, V")
  32. def test_2x_style_3(self):
  33. self.validate("raise E, V, T")
  34. def test_2x_style_invalid_1(self):
  35. self.invalid_syntax("raise E, V, T, Z")
  36. def test_3x_style(self):
  37. self.validate("raise E1 from E2")
  38. def test_3x_style_invalid_1(self):
  39. self.invalid_syntax("raise E, V from E1")
  40. def test_3x_style_invalid_2(self):
  41. self.invalid_syntax("raise E from E1, E2")
  42. def test_3x_style_invalid_3(self):
  43. self.invalid_syntax("raise from E1, E2")
  44. def test_3x_style_invalid_4(self):
  45. self.invalid_syntax("raise E from")
  46. # Adapated from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef
  47. class TestFunctionAnnotations(GrammarTest):
  48. def test_1(self):
  49. self.validate("""def f(x) -> list: pass""")
  50. def test_2(self):
  51. self.validate("""def f(x:int): pass""")
  52. def test_3(self):
  53. self.validate("""def f(*x:str): pass""")
  54. def test_4(self):
  55. self.validate("""def f(**x:float): pass""")
  56. def test_5(self):
  57. self.validate("""def f(x, y:1+2): pass""")
  58. def test_6(self):
  59. self.validate("""def f(a, (b:1, c:2, d)): pass""")
  60. def test_7(self):
  61. self.validate("""def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass""")
  62. def test_8(self):
  63. s = """def f(a, (b:1, c:2, d), e:3=4, f=5,
  64. *g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass"""
  65. self.validate(s)
  66. class TestExcept(GrammarTest):
  67. def test_new(self):
  68. s = """
  69. try:
  70. x
  71. except E as N:
  72. y"""
  73. self.validate(s)
  74. def test_old(self):
  75. s = """
  76. try:
  77. x
  78. except E, N:
  79. y"""
  80. self.validate(s)
  81. # Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testAtoms
  82. class TestSetLiteral(GrammarTest):
  83. def test_1(self):
  84. self.validate("""x = {'one'}""")
  85. def test_2(self):
  86. self.validate("""x = {'one', 1,}""")
  87. def test_3(self):
  88. self.validate("""x = {'one', 'two', 'three'}""")
  89. def test_4(self):
  90. self.validate("""x = {2, 3, 4,}""")
  91. class TestNumericLiterals(GrammarTest):
  92. def test_new_octal_notation(self):
  93. self.validate("""0o7777777777777""")
  94. self.invalid_syntax("""0o7324528887""")
  95. def test_new_binary_notation(self):
  96. self.validate("""0b101010""")
  97. self.invalid_syntax("""0b0101021""")
  98. class TestClassDef(GrammarTest):
  99. def test_new_syntax(self):
  100. self.validate("class B(t=7): pass")
  101. self.validate("class B(t, *args): pass")
  102. self.validate("class B(t, **kwargs): pass")
  103. self.validate("class B(t, *args, **kwargs): pass")
  104. self.validate("class B(t, y=9, *args, **kwargs): pass")
  105. class TestParserIdempotency(support.TestCase):
  106. """A cut-down version of pytree_idempotency.py."""
  107. def test_all_project_files(self):
  108. for filepath in support.all_project_files():
  109. print "Parsing %s..." % filepath
  110. tree = driver.parse_file(filepath, debug=True)
  111. if diff(filepath, tree):
  112. self.fail("Idempotency failed: %s" % filepath)
  113. class TestLiterals(GrammarTest):
  114. def test_multiline_bytes_literals(self):
  115. s = """
  116. md5test(b"\xaa" * 80,
  117. (b"Test Using Larger Than Block-Size Key "
  118. b"and Larger Than One Block-Size Data"),
  119. "6f630fad67cda0ee1fb1f562db3aa53e")
  120. """
  121. self.validate(s)
  122. def test_multiline_bytes_tripquote_literals(self):
  123. s = '''
  124. b"""
  125. <?xml version="1.0" encoding="UTF-8"?>
  126. <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN">
  127. """
  128. '''
  129. self.validate(s)
  130. def test_multiline_str_literals(self):
  131. s = """
  132. md5test("\xaa" * 80,
  133. ("Test Using Larger Than Block-Size Key "
  134. "and Larger Than One Block-Size Data"),
  135. "6f630fad67cda0ee1fb1f562db3aa53e")
  136. """
  137. self.validate(s)
  138. def diff(fn, tree):
  139. f = open("@", "w")
  140. try:
  141. f.write(str(tree))
  142. finally:
  143. f.close()
  144. try:
  145. return os.system("diff -u %s @" % fn)
  146. finally:
  147. os.remove("@")
  148. if __name__ == "__main__":
  149. import __main__
  150. support.run_all_tests(__main__)