]> granicus.if.org Git - python/commitdiff
Issue #20731: Properly position in source code files even if they
authorMartin v. Löwis <martin@v.loewis.de>
Fri, 28 Feb 2014 14:27:29 +0000 (15:27 +0100)
committerMartin v. Löwis <martin@v.loewis.de>
Fri, 28 Feb 2014 14:27:29 +0000 (15:27 +0100)
are opened in text mode. Patch by Serhiy Storchaka.

.hgeol
Lib/test/coding20731.py [new file with mode: 0644]
Lib/test/test_coding.py
Misc/NEWS
Parser/tokenizer.c

diff --git a/.hgeol b/.hgeol
index 4e036906607ecf62bc68b6902fe2e85f3fc0d040..73a4770f320e04639b01e36bcbc2b55c82c2d8a9 100644 (file)
--- a/.hgeol
+++ b/.hgeol
@@ -37,6 +37,8 @@ Lib/test/xmltestdata/* = BIN
 
 Lib/venv/scripts/nt/* = BIN
 
+Lib/test/coding20731.py = BIN
+
 # All other files (which presumably are human-editable) are "native".
 # This must be the last rule!
 
diff --git a/Lib/test/coding20731.py b/Lib/test/coding20731.py
new file mode 100644 (file)
index 0000000..ca4962e
--- /dev/null
@@ -0,0 +1,4 @@
+#coding:latin1
+
+
+
index 989c7a85d2ff8428a1562e0e579f8e7eaf494da2..760676750c4c9797316ddf5c625a8fc4e7d1b97a 100644 (file)
@@ -1,6 +1,6 @@
 import unittest
 from test.support import TESTFN, unlink, unload
-import importlib, os, sys
+import importlib, os, sys, subprocess
 
 class CodingTest(unittest.TestCase):
     def test_bad_coding(self):
@@ -58,6 +58,13 @@ class CodingTest(unittest.TestCase):
         self.assertTrue(c.exception.args[0].startswith(expected),
                         msg=c.exception.args[0])
 
+    def test_20731(self):
+        sub = subprocess.Popen([sys.executable, 
+                        os.path.join(os.path.dirname(__file__),
+                                     'coding20731.py')],
+                        stderr=subprocess.PIPE)
+        err = sub.communicate()[1]
+        self.assertEquals(err, b'')
 
 if __name__ == "__main__":
     unittest.main()
index 4c99dd3394542104788447d44cdf49307b1f5ff3..3b707839e2ba6f985ab16d684fa4fccf9bd720fd 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.3.5 release candidate 1?
 Core and Builtins
 -----------------
 
+- Issue #20731: Properly position in source code files even if they
+  are opened in text mode. Patch by Serhiy Storchaka.
+
 - Issue #19619: str.encode, bytes.decode and bytearray.decode now use an
   internal API to throw LookupError for known non-text encodings, rather
   than attempting the encoding or decoding operation and then throwing a
index 8530723c266dcd382097380ad322f8383c75d49f..660c0f042bc951e7b50fe33a839d262870eec747 100644 (file)
@@ -498,9 +498,13 @@ fp_setreadl(struct tok_state *tok, const char* enc)
 
     fd = fileno(tok->fp);
     /* Due to buffering the file offset for fd can be different from the file
-     * position of tok->fp. */
+     * position of tok->fp.  If tok->fp was opened in text mode on Windows,
+     * its file position counts CRLF as one char and can't be directly mapped
+     * to the file offset for fd.  Instead we step back one byte and read to
+     * the end of line.*/
     pos = ftell(tok->fp);
-    if (pos == -1 || lseek(fd, (off_t)pos, SEEK_SET) == (off_t)-1) {
+    if (pos == -1 ||
+        lseek(fd, (off_t)(pos > 0 ? pos - 1 : pos), SEEK_SET) == (off_t)-1) {
         PyErr_SetFromErrnoWithFilename(PyExc_OSError, NULL);
         goto cleanup;
     }
@@ -513,6 +517,12 @@ fp_setreadl(struct tok_state *tok, const char* enc)
     Py_XDECREF(tok->decoding_readline);
     readline = _PyObject_GetAttrId(stream, &PyId_readline);
     tok->decoding_readline = readline;
+    if (pos > 0) {
+        if (PyObject_CallObject(readline, NULL) == NULL) {
+            readline = NULL;
+            goto cleanup;
+        }
+    }
 
   cleanup:
     Py_XDECREF(stream);