mirror of
https://github.com/python/cpython
synced 2024-10-14 09:01:41 +00:00
17830: preserve line endings of original file when updating keywords.
This fixes the test failures on Windows from the new tests, and includes test fixes as well as the module fix.
This commit is contained in:
parent
5238092592
commit
f0f7ceae3c
|
@ -60,6 +60,12 @@ def main():
|
|||
if len(args) > 1: optfile = args[1]
|
||||
else: optfile = "Lib/keyword.py"
|
||||
|
||||
# load the output skeleton from the target, taking care to preserve its
|
||||
# newline convention.
|
||||
with open(optfile, newline='') as fp:
|
||||
format = fp.readlines()
|
||||
nl = format[0][len(format[0].strip()):] if format else '\n'
|
||||
|
||||
# scan the source file for keywords
|
||||
with open(iptfile) as fp:
|
||||
strprog = re.compile('"([^"]+)"')
|
||||
|
@ -68,25 +74,21 @@ def main():
|
|||
if '{1, "' in line:
|
||||
match = strprog.search(line)
|
||||
if match:
|
||||
lines.append(" '" + match.group(1) + "',\n")
|
||||
lines.append(" '" + match.group(1) + "'," + nl)
|
||||
lines.sort()
|
||||
|
||||
# load the output skeleton from the target
|
||||
with open(optfile) as fp:
|
||||
format = fp.readlines()
|
||||
|
||||
# insert the lines of keywords
|
||||
# insert the lines of keywords into the skeleton
|
||||
try:
|
||||
start = format.index("#--start keywords--\n") + 1
|
||||
end = format.index("#--end keywords--\n")
|
||||
start = format.index("#--start keywords--" + nl) + 1
|
||||
end = format.index("#--end keywords--" + nl)
|
||||
format[start:end] = lines
|
||||
except ValueError:
|
||||
sys.stderr.write("target does not contain format markers\n")
|
||||
sys.exit(1)
|
||||
|
||||
# write the output file
|
||||
with open(optfile, 'w') as fp:
|
||||
fp.write(''.join(format))
|
||||
with open(optfile, 'w', newline='') as fp:
|
||||
fp.writelines(format)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
import textwrap
|
||||
|
||||
KEYWORD_FILE = support.findfile('keyword.py')
|
||||
GRAMMAR_FILE = os.path.join('..', '..', 'Python', 'graminit.c')
|
||||
GRAMMAR_FILE = os.path.join(os.path.split(__file__)[0],
|
||||
'..', '..', 'Python', 'graminit.c')
|
||||
TEST_PY_FILE = 'keyword_test.py'
|
||||
GRAMMAR_TEST_FILE = 'graminit_test.c'
|
||||
PY_FILE_WITHOUT_KEYWORDS = 'minimal_keyword.py'
|
||||
|
@ -30,7 +31,7 @@ def test_none_value_is_not_a_keyword(self):
|
|||
# preserved for backward compatibility.
|
||||
def test_changing_the_kwlist_does_not_affect_iskeyword(self):
|
||||
oldlist = keyword.kwlist
|
||||
self.addCleanup(lambda: setattr(keyword, 'kwlist', oldlist))
|
||||
self.addCleanup(setattr, keyword, 'kwlist', oldlist)
|
||||
keyword.kwlist = ['its', 'all', 'eggs', 'beans', 'and', 'a', 'slice']
|
||||
self.assertFalse(keyword.iskeyword('eggs'))
|
||||
|
||||
|
@ -38,11 +39,12 @@ def test_changing_the_kwlist_does_not_affect_iskeyword(self):
|
|||
class TestKeywordGeneration(unittest.TestCase):
|
||||
|
||||
def _copy_file_without_generated_keywords(self, source_file, dest_file):
|
||||
with open(source_file) as fp:
|
||||
with open(source_file, 'rb') as fp:
|
||||
lines = fp.readlines()
|
||||
with open(dest_file, 'w') as fp:
|
||||
fp.writelines(lines[:lines.index("#--start keywords--\n") + 1])
|
||||
fp.writelines(lines[lines.index("#--end keywords--\n"):])
|
||||
nl = lines[0][len(lines[0].strip()):]
|
||||
with open(dest_file, 'wb') as fp:
|
||||
fp.writelines(lines[:lines.index(b"#--start keywords--" + nl) + 1])
|
||||
fp.writelines(lines[lines.index(b"#--end keywords--" + nl):])
|
||||
|
||||
def _generate_keywords(self, grammar_file, target_keyword_py_file):
|
||||
proc = subprocess.Popen([sys.executable,
|
||||
|
@ -56,15 +58,15 @@ def _generate_keywords(self, grammar_file, target_keyword_py_file):
|
|||
'test only works from source build directory')
|
||||
def test_real_grammar_and_keyword_file(self):
|
||||
self._copy_file_without_generated_keywords(KEYWORD_FILE, TEST_PY_FILE)
|
||||
self.addCleanup(lambda: support.unlink(TEST_PY_FILE))
|
||||
self.addCleanup(support.unlink, TEST_PY_FILE)
|
||||
self.assertFalse(filecmp.cmp(KEYWORD_FILE, TEST_PY_FILE))
|
||||
self.assertEqual(0, self._generate_keywords(GRAMMAR_FILE,
|
||||
TEST_PY_FILE)[0])
|
||||
self.assertEqual((0, b''), self._generate_keywords(GRAMMAR_FILE,
|
||||
TEST_PY_FILE))
|
||||
self.assertTrue(filecmp.cmp(KEYWORD_FILE, TEST_PY_FILE))
|
||||
|
||||
def test_grammar(self):
|
||||
self._copy_file_without_generated_keywords(KEYWORD_FILE, TEST_PY_FILE)
|
||||
self.addCleanup(lambda: support.unlink(TEST_PY_FILE))
|
||||
self.addCleanup(support.unlink, TEST_PY_FILE)
|
||||
with open(GRAMMAR_TEST_FILE, 'w') as fp:
|
||||
# Some of these are probably implementation accidents.
|
||||
fp.writelines(textwrap.dedent("""\
|
||||
|
@ -86,40 +88,40 @@ def test_grammar(self):
|
|||
{1, 'no good'}
|
||||
{283, 0},
|
||||
{1, "too many spaces"}"""))
|
||||
self.addCleanup(lambda: support.unlink(GRAMMAR_TEST_FILE))
|
||||
self.addCleanup(support.unlink, GRAMMAR_TEST_FILE)
|
||||
self._generate_keywords(GRAMMAR_TEST_FILE, TEST_PY_FILE)
|
||||
expected = [
|
||||
" 'This one is tab indented',\n",
|
||||
" 'also legal',\n",
|
||||
" 'continue',\n",
|
||||
" 'crazy but legal',\n",
|
||||
" 'jello',\n",
|
||||
" 'lemon',\n",
|
||||
" 'tomato',\n",
|
||||
" 'turnip',\n",
|
||||
" 'wigii',\n",
|
||||
" 'This one is tab indented',",
|
||||
" 'also legal',",
|
||||
" 'continue',",
|
||||
" 'crazy but legal',",
|
||||
" 'jello',",
|
||||
" 'lemon',",
|
||||
" 'tomato',",
|
||||
" 'turnip',",
|
||||
" 'wigii',",
|
||||
]
|
||||
with open(TEST_PY_FILE) as fp:
|
||||
lines = fp.readlines()
|
||||
start = lines.index("#--start keywords--\n") + 1
|
||||
end = lines.index("#--end keywords--\n")
|
||||
lines = fp.read().splitlines()
|
||||
start = lines.index("#--start keywords--") + 1
|
||||
end = lines.index("#--end keywords--")
|
||||
actual = lines[start:end]
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
def test_empty_grammar_results_in_no_keywords(self):
|
||||
self._copy_file_without_generated_keywords(KEYWORD_FILE,
|
||||
PY_FILE_WITHOUT_KEYWORDS)
|
||||
self.addCleanup(lambda: support.unlink(PY_FILE_WITHOUT_KEYWORDS))
|
||||
self.addCleanup(support.unlink, PY_FILE_WITHOUT_KEYWORDS)
|
||||
shutil.copyfile(KEYWORD_FILE, TEST_PY_FILE)
|
||||
self.addCleanup(lambda: support.unlink(TEST_PY_FILE))
|
||||
self.assertEqual(0, self._generate_keywords(os.devnull,
|
||||
TEST_PY_FILE)[0])
|
||||
self.addCleanup(support.unlink, TEST_PY_FILE)
|
||||
self.assertEqual((0, b''), self._generate_keywords(os.devnull,
|
||||
TEST_PY_FILE))
|
||||
self.assertTrue(filecmp.cmp(TEST_PY_FILE, PY_FILE_WITHOUT_KEYWORDS))
|
||||
|
||||
def test_keywords_py_without_markers_produces_error(self):
|
||||
rc, stderr = self._generate_keywords(os.devnull, os.devnull)
|
||||
self.assertNotEqual(rc, 0)
|
||||
self.assertEqual(stderr, b'target does not contain format markers\n')
|
||||
self.assertRegex(stderr, b'does not contain format markers')
|
||||
|
||||
def test_missing_grammar_file_produces_error(self):
|
||||
rc, stderr = self._generate_keywords(NONEXISTENT_FILE, KEYWORD_FILE)
|
||||
|
|
|
@ -49,6 +49,9 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #17830: When keyword.py is used to update a keyword file, it now
|
||||
preserves the line endings of the original file.
|
||||
|
||||
- Issue #17272: Making the urllib.request's Request.full_url a descriptor.
|
||||
Fixes bugs with assignment to full_url. Patch by Demian Brecht.
|
||||
|
||||
|
|
Loading…
Reference in a new issue