Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r67936:b1648711d9dc
Date: 2013-11-11 00:14 +0100
http://bitbucket.org/pypy/pypy/changeset/b1648711d9dc/

Log:    Issue1491. Test and fix: when CSI escape sequences are given in the
        prompts for raw_input(), even if they are not within \x01..\x02,
        then detect and ignore them for computing the printed length of the
        string.

diff --git a/lib_pypy/pyrepl/reader.py b/lib_pypy/pyrepl/reader.py
--- a/lib_pypy/pyrepl/reader.py
+++ b/lib_pypy/pyrepl/reader.py
@@ -19,11 +19,13 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-import types
+import types, re
 from pyrepl import unicodedata_
 from pyrepl import commands
 from pyrepl import input
 
+_r_csi_seq = re.compile(r"\033\[[ -@]*[A-~]")
+
 def _make_unctrl_map():
     uc_map = {}
     for c in map(unichr, range(256)):
@@ -309,6 +311,10 @@
         excluded from the length calculation.  So also a copy of the prompt
         is returned with these control characters removed.  """
 
+        # The logic below also ignores the length of common escape
+        # sequences if they were not explicitly within \x01...\x02.
+        # They are CSI (or ANSI) sequences  ( ESC [ ... LETTER )
+
         out_prompt = ''
         l = len(prompt)
         pos = 0
@@ -321,9 +327,13 @@
                 break
             # Found start and end brackets, subtract from string length
             l = l - (e-s+1)
-            out_prompt += prompt[pos:s] + prompt[s+1:e]
+            keep = prompt[pos:s]
+            l -= sum(map(len, _r_csi_seq.findall(keep)))
+            out_prompt += keep + prompt[s+1:e]
             pos = e+1
-        out_prompt += prompt[pos:]
+        keep = prompt[pos:]
+        l -= sum(map(len, _r_csi_seq.findall(keep)))
+        out_prompt += keep
         return out_prompt, l
 
     def bow(self, p=None):
diff --git a/pypy/module/test_lib_pypy/pyrepl/test_reader.py 
b/pypy/module/test_lib_pypy/pyrepl/test_reader.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/pyrepl/test_reader.py
@@ -0,0 +1,9 @@
+
+def test_process_prompt():
+    from pyrepl.reader import Reader
+    r = Reader(None)
+    assert r.process_prompt("hi!") == ("hi!", 3)
+    assert r.process_prompt("h\x01i\x02!") == ("hi!", 2)
+    assert r.process_prompt("hi\033[11m!") == ("hi\033[11m!", 3)
+    assert r.process_prompt("h\x01i\033[11m!\x02") == ("hi\033[11m!", 1)
+    assert r.process_prompt("h\033[11m\x01i\x02!") == ("h\033[11mi!", 2)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to