]> granicus.if.org Git - python/commitdiff
#8620: Cmd no longer truncates last character if stdin ends without newline
authorR. David Murray <rdmurray@bitdance.com>
Sun, 1 Aug 2010 03:31:09 +0000 (03:31 +0000)
committerR. David Murray <rdmurray@bitdance.com>
Sun, 1 Aug 2010 03:31:09 +0000 (03:31 +0000)
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
Lib/test/test_cmd.py
Misc/ACKS
Misc/NEWS

index c791d6b256b44d527b515851b4c2f5848fe7af33..85282f89a6b339d4d1b6bc3a1bb24fb2179a63b7 100644 (file)
@@ -133,7 +133,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)
index b3ad5d074bf5c8f5d621260156aea275231b8d4c..75aa6bbd1a1bbdf416cb7bc1a49faff2c6c9f259 100644 (file)
@@ -8,7 +8,8 @@ Original by Michael Schneider
 import cmd
 import sys
 import re
-from io import StringIO
+import unittest
+import io
 from test import support
 
 class samplecmdclass(cmd.Cmd):
@@ -168,9 +169,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(args, file=self.stdout)
+
+        def do_EOF(self, args):
+            return True
+
+    def test_file_with_missing_final_nl(self):
+        input = io.StringIO("print test\nprint test2")
+        output = io.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
     support.run_doctest(test_cmd, verbose)
+    support.run_unittest(TestAlternateInput)
 
 def test_coverage(coverdir):
     trace = support.import_module('trace')
index 3c186b48aae25bdf73fa675f3b33c317729ebc17..3d02af71db2cd9b7aa8423cd38ac097db40f483e 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -195,6 +195,7 @@ Vincent Delft
 Arnaud Delobelle
 Erik Demaine
 Roger Dev
+Catherine Devlin
 Raghuram Devarakonda
 Caleb Deveraux
 Toby Dickenson
index fffed33fbed9d2b07a9a1f6247156ebb4c2e6933..fd47e9608b176b2f0e233e673b711bb658c115db 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -15,6 +15,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 #5146: Handle UID THREAD command correctly in imaplib.
 
 - Issue #5147: Fix the header generated for cookie files written by