From 58f15b66ffb03bfe2c9fbc111e1cc28f4cd3ddd4 Mon Sep 17 00:00:00 2001 From: "R. David Murray" Date: Sun, 1 Aug 2010 04:04:03 +0000 Subject: [PATCH] Merged revisions 83380 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r83380 | r.david.murray | 2010-07-31 23:31:09 -0400 (Sat, 31 Jul 2010) | 17 lines #8620: Cmd no longer truncates last character if stdin ends without newline Cmd used to blindly chop off the last character of every input line. If the input reached EOF and there was no final new line, it would truncate the last character of the last command. This fix instead strips trailing \r\n from the input lines. While this is a small behavior change, it should not break any working code, since feeding a '\r\n' terminated file to Cmd would previously leave the \r's on the lines, resulting in failed command execution. I wrote the unit test in preparation for a PyOhio TeachMe session run by Catherine Devlin, and we can thank Catherine and the PyOhio session attendees for the fix. I've added Catherine to the Acks file for organizing and leading the TeachMe session, out of which we will hopefully get some new contributors. ........ --- Lib/cmd.py | 2 +- Lib/test/test_cmd.py | 27 +++++++++++++++++++++++++++ Misc/ACKS | 1 + Misc/NEWS | 3 +++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Lib/cmd.py b/Lib/cmd.py index 5847f76360..29ea4608e7 100644 --- a/Lib/cmd.py +++ b/Lib/cmd.py @@ -137,7 +137,7 @@ class Cmd: if not len(line): line = 'EOF' else: - line = line[:-1] # chop \n + line = line.rstrip('\r\n') line = self.precmd(line) stop = self.onecmd(line) stop = self.postcmd(stop, line) diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py index 19ee52e090..c46fec8a5f 100644 --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -8,6 +8,9 @@ Original by Michael Schneider import cmd import sys from test import test_support +import re +import unittest +import StringIO class samplecmdclass(cmd.Cmd): """ @@ -168,9 +171,33 @@ class samplecmdclass(cmd.Cmd): def do_exit(self, arg): return True + +class TestAlternateInput(unittest.TestCase): + + class simplecmd(cmd.Cmd): + + def do_print(self, args): + print >>self.stdout, args + + def do_EOF(self, args): + return True + + def test_file_with_missing_final_nl(self): + input = StringIO.StringIO("print test\nprint test2") + output = StringIO.StringIO() + cmd = self.simplecmd(stdin=input, stdout=output) + cmd.use_rawinput = False + cmd.cmdloop() + self.assertMultiLineEqual(output.getvalue(), + ("(Cmd) test\n" + "(Cmd) test2\n" + "(Cmd) ")) + + def test_main(verbose=None): from test import test_cmd test_support.run_doctest(test_cmd, verbose) + test_support.run_unittest(TestAlternateInput) def test_coverage(coverdir): trace = test_support.import_module('trace') diff --git a/Misc/ACKS b/Misc/ACKS index 2d15ca5479..c75fced81e 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -188,6 +188,7 @@ Vincent Delft Arnaud Delobelle Erik Demaine Roger Dev +Catherine Devlin Raghuram Devarakonda Scott Dial Toby Dickenson diff --git a/Misc/NEWS b/Misc/NEWS index ea60e3b818..a7928c0843 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -18,6 +18,9 @@ Core and Builtins Library ------- +- Issue #8620: when a Cmd is fed input that reaches EOF without a final + newline, it no longer truncates the last character of the last command line. + - Issue #6213: Implement getstate() and setstate() methods of utf-8-sig and utf-16 incremental encoders. -- 2.40.0