1import keyword 2import unittest 3from test import support 4import filecmp 5import os 6import sys 7import subprocess 8import shutil 9import textwrap 10 11KEYWORD_FILE = support.findfile('keyword.py') 12GRAMMAR_FILE = os.path.join(os.path.split(__file__)[0], 13 '..', '..', 'Python', 'graminit.c') 14TEST_PY_FILE = 'keyword_test.py' 15GRAMMAR_TEST_FILE = 'graminit_test.c' 16PY_FILE_WITHOUT_KEYWORDS = 'minimal_keyword.py' 17NONEXISTENT_FILE = 'not_here.txt' 18 19 20class Test_iskeyword(unittest.TestCase): 21 def test_true_is_a_keyword(self): 22 self.assertTrue(keyword.iskeyword('True')) 23 24 def test_uppercase_true_is_not_a_keyword(self): 25 self.assertFalse(keyword.iskeyword('TRUE')) 26 27 def test_none_value_is_not_a_keyword(self): 28 self.assertFalse(keyword.iskeyword(None)) 29 30 # This is probably an accident of the current implementation, but should be 31 # preserved for backward compatibility. 32 def test_changing_the_kwlist_does_not_affect_iskeyword(self): 33 oldlist = keyword.kwlist 34 self.addCleanup(setattr, keyword, 'kwlist', oldlist) 35 keyword.kwlist = ['its', 'all', 'eggs', 'beans', 'and', 'a', 'slice'] 36 self.assertFalse(keyword.iskeyword('eggs')) 37 38 39class TestKeywordGeneration(unittest.TestCase): 40 41 def _copy_file_without_generated_keywords(self, source_file, dest_file): 42 with open(source_file, 'rb') as fp: 43 lines = fp.readlines() 44 nl = lines[0][len(lines[0].strip()):] 45 with open(dest_file, 'wb') as fp: 46 fp.writelines(lines[:lines.index(b"#--start keywords--" + nl) + 1]) 47 fp.writelines(lines[lines.index(b"#--end keywords--" + nl):]) 48 49 def _generate_keywords(self, grammar_file, target_keyword_py_file): 50 proc = subprocess.Popen([sys.executable, 51 KEYWORD_FILE, 52 grammar_file, 53 target_keyword_py_file], stderr=subprocess.PIPE) 54 stderr = proc.communicate()[1] 55 return proc.returncode, stderr 56 57 @unittest.skipIf(not os.path.exists(GRAMMAR_FILE), 58 'test only works from source build directory') 59 def test_real_grammar_and_keyword_file(self): 60 self._copy_file_without_generated_keywords(KEYWORD_FILE, TEST_PY_FILE) 61 self.addCleanup(support.unlink, TEST_PY_FILE) 62 self.assertFalse(filecmp.cmp(KEYWORD_FILE, TEST_PY_FILE)) 63 self.assertEqual((0, b''), self._generate_keywords(GRAMMAR_FILE, 64 TEST_PY_FILE)) 65 self.assertTrue(filecmp.cmp(KEYWORD_FILE, TEST_PY_FILE)) 66 67 def test_grammar(self): 68 self._copy_file_without_generated_keywords(KEYWORD_FILE, TEST_PY_FILE) 69 self.addCleanup(support.unlink, TEST_PY_FILE) 70 with open(GRAMMAR_TEST_FILE, 'w') as fp: 71 # Some of these are probably implementation accidents. 72 fp.writelines(textwrap.dedent("""\ 73 {2, 1}, 74 {11, "encoding_decl", 0, 2, states_79, 75 "\000\000\040\000\000\000\000\000\000\000\000\000" 76 "\000\000\000\000\000\000\000\000\000"}, 77 {1, "jello"}, 78 {326, 0}, 79 {1, "turnip"}, 80 \t{1, "This one is tab indented" 81 {278, 0}, 82 {1, "crazy but legal" 83 "also legal" {1, " 84 {1, "continue"}, 85 {1, "lemon"}, 86 {1, "tomato"}, 87 {1, "wigii"}, 88 {1, 'no good'} 89 {283, 0}, 90 {1, "too many spaces"}""")) 91 self.addCleanup(support.unlink, GRAMMAR_TEST_FILE) 92 self._generate_keywords(GRAMMAR_TEST_FILE, TEST_PY_FILE) 93 expected = [ 94 " 'This one is tab indented',", 95 " 'also legal',", 96 " 'continue',", 97 " 'crazy but legal',", 98 " 'jello',", 99 " 'lemon',", 100 " 'tomato',", 101 " 'turnip',", 102 " 'wigii',", 103 ] 104 with open(TEST_PY_FILE) as fp: 105 lines = fp.read().splitlines() 106 start = lines.index("#--start keywords--") + 1 107 end = lines.index("#--end keywords--") 108 actual = lines[start:end] 109 self.assertEqual(actual, expected) 110 111 def test_empty_grammar_results_in_no_keywords(self): 112 self._copy_file_without_generated_keywords(KEYWORD_FILE, 113 PY_FILE_WITHOUT_KEYWORDS) 114 self.addCleanup(support.unlink, PY_FILE_WITHOUT_KEYWORDS) 115 shutil.copyfile(KEYWORD_FILE, TEST_PY_FILE) 116 self.addCleanup(support.unlink, TEST_PY_FILE) 117 self.assertEqual((0, b''), self._generate_keywords(os.devnull, 118 TEST_PY_FILE)) 119 self.assertTrue(filecmp.cmp(TEST_PY_FILE, PY_FILE_WITHOUT_KEYWORDS)) 120 121 def test_keywords_py_without_markers_produces_error(self): 122 rc, stderr = self._generate_keywords(os.devnull, os.devnull) 123 self.assertNotEqual(rc, 0) 124 self.assertRegex(stderr, b'does not contain format markers') 125 126 def test_missing_grammar_file_produces_error(self): 127 rc, stderr = self._generate_keywords(NONEXISTENT_FILE, KEYWORD_FILE) 128 self.assertNotEqual(rc, 0) 129 self.assertRegex(stderr, b'(?ms)' + NONEXISTENT_FILE.encode()) 130 131 def test_missing_keywords_py_file_produces_error(self): 132 rc, stderr = self._generate_keywords(os.devnull, NONEXISTENT_FILE) 133 self.assertNotEqual(rc, 0) 134 self.assertRegex(stderr, b'(?ms)' + NONEXISTENT_FILE.encode()) 135 136 137if __name__ == "__main__": 138 unittest.main() 139