]> granicus.if.org Git - python/commitdiff
Merged revisions 88481 via svnmerge from
authorVictor Stinner <victor.stinner@haypocalc.com>
Wed, 23 Feb 2011 12:14:22 +0000 (12:14 +0000)
committerVictor Stinner <victor.stinner@haypocalc.com>
Wed, 23 Feb 2011 12:14:22 +0000 (12:14 +0000)
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r88481 | victor.stinner | 2011-02-21 22:13:44 +0100 (lun., 21 févr. 2011) | 4 lines

  Fix PyUnicode_FromFormatV("%c") for non-BMP char

  Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on
  narrow build.
........

Lib/test/test_unicode.py
Misc/NEWS
Objects/unicodeobject.c

index e2d67cd949cec5376803f9c4a07c7b4e21ceb1c3..9ad9eed6ac97d6350f584dbdc03042466cc5bce7 100644 (file)
@@ -1427,7 +1427,7 @@ class UnicodeTest(string_tests.CommonTest,
     # Test PyUnicode_FromFormat()
     def test_from_format(self):
         support.import_module('ctypes')
-        from ctypes import pythonapi, py_object
+        from ctypes import pythonapi, py_object, c_int
         if sys.maxunicode == 65535:
             name = "PyUnicodeUCS2_FromFormat"
         else:
@@ -1452,6 +1452,9 @@ class UnicodeTest(string_tests.CommonTest,
             'string, got a non-ASCII byte: 0xe9$',
             PyUnicode_FromFormat, b'unicode\xe9=%s', 'ascii')
 
+        self.assertEqual(PyUnicode_FromFormat(b'%c', c_int(0xabcd)), '\uabcd')
+        self.assertEqual(PyUnicode_FromFormat(b'%c', c_int(0x10ffff)), '\U0010ffff')
+
         # other tests
         text = PyUnicode_FromFormat(b'%%A:%A', 'abc\xe9\uabcd\U0010ffff')
         self.assertEqual(text, r"%A:'abc\xe9\uabcd\U0010ffff'")
index b4cff7ff4e9b31ddcf3095e9d41967f58d40bcf8..a7f9ba5a567d84b5d5dd65c4253068436a7194ba 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,9 @@ Core and Builtins
 - Issue #11272: On Windows, input() strips '\r' (and not only '\n'), and
   sys.stdin uses universal newline (replace '\r\n' by '\n').
 
+- Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on
+  narrow build.
+
 - Check for NULL result in PyType_FromSpec.
 
 Library
index 456719685d48db4c03a74bb25fc4011b50b9ae47..423a53383ae169f40a4c4ff1f6fadfc40ea87768 100644 (file)
@@ -813,8 +813,19 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
 
             switch (*f) {
             case 'c':
+            {
+#ifndef Py_UNICODE_WIDE
+                int ordinal = va_arg(count, int);
+                if (ordinal > 0xffff)
+                    n += 2;
+                else
+                    n++;
+#else
                 (void)va_arg(count, int);
-                /* fall through... */
+                n++;
+#endif
+                break;
+            }
             case '%':
                 n++;
                 break;
@@ -992,8 +1003,18 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
 
             switch (*f) {
             case 'c':
-                *s++ = va_arg(vargs, int);
+            {
+                int ordinal = va_arg(vargs, int);
+#ifndef Py_UNICODE_WIDE
+                if (ordinal > 0xffff) {
+                    ordinal -= 0x10000;
+                    *s++ = 0xD800 | (ordinal >> 10);
+                    *s++ = 0xDC00 | (ordinal & 0x3FF);
+                } else
+#endif
+                *s++ = ordinal;
                 break;
+            }
             case 'd':
                 makefmt(fmt, longflag, longlongflag, size_tflag, zeropad,
                         width, precision, 'd');