Index: Python/ast.c =================================================================== --- Python/ast.c (revision 70260) +++ Python/ast.c (working copy) @@ -3241,9 +3241,55 @@ #ifdef Py_USING_UNICODE static PyObject * +remove_unicode_escapes(const char *s, size_t *len) +{ + PyObject *u; + char *buf; + char *p; + const char *q; + const char *end; + + /* Allocate a buffer big enough to hold the new string. The size is six + * times bigger, since \u is translated into \u005c\u0075. */ + u = PyString_FromStringAndSize(NULL, *len * 6); + if (!u) + return NULL; + p = buf = PyString_AS_STRING(u); + + end = s + *len; + while (s < end) { + *p++ = *s; + if (*s++ != '\\') + continue; + + /* Check for a unicode escape sequence: \uXXXX or \UXXXXXXXX. + * If one is found, replace the \ and u or U with the + * equivalent unicode escape characters. */ + switch (*s) { + case 'u': + q = "\\u0075"; + goto replace; + case 'U': + q = "\\u0055"; + goto replace; + replace: + strcpy(p, "u005c"); /* \ */ + p += 5; + strcpy(p, q); + p += 6; + s += 1; + } + } + + *len = p - buf; + return u; +} + +static PyObject * decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, const char *encoding) { - PyObject *v, *u; + PyObject *u; + PyObject *v = NULL; char *buf; char *p; const char *end; @@ -3297,10 +3343,20 @@ len = p - buf; s = buf; } - if (rawmode) + if (rawmode) { + PyObject *x = NULL; + if (c->c_future_unicode || Py_UnicodeFlag) { + x = remove_unicode_escapes(s, &len); + if (x == NULL) + goto exit; + s = PyString_AsString(x); + } v = PyUnicode_DecodeRawUnicodeEscape(s, len, NULL); + Py_XDECREF(x); + } else v = PyUnicode_DecodeUnicodeEscape(s, len, NULL); + exit: Py_XDECREF(u); return v; } Index: Lib/test/test_future4.py =================================================================== --- Lib/test/test_future4.py (revision 70260) +++ Lib/test/test_future4.py (working copy) @@ -40,6 +40,9 @@ self.assertType(u'' '', unicode) self.assertType(u'' u'', unicode) + self.assertEqual(r'\u.bug', '\\u.bug') + self.assertEqual(ur'\u.bug', '\\u.bug') + def test_main(): test_support.run_unittest(TestFuture)