diff --git a/Lib/_pycodecs.py b/Lib/_pycodecs.py index 98dec3c61..2c043f0ec 100644 --- a/Lib/_pycodecs.py +++ b/Lib/_pycodecs.py @@ -1102,20 +1102,6 @@ def unicodeescape_string(s, size, quotes): pos += 1 continue # endif - # /* Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes */ - elif ord(ch) >= 0xD800 and ord(ch) < 0xDC00: - pos += 1 - ch2 = s[pos] - - if ord(ch2) >= 0xDC00 and ord(ch2) <= 0xDFFF: - ucs = (((ord(ch) & 0x03FF) << 10) | (ord(ch2) & 0x03FF)) + 0x00010000 - p.append(b"\\U%08x" % ucs) - pos += 1 - continue - - # /* Fall through: isolated surrogates are copied as-is */ - pos -= 1 - # /* Map 16-bit characters to '\uxxxx' */ if ord(ch) >= 256: p.append(b"\\u%04x" % ord(ch)) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 58a7d6f3a..a55057d91 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -2776,9 +2776,6 @@ class UnicodeEscapeTest(ReadTest, unittest.TestCase): ] ) - @unittest.expectedFailure # TODO: RUSTPYTHON; IndexError: index out of range - def test_incremental_surrogatepass(self): - return super().test_incremental_surrogatepass() class RawUnicodeEscapeTest(ReadTest, unittest.TestCase): encoding = "raw-unicode-escape" diff --git a/extra_tests/snippets/builtin_str_encode.py b/extra_tests/snippets/builtin_str_encode.py index fc72e6ad4..7e7cff577 100644 --- a/extra_tests/snippets/builtin_str_encode.py +++ b/extra_tests/snippets/builtin_str_encode.py @@ -32,3 +32,12 @@ assert not b"\x80\x80".islower() assert not b"\x80\x80".isupper() assert b"\x80cat\x80".islower() assert b"\x80CAT\x80".isupper() + +# A lone surrogate gets an escape of its own wherever it sits, and a high one +# followed by a low one stays two escapes rather than being folded into one. +assert "\ud800".encode("unicode_escape") == b"\\ud800" +assert "a\ud800".encode("unicode_escape") == b"a\\ud800" +assert "\ud800b".encode("unicode_escape") == b"\\ud800b" +assert "\ud800\ud800".encode("unicode_escape") == b"\\ud800\\ud800" +assert "\ud800\udc00".encode("unicode_escape") == b"\\ud800\\udc00" +assert "\U00010000".encode("unicode_escape") == b"\\U00010000"