]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-116417: Move limited C API unicode.c tests to _testlimitedcapi (#116993)
authorVictor Stinner <vstinner@python.org>
Tue, 19 Mar 2024 12:30:39 +0000 (13:30 +0100)
committerGitHub <noreply@github.com>
Tue, 19 Mar 2024 12:30:39 +0000 (12:30 +0000)
Split unicode.c tests of _testcapi into two parts: limited C API
tests in _testlimitedcapi and non-limited C API tests in _testcapi.

Update test_codecs.

12 files changed:
Lib/test/test_capi/test_codecs.py
Lib/test/test_capi/test_misc.py
Lib/test/test_capi/test_unicode.py
Lib/test/test_codecs.py
Modules/Setup.stdlib.in
Modules/_testcapi/unicode.c
Modules/_testlimitedcapi.c
Modules/_testlimitedcapi/float.c
Modules/_testlimitedcapi/parts.h
Modules/_testlimitedcapi/unicode.c [new file with mode: 0644]
PCbuild/_testlimitedcapi.vcxproj
PCbuild/_testlimitedcapi.vcxproj.filters

index 682c56979c6dfaf83851a27d4cfe17f6494f6789..bd521a509d07ec569e62ae5743340ca739df1afe 100644 (file)
@@ -2,7 +2,7 @@ import unittest
 import sys
 from test.support import import_helper
 
-_testcapi = import_helper.import_module('_testcapi')
+_testlimitedcapi = import_helper.import_module('_testlimitedcapi')
 
 NULL = None
 
@@ -27,7 +27,7 @@ class CAPITest(unittest.TestCase):
 
     def test_fromencodedobject(self):
         """Test PyUnicode_FromEncodedObject()"""
-        fromencodedobject = _testcapi.unicode_fromencodedobject
+        fromencodedobject = _testlimitedcapi.unicode_fromencodedobject
 
         self.assertEqual(fromencodedobject(b'abc', NULL), 'abc')
         self.assertEqual(fromencodedobject(b'abc', 'ascii'), 'abc')
@@ -52,7 +52,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decode(self):
         """Test PyUnicode_Decode()"""
-        decode = _testcapi.unicode_decode
+        decode = _testlimitedcapi.unicode_decode
 
         self.assertEqual(decode(b'[\xe2\x82\xac]', 'utf-8'), '[\u20ac]')
         self.assertEqual(decode(b'[\xa4]', 'iso8859-15'), '[\u20ac]')
@@ -70,7 +70,7 @@ class CAPITest(unittest.TestCase):
 
     def test_asencodedstring(self):
         """Test PyUnicode_AsEncodedString()"""
-        asencodedstring = _testcapi.unicode_asencodedstring
+        asencodedstring = _testlimitedcapi.unicode_asencodedstring
 
         self.assertEqual(asencodedstring('abc', NULL), b'abc')
         self.assertEqual(asencodedstring('abc', 'ascii'), b'abc')
@@ -93,7 +93,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decodeutf8(self):
         """Test PyUnicode_DecodeUTF8()"""
-        decodeutf8 = _testcapi.unicode_decodeutf8
+        decodeutf8 = _testlimitedcapi.unicode_decodeutf8
 
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']:
             b = s.encode('utf-8')
@@ -113,7 +113,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decodeutf8stateful(self):
         """Test PyUnicode_DecodeUTF8Stateful()"""
-        decodeutf8stateful = _testcapi.unicode_decodeutf8stateful
+        decodeutf8stateful = _testlimitedcapi.unicode_decodeutf8stateful
 
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']:
             b = s.encode('utf-8')
@@ -136,7 +136,7 @@ class CAPITest(unittest.TestCase):
 
     def test_asutf8string(self):
         """Test PyUnicode_AsUTF8String()"""
-        asutf8string = _testcapi.unicode_asutf8string
+        asutf8string = _testlimitedcapi.unicode_asutf8string
 
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']:
             self.assertEqual(asutf8string(s), s.encode('utf-8'))
@@ -148,7 +148,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decodeutf16(self):
         """Test PyUnicode_DecodeUTF16()"""
-        decodeutf16 = _testcapi.unicode_decodeutf16
+        decodeutf16 = _testlimitedcapi.unicode_decodeutf16
 
         naturalbyteorder = -1 if sys.byteorder == 'little' else 1
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']:
@@ -192,7 +192,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decodeutf16stateful(self):
         """Test PyUnicode_DecodeUTF16Stateful()"""
-        decodeutf16stateful = _testcapi.unicode_decodeutf16stateful
+        decodeutf16stateful = _testlimitedcapi.unicode_decodeutf16stateful
 
         naturalbyteorder = -1 if sys.byteorder == 'little' else 1
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']:
@@ -238,7 +238,7 @@ class CAPITest(unittest.TestCase):
 
     def test_asutf16string(self):
         """Test PyUnicode_AsUTF16String()"""
-        asutf16string = _testcapi.unicode_asutf16string
+        asutf16string = _testlimitedcapi.unicode_asutf16string
 
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']:
             self.assertEqual(asutf16string(s), s.encode('utf-16'))
@@ -250,7 +250,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decodeutf32(self):
         """Test PyUnicode_DecodeUTF8()"""
-        decodeutf32 = _testcapi.unicode_decodeutf32
+        decodeutf32 = _testlimitedcapi.unicode_decodeutf32
 
         naturalbyteorder = -1 if sys.byteorder == 'little' else 1
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']:
@@ -290,7 +290,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decodeutf32stateful(self):
         """Test PyUnicode_DecodeUTF32Stateful()"""
-        decodeutf32stateful = _testcapi.unicode_decodeutf32stateful
+        decodeutf32stateful = _testlimitedcapi.unicode_decodeutf32stateful
 
         naturalbyteorder = -1 if sys.byteorder == 'little' else 1
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']:
@@ -342,7 +342,7 @@ class CAPITest(unittest.TestCase):
 
     def test_asutf32string(self):
         """Test PyUnicode_AsUTF32String()"""
-        asutf32string = _testcapi.unicode_asutf32string
+        asutf32string = _testlimitedcapi.unicode_asutf32string
 
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']:
             self.assertEqual(asutf32string(s), s.encode('utf-32'))
@@ -354,7 +354,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decodelatin1(self):
         """Test PyUnicode_DecodeLatin1()"""
-        decodelatin1 = _testcapi.unicode_decodelatin1
+        decodelatin1 = _testlimitedcapi.unicode_decodelatin1
 
         self.assertEqual(decodelatin1(b'abc'), 'abc')
         self.assertEqual(decodelatin1(b'abc', 'strict'), 'abc')
@@ -365,7 +365,7 @@ class CAPITest(unittest.TestCase):
 
     def test_aslatin1string(self):
         """Test PyUnicode_AsLatin1String()"""
-        aslatin1string = _testcapi.unicode_aslatin1string
+        aslatin1string = _testlimitedcapi.unicode_aslatin1string
 
         self.assertEqual(aslatin1string('abc'), b'abc')
         self.assertEqual(aslatin1string('\xa1\xa2'), b'\xa1\xa2')
@@ -377,7 +377,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decodeascii(self):
         """Test PyUnicode_DecodeASCII()"""
-        decodeascii = _testcapi.unicode_decodeascii
+        decodeascii = _testlimitedcapi.unicode_decodeascii
 
         self.assertEqual(decodeascii(b'abc'), 'abc')
         self.assertEqual(decodeascii(b'abc', 'strict'), 'abc')
@@ -392,7 +392,7 @@ class CAPITest(unittest.TestCase):
 
     def test_asasciistring(self):
         """Test PyUnicode_AsASCIIString()"""
-        asasciistring = _testcapi.unicode_asasciistring
+        asasciistring = _testlimitedcapi.unicode_asasciistring
 
         self.assertEqual(asasciistring('abc'), b'abc')
 
@@ -403,7 +403,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decodecharmap(self):
         """Test PyUnicode_DecodeCharmap()"""
-        decodecharmap = _testcapi.unicode_decodecharmap
+        decodecharmap = _testlimitedcapi.unicode_decodecharmap
 
         self.assertEqual(decodecharmap(b'\3\0\7', {0: 'a', 3: 'b', 7: 'c'}), 'bac')
         self.assertEqual(decodecharmap(b'\1\0\2', ['a', 'b', 'c']), 'bac')
@@ -426,7 +426,7 @@ class CAPITest(unittest.TestCase):
 
     def test_ascharmapstring(self):
         """Test PyUnicode_AsCharmapString()"""
-        ascharmapstring = _testcapi.unicode_ascharmapstring
+        ascharmapstring = _testlimitedcapi.unicode_ascharmapstring
 
         self.assertEqual(ascharmapstring('abc', {97: 3, 98: 0, 99: 7}), b'\3\0\7')
         self.assertEqual(ascharmapstring('\xa1\xa2\xa3', {0xa1: 3, 0xa2: 0, 0xa3: 7}), b'\3\0\7')
@@ -443,7 +443,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decodeunicodeescape(self):
         """Test PyUnicode_DecodeUnicodeEscape()"""
-        decodeunicodeescape = _testcapi.unicode_decodeunicodeescape
+        decodeunicodeescape = _testlimitedcapi.unicode_decodeunicodeescape
 
         self.assertEqual(decodeunicodeescape(b'abc'), 'abc')
         self.assertEqual(decodeunicodeescape(br'\t\n\r\x0b\x0c\x00\\'), '\t\n\r\v\f\0\\')
@@ -467,7 +467,7 @@ class CAPITest(unittest.TestCase):
 
     def test_asunicodeescapestring(self):
         """Test PyUnicode_AsUnicodeEscapeString()"""
-        asunicodeescapestring = _testcapi.unicode_asunicodeescapestring
+        asunicodeescapestring = _testlimitedcapi.unicode_asunicodeescapestring
 
         self.assertEqual(asunicodeescapestring('abc'), b'abc')
         self.assertEqual(asunicodeescapestring('\t\n\r\v\f\0\\'), br'\t\n\r\x0b\x0c\x00\\')
@@ -481,7 +481,7 @@ class CAPITest(unittest.TestCase):
 
     def test_decoderawunicodeescape(self):
         """Test PyUnicode_DecodeRawUnicodeEscape()"""
-        decoderawunicodeescape = _testcapi.unicode_decoderawunicodeescape
+        decoderawunicodeescape = _testlimitedcapi.unicode_decoderawunicodeescape
 
         self.assertEqual(decoderawunicodeescape(b'abc'), 'abc')
         self.assertEqual(decoderawunicodeescape(b'\t\n\r\v\f\0\\'), '\t\n\r\v\f\0\\')
@@ -503,7 +503,7 @@ class CAPITest(unittest.TestCase):
 
     def test_asrawunicodeescapestring(self):
         """Test PyUnicode_AsRawUnicodeEscapeString()"""
-        asrawunicodeescapestring = _testcapi.unicode_asrawunicodeescapestring
+        asrawunicodeescapestring = _testlimitedcapi.unicode_asrawunicodeescapestring
 
         self.assertEqual(asrawunicodeescapestring('abc'), b'abc')
         self.assertEqual(asrawunicodeescapestring('\t\n\r\v\f\0\\'), b'\t\n\r\v\f\0\\')
index eb0bc13911701a7f1f9dc50d537fccc243cc1b20..d3fcd0b59dfa49037a37b6d2162f68165acf535e 100644 (file)
@@ -2338,7 +2338,7 @@ class Test_testcapi(unittest.TestCase):
     # Suppress warning from PyUnicode_FromUnicode().
     @warnings_helper.ignore_warnings(category=DeprecationWarning)
     def test_widechar(self):
-        _testcapi.test_widechar()
+        _testlimitedcapi.test_widechar()
 
     def test_version_api_data(self):
         self.assertEqual(_testcapi.Py_Version, sys.hexversion)
index 91c425e483f0fff65d8b06c1f8d2857830498468..a64c75c415c3fe585242e67c3bed03260ad70064 100644 (file)
@@ -8,6 +8,10 @@ try:
     from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX
 except ImportError:
     _testcapi = None
+try:
+    import _testlimitedcapi
+except ImportError:
+    _testlimitedcapi = None
 try:
     import _testinternalcapi
 except ImportError:
@@ -84,10 +88,10 @@ class CAPITest(unittest.TestCase):
         # TODO: Test PyUnicode_Fill() with non-modifiable unicode.
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_writechar(self):
         """Test PyUnicode_WriteChar()"""
-        from _testcapi import unicode_writechar as writechar
+        from _testlimitedcapi import unicode_writechar as writechar
 
         strings = [
             # one string for every kind
@@ -115,10 +119,10 @@ class CAPITest(unittest.TestCase):
         # unicode.
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_resize(self):
         """Test PyUnicode_Resize()"""
-        from _testcapi import unicode_resize as resize
+        from _testlimitedcapi import unicode_resize as resize
 
         strings = [
             # all strings have exactly 3 characters
@@ -141,10 +145,10 @@ class CAPITest(unittest.TestCase):
         # and with NULL as the address.
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_append(self):
         """Test PyUnicode_Append()"""
-        from _testcapi import unicode_append as append
+        from _testlimitedcapi import unicode_append as append
 
         strings = [
             'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16',
@@ -169,10 +173,10 @@ class CAPITest(unittest.TestCase):
         # TODO: Check reference counts.
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_appendanddel(self):
         """Test PyUnicode_AppendAndDel()"""
-        from _testcapi import unicode_appendanddel as appendanddel
+        from _testlimitedcapi import unicode_appendanddel as appendanddel
 
         strings = [
             'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16',
@@ -196,10 +200,10 @@ class CAPITest(unittest.TestCase):
         # TODO: Check reference counts.
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_fromstringandsize(self):
         """Test PyUnicode_FromStringAndSize()"""
-        from _testcapi import unicode_fromstringandsize as fromstringandsize
+        from _testlimitedcapi import unicode_fromstringandsize as fromstringandsize
 
         self.assertEqual(fromstringandsize(b'abc'), 'abc')
         self.assertEqual(fromstringandsize(b'abc', 2), 'ab')
@@ -221,10 +225,10 @@ class CAPITest(unittest.TestCase):
         self.assertRaises(SystemError, fromstringandsize, NULL, PY_SSIZE_T_MAX)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_fromstring(self):
         """Test PyUnicode_FromString()"""
-        from _testcapi import unicode_fromstring as fromstring
+        from _testlimitedcapi import unicode_fromstring as fromstring
 
         self.assertEqual(fromstring(b'abc'), 'abc')
         self.assertEqual(fromstring(b'\xc2\xa1\xc2\xa2'), '\xa1\xa2')
@@ -273,10 +277,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES fromkindanddata(4, b'\xff\xff\xff\xff')
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_substring(self):
         """Test PyUnicode_Substring()"""
-        from _testcapi import unicode_substring as substring
+        from _testlimitedcapi import unicode_substring as substring
 
         strings = [
             'ab', 'ab\xa1\xa2',
@@ -297,10 +301,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES substring(NULL, 0, 0)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_getlength(self):
         """Test PyUnicode_GetLength()"""
-        from _testcapi import unicode_getlength as getlength
+        from _testlimitedcapi import unicode_getlength as getlength
 
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600',
                   'a\ud800b\udfffc', '\ud834\udd1e']:
@@ -311,10 +315,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES getlength(NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_readchar(self):
         """Test PyUnicode_ReadChar()"""
-        from _testcapi import unicode_readchar as readchar
+        from _testlimitedcapi import unicode_readchar as readchar
 
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600',
                   'a\ud800b\udfffc', '\ud834\udd1e']:
@@ -330,10 +334,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES readchar(NULL, 0)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_fromobject(self):
         """Test PyUnicode_FromObject()"""
-        from _testcapi import unicode_fromobject as fromobject
+        from _testlimitedcapi import unicode_fromobject as fromobject
 
         for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600',
                   'a\ud800b\udfffc', '\ud834\udd1e']:
@@ -352,7 +356,7 @@ class CAPITest(unittest.TestCase):
         """Test PyUnicode_FromFormat()"""
         # Length modifiers "j" and "t" are not tested here because ctypes does
         # not expose types for intmax_t and ptrdiff_t.
-        # _testcapi.test_string_from_format() has a wider coverage of all
+        # _testlimitedcapi.test_string_from_format() has a wider coverage of all
         # formats.
         import_helper.import_module('ctypes')
         from ctypes import (
@@ -609,40 +613,6 @@ class CAPITest(unittest.TestCase):
         check_format('xyz',
                      b'%V', None, b'xyz')
 
-        # test %T
-        check_format('type: str',
-                     b'type: %T', py_object("abc"))
-        check_format(f'type: st',
-                     b'type: %.2T', py_object("abc"))
-        check_format(f'type:        str',
-                     b'type: %10T', py_object("abc"))
-
-        class LocalType:
-            pass
-        obj = LocalType()
-        fullname = f'{__name__}.{LocalType.__qualname__}'
-        check_format(f'type: {fullname}',
-                     b'type: %T', py_object(obj))
-        fullname_alt = f'{__name__}:{LocalType.__qualname__}'
-        check_format(f'type: {fullname_alt}',
-                     b'type: %T#', py_object(obj))
-
-        # test %N
-        check_format('type: str',
-                     b'type: %N', py_object(str))
-        check_format(f'type: st',
-                     b'type: %.2N', py_object(str))
-        check_format(f'type:        str',
-                     b'type: %10N', py_object(str))
-
-        check_format(f'type: {fullname}',
-                     b'type: %N', py_object(type(obj)))
-        check_format(f'type: {fullname_alt}',
-                     b'type: %N#', py_object(type(obj)))
-        with self.assertRaisesRegex(TypeError, "%N argument must be a type"):
-            check_format('type: str',
-                         b'type: %N', py_object("abc"))
-
         # test %ls
         check_format('abc', b'%ls', c_wchar_p('abc'))
         check_format('\u4eba\u6c11', b'%ls', c_wchar_p('\u4eba\u6c11'))
@@ -741,10 +711,10 @@ class CAPITest(unittest.TestCase):
             PyUnicode_FromFormat, b'%+i', c_int(10))
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_interninplace(self):
         """Test PyUnicode_InternInPlace()"""
-        from _testcapi import unicode_interninplace as interninplace
+        from _testlimitedcapi import unicode_interninplace as interninplace
 
         s = b'abc'.decode()
         r = interninplace(s)
@@ -754,10 +724,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES interninplace(NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_internfromstring(self):
         """Test PyUnicode_InternFromString()"""
-        from _testcapi import unicode_internfromstring as internfromstring
+        from _testlimitedcapi import unicode_internfromstring as internfromstring
 
         self.assertEqual(internfromstring(b'abc'), 'abc')
         self.assertEqual(internfromstring(b'\xf0\x9f\x98\x80'), '\U0001f600')
@@ -768,10 +738,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES internfromstring(NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_fromwidechar(self):
         """Test PyUnicode_FromWideChar()"""
-        from _testcapi import unicode_fromwidechar as fromwidechar
+        from _testlimitedcapi import unicode_fromwidechar as fromwidechar
         from _testcapi import SIZEOF_WCHAR_T
 
         if SIZEOF_WCHAR_T == 2:
@@ -803,11 +773,11 @@ class CAPITest(unittest.TestCase):
         self.assertRaises(SystemError, fromwidechar, NULL, PY_SSIZE_T_MIN)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_aswidechar(self):
         """Test PyUnicode_AsWideChar()"""
-        from _testcapi import unicode_aswidechar
-        from _testcapi import unicode_aswidechar_null
+        from _testlimitedcapi import unicode_aswidechar
+        from _testlimitedcapi import unicode_aswidechar_null
         from _testcapi import SIZEOF_WCHAR_T
 
         wchar, size = unicode_aswidechar('abcdef', 2)
@@ -851,11 +821,11 @@ class CAPITest(unittest.TestCase):
         self.assertRaises(SystemError, unicode_aswidechar_null, NULL, 10)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_aswidecharstring(self):
         """Test PyUnicode_AsWideCharString()"""
-        from _testcapi import unicode_aswidecharstring
-        from _testcapi import unicode_aswidecharstring_null
+        from _testlimitedcapi import unicode_aswidecharstring
+        from _testlimitedcapi import unicode_aswidecharstring_null
         from _testcapi import SIZEOF_WCHAR_T
 
         wchar, size = unicode_aswidecharstring('abc')
@@ -927,10 +897,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES asucs4copy(NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_fromordinal(self):
         """Test PyUnicode_FromOrdinal()"""
-        from _testcapi import unicode_fromordinal as fromordinal
+        from _testlimitedcapi import unicode_fromordinal as fromordinal
 
         self.assertEqual(fromordinal(0x61), 'a')
         self.assertEqual(fromordinal(0x20ac), '\u20ac')
@@ -956,11 +926,11 @@ class CAPITest(unittest.TestCase):
         # CRASHES unicode_asutf8(NULL, 0)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_asutf8andsize(self):
         """Test PyUnicode_AsUTF8AndSize()"""
-        from _testcapi import unicode_asutf8andsize
-        from _testcapi import unicode_asutf8andsize_null
+        from _testlimitedcapi import unicode_asutf8andsize
+        from _testlimitedcapi import unicode_asutf8andsize_null
 
         self.assertEqual(unicode_asutf8andsize('abc', 4), (b'abc\0', 3))
         self.assertEqual(unicode_asutf8andsize('абв', 7), (b'\xd0\xb0\xd0\xb1\xd0\xb2\0', 6))
@@ -979,10 +949,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES unicode_asutf8andsize_null(NULL, 0)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_getdefaultencoding(self):
         """Test PyUnicode_GetDefaultEncoding()"""
-        from _testcapi import unicode_getdefaultencoding as getdefaultencoding
+        from _testlimitedcapi import unicode_getdefaultencoding as getdefaultencoding
 
         self.assertEqual(getdefaultencoding(), b'utf-8')
 
@@ -1007,10 +977,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES transform_decimal(NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_concat(self):
         """Test PyUnicode_Concat()"""
-        from _testcapi import unicode_concat as concat
+        from _testlimitedcapi import unicode_concat as concat
 
         self.assertEqual(concat('abc', 'def'), 'abcdef')
         self.assertEqual(concat('abc', 'где'), 'abcгде')
@@ -1028,10 +998,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES concat('abc', NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_split(self):
         """Test PyUnicode_Split()"""
-        from _testcapi import unicode_split as split
+        from _testlimitedcapi import unicode_split as split
 
         self.assertEqual(split('a|b|c|d', '|'), ['a', 'b', 'c', 'd'])
         self.assertEqual(split('a|b|c|d', '|', 2), ['a', 'b', 'c|d'])
@@ -1056,10 +1026,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES split(NULL, '|')
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_rsplit(self):
         """Test PyUnicode_RSplit()"""
-        from _testcapi import unicode_rsplit as rsplit
+        from _testlimitedcapi import unicode_rsplit as rsplit
 
         self.assertEqual(rsplit('a|b|c|d', '|'), ['a', 'b', 'c', 'd'])
         self.assertEqual(rsplit('a|b|c|d', '|', 2), ['a|b', 'c', 'd'])
@@ -1085,10 +1055,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES rsplit(NULL, '|')
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_partition(self):
         """Test PyUnicode_Partition()"""
-        from _testcapi import unicode_partition as partition
+        from _testlimitedcapi import unicode_partition as partition
 
         self.assertEqual(partition('a|b|c', '|'), ('a', '|', 'b|c'))
         self.assertEqual(partition('a||b||c', '||'), ('a', '||', 'b||c'))
@@ -1105,10 +1075,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES partition('a|b|c', NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_rpartition(self):
         """Test PyUnicode_RPartition()"""
-        from _testcapi import unicode_rpartition as rpartition
+        from _testlimitedcapi import unicode_rpartition as rpartition
 
         self.assertEqual(rpartition('a|b|c', '|'), ('a|b', '|', 'c'))
         self.assertEqual(rpartition('a||b||c', '||'), ('a||b', '||', 'c'))
@@ -1125,10 +1095,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES rpartition('a|b|c', NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_splitlines(self):
         """Test PyUnicode_SplitLines()"""
-        from _testcapi import unicode_splitlines as splitlines
+        from _testlimitedcapi import unicode_splitlines as splitlines
 
         self.assertEqual(splitlines('a\nb\rc\r\nd'), ['a', 'b', 'c', 'd'])
         self.assertEqual(splitlines('a\nb\rc\r\nd', True),
@@ -1143,10 +1113,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES splitlines(NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_translate(self):
         """Test PyUnicode_Translate()"""
-        from _testcapi import unicode_translate as translate
+        from _testlimitedcapi import unicode_translate as translate
 
         self.assertEqual(translate('abcd', {ord('a'): 'A', ord('b'): ord('B'), ord('c'): '<>'}), 'AB<>d')
         self.assertEqual(translate('абвг', {ord('а'): 'А', ord('б'): ord('Б'), ord('в'): '<>'}), 'АБ<>г')
@@ -1168,10 +1138,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES translate(NULL, [])
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_join(self):
         """Test PyUnicode_Join()"""
-        from _testcapi import unicode_join as join
+        from _testlimitedcapi import unicode_join as join
         self.assertEqual(join('|', ['a', 'b', 'c']), 'a|b|c')
         self.assertEqual(join('|', ['a', '', 'c']), 'a||c')
         self.assertEqual(join('', ['a', 'b', 'c']), 'abc')
@@ -1186,10 +1156,10 @@ class CAPITest(unittest.TestCase):
         self.assertRaises(SystemError, join, '|', NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_count(self):
         """Test PyUnicode_Count()"""
-        from _testcapi import unicode_count
+        from _testlimitedcapi import unicode_count
 
         for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1":
             for i, ch in enumerate(str):
@@ -1217,10 +1187,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES unicode_count(str, NULL, 0, len(str))
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_tailmatch(self):
         """Test PyUnicode_Tailmatch()"""
-        from _testcapi import unicode_tailmatch as tailmatch
+        from _testlimitedcapi import unicode_tailmatch as tailmatch
 
         str = 'ababahalamaha'
         self.assertEqual(tailmatch(str, 'aba', 0, len(str), -1), 1)
@@ -1252,10 +1222,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES tailmatch(str, NULL, 0, len(str), -1)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_find(self):
         """Test PyUnicode_Find()"""
-        from _testcapi import unicode_find as find
+        from _testlimitedcapi import unicode_find as find
 
         for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1":
             for i, ch in enumerate(str):
@@ -1293,10 +1263,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES find(str, NULL, 0, len(str), 1)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_findchar(self):
         """Test PyUnicode_FindChar()"""
-        from _testcapi import unicode_findchar
+        from _testlimitedcapi import unicode_findchar
 
         for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1":
             for i, ch in enumerate(str):
@@ -1329,10 +1299,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES unicode_findchar(NULL, ord('!'), 0, len(str), 1), 1)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_replace(self):
         """Test PyUnicode_Replace()"""
-        from _testcapi import unicode_replace as replace
+        from _testlimitedcapi import unicode_replace as replace
 
         str = 'abracadabra'
         self.assertEqual(replace(str, 'a', '='), '=br=c=d=br=')
@@ -1360,10 +1330,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES replace(NULL, 'a', '=')
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_compare(self):
         """Test PyUnicode_Compare()"""
-        from _testcapi import unicode_compare as compare
+        from _testlimitedcapi import unicode_compare as compare
 
         self.assertEqual(compare('abc', 'abc'), 0)
         self.assertEqual(compare('abc', 'def'), -1)
@@ -1382,10 +1352,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES compare('abc', NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_comparewithasciistring(self):
         """Test PyUnicode_CompareWithASCIIString()"""
-        from _testcapi import unicode_comparewithasciistring as comparewithasciistring
+        from _testlimitedcapi import unicode_comparewithasciistring as comparewithasciistring
 
         self.assertEqual(comparewithasciistring('abc', b'abc'), 0)
         self.assertEqual(comparewithasciistring('abc', b'def'), -1)
@@ -1399,11 +1369,11 @@ class CAPITest(unittest.TestCase):
         # CRASHES comparewithasciistring(NULL, b'abc')
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_equaltoutf8(self):
         # Test PyUnicode_EqualToUTF8()
-        from _testcapi import unicode_equaltoutf8 as equaltoutf8
-        from _testcapi import unicode_asutf8andsize as asutf8andsize
+        from _testlimitedcapi import unicode_equaltoutf8 as equaltoutf8
+        from _testlimitedcapi import unicode_asutf8andsize as asutf8andsize
 
         strings = [
             'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16',
@@ -1445,11 +1415,11 @@ class CAPITest(unittest.TestCase):
                             '\ud801'.encode("utf8", "surrogatepass")), 0)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_equaltoutf8andsize(self):
         # Test PyUnicode_EqualToUTF8AndSize()
-        from _testcapi import unicode_equaltoutf8andsize as equaltoutf8andsize
-        from _testcapi import unicode_asutf8andsize as asutf8andsize
+        from _testlimitedcapi import unicode_equaltoutf8andsize as equaltoutf8andsize
+        from _testlimitedcapi import unicode_asutf8andsize as asutf8andsize
 
         strings = [
             'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16',
@@ -1514,10 +1484,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES equaltoutf8andsize('abc', NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_richcompare(self):
         """Test PyUnicode_RichCompare()"""
-        from _testcapi import unicode_richcompare as richcompare
+        from _testlimitedcapi import unicode_richcompare as richcompare
 
         LT, LE, EQ, NE, GT, GE = range(6)
         strings = ('abc', 'абв', '\U0001f600', 'abc\0')
@@ -1542,10 +1512,10 @@ class CAPITest(unittest.TestCase):
             # CRASHES richcompare('abc', NULL, op)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_format(self):
         """Test PyUnicode_Format()"""
-        from _testcapi import unicode_format as format
+        from _testlimitedcapi import unicode_format as format
 
         self.assertEqual(format('x=%d!', 42), 'x=42!')
         self.assertEqual(format('x=%d!', (42,)), 'x=42!')
@@ -1555,10 +1525,10 @@ class CAPITest(unittest.TestCase):
         self.assertRaises(SystemError, format, NULL, 42)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_contains(self):
         """Test PyUnicode_Contains()"""
-        from _testcapi import unicode_contains as contains
+        from _testlimitedcapi import unicode_contains as contains
 
         self.assertEqual(contains('abcd', ''), 1)
         self.assertEqual(contains('abcd', 'b'), 1)
@@ -1577,10 +1547,10 @@ class CAPITest(unittest.TestCase):
         # CRASHES contains('abcd', NULL)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_isidentifier(self):
         """Test PyUnicode_IsIdentifier()"""
-        from _testcapi import unicode_isidentifier as isidentifier
+        from _testlimitedcapi import unicode_isidentifier as isidentifier
 
         self.assertEqual(isidentifier("a"), 1)
         self.assertEqual(isidentifier("b0"), 1)
index fe3776d6dd9337811cc3b4b7a820b70b9649a902..e05b95c2d60bade83dfefc576cf9e4bd7ee3f3d5 100644 (file)
@@ -13,9 +13,9 @@ from test import support
 from test.support import os_helper
 
 try:
-    import _testcapi
+    import _testlimitedcapi
 except ImportError:
-    _testcapi = None
+    _testlimitedcapi = None
 try:
     import _testinternalcapi
 except ImportError:
@@ -2224,14 +2224,14 @@ class BasicUnicodeTest(unittest.TestCase, MixInCheckStateHandling):
                                          "encoding=%r" % encoding)
 
     @support.cpython_only
-    @unittest.skipIf(_testcapi is None, 'need _testcapi module')
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_basics_capi(self):
         s = "abc123"  # all codecs should be able to encode these
         for encoding in all_unicode_encodings:
             if encoding not in broken_unicode_with_stateful:
                 # check incremental decoder/encoder (fetched via the C API)
                 try:
-                    cencoder = _testcapi.codec_incrementalencoder(encoding)
+                    cencoder = _testlimitedcapi.codec_incrementalencoder(encoding)
                 except LookupError:  # no IncrementalEncoder
                     pass
                 else:
@@ -2240,7 +2240,7 @@ class BasicUnicodeTest(unittest.TestCase, MixInCheckStateHandling):
                     for c in s:
                         encodedresult += cencoder.encode(c)
                     encodedresult += cencoder.encode("", True)
-                    cdecoder = _testcapi.codec_incrementaldecoder(encoding)
+                    cdecoder = _testlimitedcapi.codec_incrementaldecoder(encoding)
                     decodedresult = ""
                     for c in encodedresult:
                         decodedresult += cdecoder.decode(bytes([c]))
@@ -2251,12 +2251,12 @@ class BasicUnicodeTest(unittest.TestCase, MixInCheckStateHandling):
                 if encoding not in ("idna", "mbcs"):
                     # check incremental decoder/encoder with errors argument
                     try:
-                        cencoder = _testcapi.codec_incrementalencoder(encoding, "ignore")
+                        cencoder = _testlimitedcapi.codec_incrementalencoder(encoding, "ignore")
                     except LookupError:  # no IncrementalEncoder
                         pass
                     else:
                         encodedresult = b"".join(cencoder.encode(c) for c in s)
-                        cdecoder = _testcapi.codec_incrementaldecoder(encoding, "ignore")
+                        cdecoder = _testlimitedcapi.codec_incrementaldecoder(encoding, "ignore")
                         decodedresult = "".join(cdecoder.decode(bytes([c]))
                                                 for c in encodedresult)
                         self.assertEqual(decodedresult, s,
index d6c322e715efe9d1cd334d4a7d6576dff38b15ca..99aef6f39cfd1e9dd481a478a1821fdc9eb4208d 100644 (file)
 @MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
 @MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c _testinternalcapi/test_critical_sections.c
 @MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/complex.c _testcapi/numbers.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/gc.c _testcapi/hash.c _testcapi/time.c
-@MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/float.c _testlimitedcapi/heaptype_relative.c _testlimitedcapi/list.c _testlimitedcapi/pyos.c _testlimitedcapi/set.c _testlimitedcapi/sys.c _testlimitedcapi/vectorcall_limited.c
+@MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/float.c _testlimitedcapi/heaptype_relative.c _testlimitedcapi/list.c _testlimitedcapi/pyos.c _testlimitedcapi/set.c _testlimitedcapi/sys.c _testlimitedcapi/unicode.c _testlimitedcapi/vectorcall_limited.c
 @MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
 @MODULE__TESTCLINIC_LIMITED_TRUE@_testclinic_limited _testclinic_limited.c
 
index d0954bbe36ff9df05dd215f0658f411473150abd..015db9017139d09a93f93d95640dc2a3ea4549ed 100644 (file)
 #include "parts.h"
 #include "util.h"
 
+/* Test PyUnicode_New() */
 static PyObject *
-codec_incrementalencoder(PyObject *self, PyObject *args)
-{
-    const char *encoding, *errors = NULL;
-    if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder",
-                          &encoding, &errors))
-        return NULL;
-    return PyCodec_IncrementalEncoder(encoding, errors);
-}
-
-static PyObject *
-codec_incrementaldecoder(PyObject *self, PyObject *args)
-{
-    const char *encoding, *errors = NULL;
-    if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder",
-                          &encoding, &errors))
-        return NULL;
-    return PyCodec_IncrementalDecoder(encoding, errors);
-}
-
-static PyObject *
-test_unicode_compare_with_ascii(PyObject *self, PyObject *Py_UNUSED(ignored)) {
-    PyObject *py_s = PyUnicode_FromStringAndSize("str\0", 4);
-    int result;
-    if (py_s == NULL)
-        return NULL;
-    result = PyUnicode_CompareWithASCIIString(py_s, "str");
-    Py_DECREF(py_s);
-    if (!result) {
-        PyErr_SetString(PyExc_AssertionError, "Python string ending in NULL "
-                        "should not compare equal to c string.");
-        return NULL;
-    }
-    Py_RETURN_NONE;
-}
-
-static PyObject *
-test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored))
+unicode_new(PyObject *self, PyObject *args)
 {
-#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4)
-    const wchar_t wtext[2] = {(wchar_t)0x10ABCDu};
-    size_t wtextlen = 1;
-    const wchar_t invalid[1] = {(wchar_t)0x110000u};
-#else
-    const wchar_t wtext[3] = {(wchar_t)0xDBEAu, (wchar_t)0xDFCDu};
-    size_t wtextlen = 2;
-#endif
-    PyObject *wide, *utf8;
-
-    wide = PyUnicode_FromWideChar(wtext, wtextlen);
-    if (wide == NULL)
-        return NULL;
+    Py_ssize_t size;
+    unsigned int maxchar;
+    PyObject *result;
 
-    utf8 = PyUnicode_FromString("\xf4\x8a\xaf\x8d");
-    if (utf8 == NULL) {
-        Py_DECREF(wide);
+    if (!PyArg_ParseTuple(args, "nI", &size, &maxchar)) {
         return NULL;
     }
 
-    if (PyUnicode_GET_LENGTH(wide) != PyUnicode_GET_LENGTH(utf8)) {
-        Py_DECREF(wide);
-        Py_DECREF(utf8);
-        PyErr_SetString(PyExc_AssertionError,
-                        "test_widechar: "
-                        "wide string and utf8 string "
-                        "have different length");
-        return NULL;
-    }
-    if (PyUnicode_Compare(wide, utf8)) {
-        Py_DECREF(wide);
-        Py_DECREF(utf8);
-        if (PyErr_Occurred())
-            return NULL;
-        PyErr_SetString(PyExc_AssertionError,
-                        "test_widechar: "
-                        "wide string and utf8 string "
-                        "are different");
+    result = PyUnicode_New(size, (Py_UCS4)maxchar);
+    if (!result) {
         return NULL;
     }
-
-    Py_DECREF(wide);
-    Py_DECREF(utf8);
-
-#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4)
-    wide = PyUnicode_FromWideChar(invalid, 1);
-    if (wide == NULL)
-        PyErr_Clear();
-    else {
-        PyErr_SetString(PyExc_AssertionError,
-                        "test_widechar: "
-                        "PyUnicode_FromWideChar(L\"\\U00110000\", 1) didn't fail");
+    if (size > 0 && maxchar <= 0x10ffff &&
+        PyUnicode_Fill(result, 0, size, (Py_UCS4)maxchar) < 0)
+    {
+        Py_DECREF(result);
         return NULL;
     }
-#endif
-    Py_RETURN_NONE;
+    return result;
 }
 
 
@@ -128,30 +56,6 @@ unicode_copy(PyObject *unicode)
     return copy;
 }
 
-/* Test PyUnicode_New() */
-static PyObject *
-unicode_new(PyObject *self, PyObject *args)
-{
-    Py_ssize_t size;
-    unsigned int maxchar;
-    PyObject *result;
-
-    if (!PyArg_ParseTuple(args, "nI", &size, &maxchar)) {
-        return NULL;
-    }
-
-    result = PyUnicode_New(size, (Py_UCS4)maxchar);
-    if (!result) {
-        return NULL;
-    }
-    if (size > 0 && maxchar <= 0x10ffff &&
-        PyUnicode_Fill(result, 0, size, (Py_UCS4)maxchar) < 0)
-    {
-        Py_DECREF(result);
-        return NULL;
-    }
-    return result;
-}
 
 /* Test PyUnicode_Fill() */
 static PyObject *
@@ -178,129 +82,6 @@ unicode_fill(PyObject *self, PyObject *args)
     return Py_BuildValue("(Nn)", to_copy, filled);
 }
 
-/* Test PyUnicode_WriteChar() */
-static PyObject *
-unicode_writechar(PyObject *self, PyObject *args)
-{
-    PyObject *to, *to_copy;
-    Py_ssize_t index;
-    unsigned int character;
-    int result;
-
-    if (!PyArg_ParseTuple(args, "OnI", &to, &index, &character)) {
-        return NULL;
-    }
-
-    NULLABLE(to);
-    if (!(to_copy = unicode_copy(to)) && to) {
-        return NULL;
-    }
-
-    result = PyUnicode_WriteChar(to_copy, index, (Py_UCS4)character);
-    if (result == -1 && PyErr_Occurred()) {
-        Py_DECREF(to_copy);
-        return NULL;
-    }
-    return Py_BuildValue("(Ni)", to_copy, result);
-}
-
-/* Test PyUnicode_Resize() */
-static PyObject *
-unicode_resize(PyObject *self, PyObject *args)
-{
-    PyObject *obj, *copy;
-    Py_ssize_t length;
-    int result;
-
-    if (!PyArg_ParseTuple(args, "On", &obj, &length)) {
-        return NULL;
-    }
-
-    NULLABLE(obj);
-    if (!(copy = unicode_copy(obj)) && obj) {
-        return NULL;
-    }
-    result = PyUnicode_Resize(&copy, length);
-    if (result == -1 && PyErr_Occurred()) {
-        Py_XDECREF(copy);
-        return NULL;
-    }
-    if (obj && PyUnicode_Check(obj) && length > PyUnicode_GET_LENGTH(obj)) {
-        if (PyUnicode_Fill(copy, PyUnicode_GET_LENGTH(obj), length, 0U) < 0) {
-            Py_DECREF(copy);
-            return NULL;
-        }
-    }
-    return Py_BuildValue("(Ni)", copy, result);
-}
-
-/* Test PyUnicode_Append() */
-static PyObject *
-unicode_append(PyObject *self, PyObject *args)
-{
-    PyObject *left, *right, *left_copy;
-
-    if (!PyArg_ParseTuple(args, "OO", &left, &right))
-        return NULL;
-
-    NULLABLE(left);
-    NULLABLE(right);
-    if (!(left_copy = unicode_copy(left)) && left) {
-        return NULL;
-    }
-    PyUnicode_Append(&left_copy, right);
-    return left_copy;
-}
-
-/* Test PyUnicode_AppendAndDel() */
-static PyObject *
-unicode_appendanddel(PyObject *self, PyObject *args)
-{
-    PyObject *left, *right, *left_copy;
-
-    if (!PyArg_ParseTuple(args, "OO", &left, &right))
-        return NULL;
-
-    NULLABLE(left);
-    NULLABLE(right);
-    if (!(left_copy = unicode_copy(left)) && left) {
-        return NULL;
-    }
-    Py_XINCREF(right);
-    PyUnicode_AppendAndDel(&left_copy, right);
-    return left_copy;
-}
-
-/* Test PyUnicode_FromStringAndSize() */
-static PyObject *
-unicode_fromstringandsize(PyObject *self, PyObject *args)
-{
-    const char *s;
-    Py_ssize_t bsize;
-    Py_ssize_t size = -100;
-
-    if (!PyArg_ParseTuple(args, "z#|n", &s, &bsize, &size)) {
-        return NULL;
-    }
-
-    if (size == -100) {
-        size = bsize;
-    }
-    return PyUnicode_FromStringAndSize(s, size);
-}
-
-/* Test PyUnicode_FromString() */
-static PyObject *
-unicode_fromstring(PyObject *self, PyObject *arg)
-{
-    const char *s;
-    Py_ssize_t size;
-
-    if (!PyArg_Parse(arg, "z#", &s, &size)) {
-        return NULL;
-    }
-    return PyUnicode_FromString(s);
-}
 
 /* Test PyUnicode_FromKindAndData() */
 static PyObject *
@@ -326,211 +107,9 @@ unicode_fromkindanddata(PyObject *self, PyObject *args)
     return PyUnicode_FromKindAndData(kind, buffer, kind ? size / kind : 0);
 }
 
-/* Test PyUnicode_Substring() */
-static PyObject *
-unicode_substring(PyObject *self, PyObject *args)
-{
-    PyObject *str;
-    Py_ssize_t start, end;
-
-    if (!PyArg_ParseTuple(args, "Onn", &str, &start, &end)) {
-        return NULL;
-    }
-
-    NULLABLE(str);
-    return PyUnicode_Substring(str, start, end);
-}
-
-/* Test PyUnicode_GetLength() */
-static PyObject *
-unicode_getlength(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    RETURN_SIZE(PyUnicode_GetLength(arg));
-}
-
-/* Test PyUnicode_ReadChar() */
-static PyObject *
-unicode_readchar(PyObject *self, PyObject *args)
-{
-    PyObject *unicode;
-    Py_ssize_t index;
-    Py_UCS4 result;
-
-    if (!PyArg_ParseTuple(args, "On", &unicode, &index)) {
-        return NULL;
-    }
-
-    NULLABLE(unicode);
-    result = PyUnicode_ReadChar(unicode, index);
-    if (result == (Py_UCS4)-1)
-        return NULL;
-    return PyLong_FromUnsignedLong(result);
-}
-
-/* Test PyUnicode_FromEncodedObject() */
-static PyObject *
-unicode_fromencodedobject(PyObject *self, PyObject *args)
-{
-    PyObject *obj;
-    const char *encoding;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "Oz|z", &obj, &encoding, &errors)) {
-        return NULL;
-    }
-
-    NULLABLE(obj);
-    return PyUnicode_FromEncodedObject(obj, encoding, errors);
-}
-
-/* Test PyUnicode_FromObject() */
-static PyObject *
-unicode_fromobject(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_FromObject(arg);
-}
-
-/* Test PyUnicode_InternInPlace() */
-static PyObject *
-unicode_interninplace(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    Py_XINCREF(arg);
-    PyUnicode_InternInPlace(&arg);
-    return arg;
-}
-
-/* Test PyUnicode_InternFromString() */
-static PyObject *
-unicode_internfromstring(PyObject *self, PyObject *arg)
-{
-    const char *s;
-    Py_ssize_t size;
-
-    if (!PyArg_Parse(arg, "z#", &s, &size)) {
-        return NULL;
-    }
-    return PyUnicode_InternFromString(s);
-}
-
-/* Test PyUnicode_FromWideChar() */
-static PyObject *
-unicode_fromwidechar(PyObject *self, PyObject *args)
-{
-    const char *s;
-    Py_ssize_t bsize;
-    Py_ssize_t size = -100;
-
-    if (!PyArg_ParseTuple(args, "z#|n", &s, &bsize, &size)) {
-        return NULL;
-    }
-    if (size == -100) {
-        if (bsize % SIZEOF_WCHAR_T) {
-            PyErr_SetString(PyExc_AssertionError,
-                            "invalid size in unicode_fromwidechar()");
-            return NULL;
-        }
-        size = bsize / SIZEOF_WCHAR_T;
-    }
-    return PyUnicode_FromWideChar((const wchar_t *)s, size);
-}
-
-/* Test PyUnicode_AsWideChar() */
-static PyObject *
-unicode_aswidechar(PyObject *self, PyObject *args)
-{
-    PyObject *unicode, *result;
-    Py_ssize_t buflen, size;
-    wchar_t *buffer;
-
-    if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
-        return NULL;
-    NULLABLE(unicode);
-    buffer = PyMem_New(wchar_t, buflen);
-    if (buffer == NULL)
-        return PyErr_NoMemory();
-
-    size = PyUnicode_AsWideChar(unicode, buffer, buflen);
-    if (size == -1) {
-        PyMem_Free(buffer);
-        return NULL;
-    }
-
-    if (size < buflen)
-        buflen = size + 1;
-    else
-        buflen = size;
-    result = PyUnicode_FromWideChar(buffer, buflen);
-    PyMem_Free(buffer);
-    if (result == NULL)
-        return NULL;
-
-    return Py_BuildValue("(Nn)", result, size);
-}
-
-/* Test PyUnicode_AsWideCharString() with NULL as buffer */
-static PyObject *
-unicode_aswidechar_null(PyObject *self, PyObject *args)
-{
-    PyObject *unicode;
-    Py_ssize_t buflen;
-
-    if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
-        return NULL;
-    NULLABLE(unicode);
-    RETURN_SIZE(PyUnicode_AsWideChar(unicode, NULL, buflen));
-}
-
-/* Test PyUnicode_AsWideCharString() */
-static PyObject *
-unicode_aswidecharstring(PyObject *self, PyObject *args)
-{
-    PyObject *unicode, *result;
-    Py_ssize_t size = UNINITIALIZED_SIZE;
-    wchar_t *buffer;
-
-    if (!PyArg_ParseTuple(args, "O", &unicode))
-        return NULL;
-
-    NULLABLE(unicode);
-    buffer = PyUnicode_AsWideCharString(unicode, &size);
-    if (buffer == NULL) {
-        assert(size == UNINITIALIZED_SIZE);
-        return NULL;
-    }
-
-    result = PyUnicode_FromWideChar(buffer, size + 1);
-    PyMem_Free(buffer);
-    if (result == NULL)
-        return NULL;
-    return Py_BuildValue("(Nn)", result, size);
-}
-
-/* Test PyUnicode_AsWideCharString() with NULL as the size address */
-static PyObject *
-unicode_aswidecharstring_null(PyObject *self, PyObject *args)
-{
-    PyObject *unicode, *result;
-    wchar_t *buffer;
-
-    if (!PyArg_ParseTuple(args, "O", &unicode))
-        return NULL;
-
-    NULLABLE(unicode);
-    buffer = PyUnicode_AsWideCharString(unicode, NULL);
-    if (buffer == NULL)
-        return NULL;
-
-    result = PyUnicode_FromWideChar(buffer, -1);
-    PyMem_Free(buffer);
-    if (result == NULL)
-        return NULL;
-    return result;
-}
 
-/* Test PyUnicode_AsUCS4() */
+// Test PyUnicode_AsUCS4().
+// Part of the limited C API, but the test needs PyUnicode_FromKindAndData().
 static PyObject *
 unicode_asucs4(PyObject *self, PyObject *args)
 {
@@ -562,7 +141,9 @@ unicode_asucs4(PyObject *self, PyObject *args)
     return result;
 }
 
-/* Test PyUnicode_AsUCS4Copy() */
+
+// Test PyUnicode_AsUCS4Copy().
+// Part of the limited C API, but the test needs PyUnicode_FromKindAndData().
 static PyObject *
 unicode_asucs4copy(PyObject *self, PyObject *args)
 {
@@ -586,17 +167,6 @@ unicode_asucs4copy(PyObject *self, PyObject *args)
     return result;
 }
 
-/* Test PyUnicode_FromOrdinal() */
-static PyObject *
-unicode_fromordinal(PyObject *self, PyObject *args)
-{
-    int ordinal;
-
-    if (!PyArg_ParseTuple(args, "i", &ordinal))
-        return NULL;
-
-    return PyUnicode_FromOrdinal(ordinal);
-}
 
 /* Test PyUnicode_AsUTF8() */
 static PyObject *
@@ -617,911 +187,6 @@ unicode_asutf8(PyObject *self, PyObject *args)
     return PyBytes_FromStringAndSize(s, buflen);
 }
 
-/* Test PyUnicode_AsUTF8AndSize() */
-static PyObject *
-unicode_asutf8andsize(PyObject *self, PyObject *args)
-{
-    PyObject *unicode;
-    Py_ssize_t buflen;
-    const char *s;
-    Py_ssize_t size = UNINITIALIZED_SIZE;
-
-    if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
-        return NULL;
-
-    NULLABLE(unicode);
-    s = PyUnicode_AsUTF8AndSize(unicode, &size);
-    if (s == NULL) {
-        assert(size == -1);
-        return NULL;
-    }
-
-    return Py_BuildValue("(y#n)", s, buflen, size);
-}
-
-/* Test PyUnicode_AsUTF8AndSize() with NULL as the size address */
-static PyObject *
-unicode_asutf8andsize_null(PyObject *self, PyObject *args)
-{
-    PyObject *unicode;
-    Py_ssize_t buflen;
-    const char *s;
-
-    if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
-        return NULL;
-
-    NULLABLE(unicode);
-    s = PyUnicode_AsUTF8AndSize(unicode, NULL);
-    if (s == NULL)
-        return NULL;
-
-    return PyBytes_FromStringAndSize(s, buflen);
-}
-
-/* Test PyUnicode_GetDefaultEncoding() */
-static PyObject *
-unicode_getdefaultencoding(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    const char *s = PyUnicode_GetDefaultEncoding();
-    if (s == NULL)
-        return NULL;
-
-    return PyBytes_FromString(s);
-}
-
-/* Test PyUnicode_Decode() */
-static PyObject *
-unicode_decode(PyObject *self, PyObject *args)
-{
-    const char *s;
-    Py_ssize_t size;
-    const char *encoding;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "y#z|z", &s, &size, &encoding, &errors))
-        return NULL;
-
-    return PyUnicode_Decode(s, size, encoding, errors);
-}
-
-/* Test PyUnicode_AsEncodedString() */
-static PyObject *
-unicode_asencodedstring(PyObject *self, PyObject *args)
-{
-    PyObject *unicode;
-    const char *encoding;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "Oz|z", &unicode, &encoding, &errors))
-        return NULL;
-
-    NULLABLE(unicode);
-    return PyUnicode_AsEncodedString(unicode, encoding, errors);
-}
-
-/* Test PyUnicode_BuildEncodingMap() */
-static PyObject *
-unicode_buildencodingmap(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_BuildEncodingMap(arg);
-}
-
-/* Test PyUnicode_DecodeUTF7() */
-static PyObject *
-unicode_decodeutf7(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    return PyUnicode_DecodeUTF7(data, size, errors);
-}
-
-/* Test PyUnicode_DecodeUTF7Stateful() */
-static PyObject *
-unicode_decodeutf7stateful(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-    Py_ssize_t consumed = UNINITIALIZED_SIZE;
-    PyObject *result;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    result = PyUnicode_DecodeUTF7Stateful(data, size, errors, &consumed);
-    if (!result) {
-        assert(consumed == UNINITIALIZED_SIZE);
-        return NULL;
-    }
-    return Py_BuildValue("(Nn)", result, consumed);
-}
-
-/* Test PyUnicode_DecodeUTF8() */
-static PyObject *
-unicode_decodeutf8(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    return PyUnicode_DecodeUTF8(data, size, errors);
-}
-
-/* Test PyUnicode_DecodeUTF8Stateful() */
-static PyObject *
-unicode_decodeutf8stateful(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-    Py_ssize_t consumed = UNINITIALIZED_SIZE;
-    PyObject *result;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    result = PyUnicode_DecodeUTF8Stateful(data, size, errors, &consumed);
-    if (!result) {
-        assert(consumed == UNINITIALIZED_SIZE);
-        return NULL;
-    }
-    return Py_BuildValue("(Nn)", result, consumed);
-}
-
-/* Test PyUnicode_AsUTF8String() */
-static PyObject *
-unicode_asutf8string(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_AsUTF8String(arg);
-}
-
-/* Test PyUnicode_DecodeUTF32() */
-static PyObject *
-unicode_decodeutf32(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-    int byteorder = UNINITIALIZED_INT;
-    PyObject *result;
-
-    if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
-        return NULL;
-
-    result = PyUnicode_DecodeUTF32(data, size, errors, &byteorder);
-    if (!result) {
-        return NULL;
-    }
-    return Py_BuildValue("(iN)", byteorder, result);
-}
-
-/* Test PyUnicode_DecodeUTF32Stateful() */
-static PyObject *
-unicode_decodeutf32stateful(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-    int byteorder = UNINITIALIZED_INT;
-    Py_ssize_t consumed = UNINITIALIZED_SIZE;
-    PyObject *result;
-
-    if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
-        return NULL;
-
-    result = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder, &consumed);
-    if (!result) {
-        assert(consumed == UNINITIALIZED_SIZE);
-        return NULL;
-    }
-    return Py_BuildValue("(iNn)", byteorder, result, consumed);
-}
-
-/* Test PyUnicode_AsUTF32String() */
-static PyObject *
-unicode_asutf32string(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_AsUTF32String(arg);
-}
-
-/* Test PyUnicode_DecodeUTF16() */
-static PyObject *
-unicode_decodeutf16(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-    int byteorder = UNINITIALIZED_INT;
-    PyObject *result;
-
-    if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
-        return NULL;
-
-    result = PyUnicode_DecodeUTF16(data, size, errors, &byteorder);
-    if (!result) {
-        return NULL;
-    }
-    return Py_BuildValue("(iN)", byteorder, result);
-}
-
-/* Test PyUnicode_DecodeUTF16Stateful() */
-static PyObject *
-unicode_decodeutf16stateful(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-    int byteorder = UNINITIALIZED_INT;
-    Py_ssize_t consumed = UNINITIALIZED_SIZE;
-    PyObject *result;
-
-    if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
-        return NULL;
-
-    result = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, &consumed);
-    if (!result) {
-        assert(consumed == UNINITIALIZED_SIZE);
-        return NULL;
-    }
-    return Py_BuildValue("(iNn)", byteorder, result, consumed);
-}
-
-/* Test PyUnicode_AsUTF16String() */
-static PyObject *
-unicode_asutf16string(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_AsUTF16String(arg);
-}
-
-/* Test PyUnicode_DecodeUnicodeEscape() */
-static PyObject *
-unicode_decodeunicodeescape(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    return PyUnicode_DecodeUnicodeEscape(data, size, errors);
-}
-
-/* Test PyUnicode_AsUnicodeEscapeString() */
-static PyObject *
-unicode_asunicodeescapestring(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_AsUnicodeEscapeString(arg);
-}
-
-static PyObject *
-unicode_decoderawunicodeescape(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    return PyUnicode_DecodeRawUnicodeEscape(data, size, errors);
-}
-
-/* Test PyUnicode_AsRawUnicodeEscapeString() */
-static PyObject *
-unicode_asrawunicodeescapestring(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_AsRawUnicodeEscapeString(arg);
-}
-
-static PyObject *
-unicode_decodelatin1(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    return PyUnicode_DecodeLatin1(data, size, errors);
-}
-
-/* Test PyUnicode_AsLatin1String() */
-static PyObject *
-unicode_aslatin1string(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_AsLatin1String(arg);
-}
-
-/* Test PyUnicode_DecodeASCII() */
-static PyObject *
-unicode_decodeascii(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    return PyUnicode_DecodeASCII(data, size, errors);
-}
-
-/* Test PyUnicode_AsASCIIString() */
-static PyObject *
-unicode_asasciistring(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_AsASCIIString(arg);
-}
-
-/* Test PyUnicode_DecodeCharmap() */
-static PyObject *
-unicode_decodecharmap(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    PyObject *mapping;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "y#O|z", &data, &size, &mapping, &errors))
-        return NULL;
-
-    NULLABLE(mapping);
-    return PyUnicode_DecodeCharmap(data, size, mapping, errors);
-}
-
-/* Test PyUnicode_AsCharmapString() */
-static PyObject *
-unicode_ascharmapstring(PyObject *self, PyObject *args)
-{
-    PyObject *unicode;
-    PyObject *mapping;
-
-    if (!PyArg_ParseTuple(args, "OO", &unicode, &mapping))
-        return NULL;
-
-    NULLABLE(unicode);
-    NULLABLE(mapping);
-    return PyUnicode_AsCharmapString(unicode, mapping);
-}
-
-#ifdef MS_WINDOWS
-
-/* Test PyUnicode_DecodeMBCS() */
-static PyObject *
-unicode_decodembcs(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    return PyUnicode_DecodeMBCS(data, size, errors);
-}
-
-/* Test PyUnicode_DecodeMBCSStateful() */
-static PyObject *
-unicode_decodembcsstateful(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-    Py_ssize_t consumed = UNINITIALIZED_SIZE;
-    PyObject *result;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    result = PyUnicode_DecodeMBCSStateful(data, size, errors, &consumed);
-    if (!result) {
-        assert(consumed == UNINITIALIZED_SIZE);
-        return NULL;
-    }
-    return Py_BuildValue("(Nn)", result, consumed);
-}
-
-/* Test PyUnicode_DecodeCodePageStateful() */
-static PyObject *
-unicode_decodecodepagestateful(PyObject *self, PyObject *args)
-{
-    int code_page;
-    const char *data;
-    Py_ssize_t size;
-    const char *errors = NULL;
-    Py_ssize_t consumed = UNINITIALIZED_SIZE;
-    PyObject *result;
-
-    if (!PyArg_ParseTuple(args, "iy#|z", &code_page, &data, &size, &errors))
-        return NULL;
-
-    result = PyUnicode_DecodeCodePageStateful(code_page, data, size, errors, &consumed);
-    if (!result) {
-        assert(consumed == UNINITIALIZED_SIZE);
-        return NULL;
-    }
-    return Py_BuildValue("(Nn)", result, consumed);
-}
-
-/* Test PyUnicode_AsMBCSString() */
-static PyObject *
-unicode_asmbcsstring(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_AsMBCSString(arg);
-}
-
-/* Test PyUnicode_EncodeCodePage() */
-static PyObject *
-unicode_encodecodepage(PyObject *self, PyObject *args)
-{
-    int code_page;
-    PyObject *unicode;
-    const char *errors;
-
-    if (!PyArg_ParseTuple(args, "iO|z", &code_page, &unicode, &errors))
-        return NULL;
-
-    NULLABLE(unicode);
-    return PyUnicode_EncodeCodePage(code_page, unicode, errors);
-}
-
-#endif /* MS_WINDOWS */
-
-/* Test PyUnicode_DecodeLocaleAndSize() */
-static PyObject *
-unicode_decodelocaleandsize(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    return PyUnicode_DecodeLocaleAndSize(data, size, errors);
-}
-
-/* Test PyUnicode_DecodeLocale() */
-static PyObject *
-unicode_decodelocale(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-    const char *errors;
-
-    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
-        return NULL;
-
-    return PyUnicode_DecodeLocale(data, errors);
-}
-
-/* Test PyUnicode_EncodeLocale() */
-static PyObject *
-unicode_encodelocale(PyObject *self, PyObject *args)
-{
-    PyObject *unicode;
-    const char *errors;
-
-    if (!PyArg_ParseTuple(args, "O|z", &unicode, &errors))
-        return NULL;
-
-    NULLABLE(unicode);
-    return PyUnicode_EncodeLocale(unicode, errors);
-}
-
-/* Test PyUnicode_DecodeFSDefault() */
-static PyObject *
-unicode_decodefsdefault(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-
-    if (!PyArg_ParseTuple(args, "y#", &data, &size))
-        return NULL;
-
-    return PyUnicode_DecodeFSDefault(data);
-}
-
-/* Test PyUnicode_DecodeFSDefaultAndSize() */
-static PyObject *
-unicode_decodefsdefaultandsize(PyObject *self, PyObject *args)
-{
-    const char *data;
-    Py_ssize_t size;
-
-    if (!PyArg_ParseTuple(args, "y#|n", &data, &size, &size))
-        return NULL;
-
-    return PyUnicode_DecodeFSDefaultAndSize(data, size);
-}
-
-/* Test PyUnicode_EncodeFSDefault() */
-static PyObject *
-unicode_encodefsdefault(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    return PyUnicode_EncodeFSDefault(arg);
-}
-
-/* Test PyUnicode_Concat() */
-static PyObject *
-unicode_concat(PyObject *self, PyObject *args)
-{
-    PyObject *left;
-    PyObject *right;
-
-    if (!PyArg_ParseTuple(args, "OO", &left, &right))
-        return NULL;
-
-    NULLABLE(left);
-    NULLABLE(right);
-    return PyUnicode_Concat(left, right);
-}
-
-/* Test PyUnicode_Split() */
-static PyObject *
-unicode_split(PyObject *self, PyObject *args)
-{
-    PyObject *s;
-    PyObject *sep;
-    Py_ssize_t maxsplit = -1;
-
-    if (!PyArg_ParseTuple(args, "OO|n", &s, &sep, &maxsplit))
-        return NULL;
-
-    NULLABLE(s);
-    NULLABLE(sep);
-    return PyUnicode_Split(s, sep, maxsplit);
-}
-
-/* Test PyUnicode_RSplit() */
-static PyObject *
-unicode_rsplit(PyObject *self, PyObject *args)
-{
-    PyObject *s;
-    PyObject *sep;
-    Py_ssize_t maxsplit = -1;
-
-    if (!PyArg_ParseTuple(args, "OO|n", &s, &sep, &maxsplit))
-        return NULL;
-
-    NULLABLE(s);
-    NULLABLE(sep);
-    return PyUnicode_RSplit(s, sep, maxsplit);
-}
-
-/* Test PyUnicode_Splitlines() */
-static PyObject *
-unicode_splitlines(PyObject *self, PyObject *args)
-{
-    PyObject *s;
-    int keepends = 0;
-
-    if (!PyArg_ParseTuple(args, "O|i", &s, &keepends))
-        return NULL;
-
-    NULLABLE(s);
-    return PyUnicode_Splitlines(s, keepends);
-}
-
-/* Test PyUnicode_Partition() */
-static PyObject *
-unicode_partition(PyObject *self, PyObject *args)
-{
-    PyObject *s;
-    PyObject *sep;
-
-    if (!PyArg_ParseTuple(args, "OO", &s, &sep))
-        return NULL;
-
-    NULLABLE(s);
-    NULLABLE(sep);
-    return PyUnicode_Partition(s, sep);
-}
-
-/* Test PyUnicode_RPartition() */
-static PyObject *
-unicode_rpartition(PyObject *self, PyObject *args)
-{
-    PyObject *s;
-    PyObject *sep;
-
-    if (!PyArg_ParseTuple(args, "OO", &s, &sep))
-        return NULL;
-
-    NULLABLE(s);
-    NULLABLE(sep);
-    return PyUnicode_RPartition(s, sep);
-}
-
-/* Test PyUnicode_Translate() */
-static PyObject *
-unicode_translate(PyObject *self, PyObject *args)
-{
-    PyObject *obj;
-    PyObject *table;
-    const char *errors = NULL;
-
-    if (!PyArg_ParseTuple(args, "OO|z", &obj, &table, &errors))
-        return NULL;
-
-    NULLABLE(obj);
-    NULLABLE(table);
-    return PyUnicode_Translate(obj, table, errors);
-}
-
-/* Test PyUnicode_Join() */
-static PyObject *
-unicode_join(PyObject *self, PyObject *args)
-{
-    PyObject *sep;
-    PyObject *seq;
-
-    if (!PyArg_ParseTuple(args, "OO", &sep, &seq))
-        return NULL;
-
-    NULLABLE(sep);
-    NULLABLE(seq);
-    return PyUnicode_Join(sep, seq);
-}
-
-/* Test PyUnicode_Count() */
-static PyObject *
-unicode_count(PyObject *self, PyObject *args)
-{
-    PyObject *str;
-    PyObject *substr;
-    Py_ssize_t start;
-    Py_ssize_t end;
-
-    if (!PyArg_ParseTuple(args, "OOnn", &str, &substr, &start, &end))
-        return NULL;
-
-    NULLABLE(str);
-    NULLABLE(substr);
-    RETURN_SIZE(PyUnicode_Count(str, substr, start, end));
-}
-
-/* Test PyUnicode_Find() */
-static PyObject *
-unicode_find(PyObject *self, PyObject *args)
-{
-    PyObject *str;
-    PyObject *substr;
-    Py_ssize_t start;
-    Py_ssize_t end;
-    int direction;
-    Py_ssize_t result;
-
-    if (!PyArg_ParseTuple(args, "OOnni", &str, &substr, &start, &end, &direction))
-        return NULL;
-
-    NULLABLE(str);
-    NULLABLE(substr);
-    result = PyUnicode_Find(str, substr, start, end, direction);
-    if (result == -2) {
-        assert(PyErr_Occurred());
-        return NULL;
-    }
-    assert(!PyErr_Occurred());
-    return PyLong_FromSsize_t(result);
-}
-
-/* Test PyUnicode_Tailmatch() */
-static PyObject *
-unicode_tailmatch(PyObject *self, PyObject *args)
-{
-    PyObject *str;
-    PyObject *substr;
-    Py_ssize_t start;
-    Py_ssize_t end;
-    int direction;
-
-    if (!PyArg_ParseTuple(args, "OOnni", &str, &substr, &start, &end, &direction))
-        return NULL;
-
-    NULLABLE(str);
-    NULLABLE(substr);
-    RETURN_SIZE(PyUnicode_Tailmatch(str, substr, start, end, direction));
-}
-
-/* Test PyUnicode_FindChar() */
-static PyObject *
-unicode_findchar(PyObject *self, PyObject *args)
-{
-    PyObject *str;
-    int direction;
-    unsigned int ch;
-    Py_ssize_t result;
-    Py_ssize_t start, end;
-
-    if (!PyArg_ParseTuple(args, "OInni:unicode_findchar", &str, &ch,
-                          &start, &end, &direction)) {
-        return NULL;
-    }
-    NULLABLE(str);
-    result = PyUnicode_FindChar(str, (Py_UCS4)ch, start, end, direction);
-    if (result == -2) {
-        assert(PyErr_Occurred());
-        return NULL;
-    }
-    assert(!PyErr_Occurred());
-    return PyLong_FromSsize_t(result);
-}
-
-/* Test PyUnicode_Replace() */
-static PyObject *
-unicode_replace(PyObject *self, PyObject *args)
-{
-    PyObject *str;
-    PyObject *substr;
-    PyObject *replstr;
-    Py_ssize_t maxcount = -1;
-
-    if (!PyArg_ParseTuple(args, "OOO|n", &str, &substr, &replstr, &maxcount))
-        return NULL;
-
-    NULLABLE(str);
-    NULLABLE(substr);
-    NULLABLE(replstr);
-    return PyUnicode_Replace(str, substr, replstr, maxcount);
-}
-
-/* Test PyUnicode_Compare() */
-static PyObject *
-unicode_compare(PyObject *self, PyObject *args)
-{
-    PyObject *left;
-    PyObject *right;
-    int result;
-
-    if (!PyArg_ParseTuple(args, "OO", &left, &right))
-        return NULL;
-
-    NULLABLE(left);
-    NULLABLE(right);
-    result = PyUnicode_Compare(left, right);
-    if (result == -1 && PyErr_Occurred()) {
-        return NULL;
-    }
-    assert(!PyErr_Occurred());
-    return PyLong_FromLong(result);
-}
-
-/* Test PyUnicode_CompareWithASCIIString() */
-static PyObject *
-unicode_comparewithasciistring(PyObject *self, PyObject *args)
-{
-    PyObject *left;
-    const char *right = NULL;
-    Py_ssize_t right_len;
-    int result;
-
-    if (!PyArg_ParseTuple(args, "O|y#", &left, &right, &right_len))
-        return NULL;
-
-    NULLABLE(left);
-    result = PyUnicode_CompareWithASCIIString(left, right);
-    if (result == -1 && PyErr_Occurred()) {
-        return NULL;
-    }
-    return PyLong_FromLong(result);
-}
-
-/* Test PyUnicode_EqualToUTF8() */
-static PyObject *
-unicode_equaltoutf8(PyObject *self, PyObject *args)
-{
-    PyObject *left;
-    const char *right = NULL;
-    Py_ssize_t right_len;
-    int result;
-
-    if (!PyArg_ParseTuple(args, "Oz#", &left, &right, &right_len)) {
-        return NULL;
-    }
-
-    NULLABLE(left);
-    result = PyUnicode_EqualToUTF8(left, right);
-    assert(!PyErr_Occurred());
-    return PyLong_FromLong(result);
-}
-
-/* Test PyUnicode_EqualToUTF8AndSize() */
-static PyObject *
-unicode_equaltoutf8andsize(PyObject *self, PyObject *args)
-{
-    PyObject *left;
-    const char *right = NULL;
-    Py_ssize_t right_len;
-    Py_ssize_t size = -100;
-    int result;
-
-    if (!PyArg_ParseTuple(args, "Oz#|n", &left, &right, &right_len, &size)) {
-        return NULL;
-    }
-
-    NULLABLE(left);
-    if (size == -100) {
-        size = right_len;
-    }
-    result = PyUnicode_EqualToUTF8AndSize(left, right, size);
-    assert(!PyErr_Occurred());
-    return PyLong_FromLong(result);
-}
-
-/* Test PyUnicode_RichCompare() */
-static PyObject *
-unicode_richcompare(PyObject *self, PyObject *args)
-{
-    PyObject *left;
-    PyObject *right;
-    int op;
-
-    if (!PyArg_ParseTuple(args, "OOi", &left, &right, &op))
-        return NULL;
-
-    NULLABLE(left);
-    NULLABLE(right);
-    return PyUnicode_RichCompare(left, right, op);
-}
-
-/* Test PyUnicode_Format() */
-static PyObject *
-unicode_format(PyObject *self, PyObject *args)
-{
-    PyObject *format;
-    PyObject *fargs;
-
-    if (!PyArg_ParseTuple(args, "OO", &format, &fargs))
-        return NULL;
-
-    NULLABLE(format);
-    NULLABLE(fargs);
-    return PyUnicode_Format(format, fargs);
-}
-
-/* Test PyUnicode_Contains() */
-static PyObject *
-unicode_contains(PyObject *self, PyObject *args)
-{
-    PyObject *container;
-    PyObject *element;
-
-    if (!PyArg_ParseTuple(args, "OO", &container, &element))
-        return NULL;
-
-    NULLABLE(container);
-    NULLABLE(element);
-    RETURN_INT(PyUnicode_Contains(container, element));
-}
-
-/* Test PyUnicode_IsIdentifier() */
-static PyObject *
-unicode_isidentifier(PyObject *self, PyObject *arg)
-{
-    NULLABLE(arg);
-    RETURN_INT(PyUnicode_IsIdentifier(arg));
-}
 
 /* Test PyUnicode_CopyCharacters() */
 static PyObject *
@@ -1555,541 +220,14 @@ unicode_copycharacters(PyObject *self, PyObject *args)
     return Py_BuildValue("(Nn)", to_copy, copied);
 }
 
-static int
-check_raised_systemerror(PyObject *result, char* msg)
-{
-    if (result) {
-        // no exception
-        PyErr_Format(PyExc_AssertionError,
-                     "SystemError not raised: %s",
-                     msg);
-        return 0;
-    }
-    if (PyErr_ExceptionMatches(PyExc_SystemError)) {
-        // expected exception
-        PyErr_Clear();
-        return 1;
-    }
-    // unexpected exception
-    return 0;
-}
-
-static PyObject *
-test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    PyObject *result;
-    PyObject *unicode = PyUnicode_FromString("None");
-
-#define CHECK_FORMAT_2(FORMAT, EXPECTED, ARG1, ARG2)                \
-    result = PyUnicode_FromFormat(FORMAT, ARG1, ARG2);              \
-    if (EXPECTED == NULL) {                                         \
-        if (!check_raised_systemerror(result, FORMAT)) {            \
-            goto Fail;                                              \
-        }                                                           \
-    }                                                               \
-    else if (result == NULL)                                        \
-        return NULL;                                                \
-    else if (PyUnicode_CompareWithASCIIString(result, EXPECTED) != 0) { \
-        PyErr_Format(PyExc_AssertionError,                          \
-                     "test_string_from_format: failed at \"%s\" "   \
-                     "expected \"%s\" got \"%s\"",                  \
-                     FORMAT, EXPECTED, PyUnicode_AsUTF8(result));   \
-        goto Fail;                                                  \
-    }                                                               \
-    Py_XDECREF(result)
-
-#define CHECK_FORMAT_1(FORMAT, EXPECTED, ARG)                       \
-    CHECK_FORMAT_2(FORMAT, EXPECTED, ARG, 0)
-
-#define CHECK_FORMAT_0(FORMAT, EXPECTED)                            \
-    CHECK_FORMAT_2(FORMAT, EXPECTED, 0, 0)
-
-    // Unrecognized
-    CHECK_FORMAT_2("%u %? %u", NULL, 1, 2);
-
-    // "%%" (options are rejected)
-    CHECK_FORMAT_0(  "%%", "%");
-    CHECK_FORMAT_0( "%0%", NULL);
-    CHECK_FORMAT_0("%00%", NULL);
-    CHECK_FORMAT_0( "%2%", NULL);
-    CHECK_FORMAT_0("%02%", NULL);
-    CHECK_FORMAT_0("%.0%", NULL);
-    CHECK_FORMAT_0("%.2%", NULL);
-
-    // "%c"
-    CHECK_FORMAT_1(  "%c", "c", 'c');
-    CHECK_FORMAT_1( "%0c", "c", 'c');
-    CHECK_FORMAT_1("%00c", "c", 'c');
-    CHECK_FORMAT_1( "%2c", NULL, 'c');
-    CHECK_FORMAT_1("%02c", NULL, 'c');
-    CHECK_FORMAT_1("%.0c", NULL, 'c');
-    CHECK_FORMAT_1("%.2c", NULL, 'c');
-
-    // Integers
-    CHECK_FORMAT_1("%d",             "123",                (int)123);
-    CHECK_FORMAT_1("%i",             "123",                (int)123);
-    CHECK_FORMAT_1("%u",             "123",       (unsigned int)123);
-    CHECK_FORMAT_1("%x",              "7b",       (unsigned int)123);
-    CHECK_FORMAT_1("%X",              "7B",       (unsigned int)123);
-    CHECK_FORMAT_1("%o",             "173",       (unsigned int)123);
-    CHECK_FORMAT_1("%ld",            "123",               (long)123);
-    CHECK_FORMAT_1("%li",            "123",               (long)123);
-    CHECK_FORMAT_1("%lu",            "123",      (unsigned long)123);
-    CHECK_FORMAT_1("%lx",             "7b",      (unsigned long)123);
-    CHECK_FORMAT_1("%lX",             "7B",      (unsigned long)123);
-    CHECK_FORMAT_1("%lo",            "173",      (unsigned long)123);
-    CHECK_FORMAT_1("%lld",           "123",          (long long)123);
-    CHECK_FORMAT_1("%lli",           "123",          (long long)123);
-    CHECK_FORMAT_1("%llu",           "123", (unsigned long long)123);
-    CHECK_FORMAT_1("%llx",            "7b", (unsigned long long)123);
-    CHECK_FORMAT_1("%llX",            "7B", (unsigned long long)123);
-    CHECK_FORMAT_1("%llo",           "173", (unsigned long long)123);
-    CHECK_FORMAT_1("%zd",            "123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%zi",            "123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%zu",            "123",             (size_t)123);
-    CHECK_FORMAT_1("%zx",             "7b",             (size_t)123);
-    CHECK_FORMAT_1("%zX",             "7B",             (size_t)123);
-    CHECK_FORMAT_1("%zo",            "173",             (size_t)123);
-    CHECK_FORMAT_1("%td",            "123",          (ptrdiff_t)123);
-    CHECK_FORMAT_1("%ti",            "123",          (ptrdiff_t)123);
-    CHECK_FORMAT_1("%tu",            "123",          (ptrdiff_t)123);
-    CHECK_FORMAT_1("%tx",             "7b",          (ptrdiff_t)123);
-    CHECK_FORMAT_1("%tX",             "7B",          (ptrdiff_t)123);
-    CHECK_FORMAT_1("%to",            "173",          (ptrdiff_t)123);
-    CHECK_FORMAT_1("%jd",            "123",           (intmax_t)123);
-    CHECK_FORMAT_1("%ji",            "123",           (intmax_t)123);
-    CHECK_FORMAT_1("%ju",            "123",          (uintmax_t)123);
-    CHECK_FORMAT_1("%jx",             "7b",          (uintmax_t)123);
-    CHECK_FORMAT_1("%jX",             "7B",          (uintmax_t)123);
-    CHECK_FORMAT_1("%jo",            "173",          (uintmax_t)123);
-
-    CHECK_FORMAT_1("%d",            "-123",               (int)-123);
-    CHECK_FORMAT_1("%i",            "-123",               (int)-123);
-    CHECK_FORMAT_1("%ld",           "-123",              (long)-123);
-    CHECK_FORMAT_1("%li",           "-123",              (long)-123);
-    CHECK_FORMAT_1("%lld",          "-123",         (long long)-123);
-    CHECK_FORMAT_1("%lli",          "-123",         (long long)-123);
-    CHECK_FORMAT_1("%zd",           "-123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%zi",           "-123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%td",           "-123",         (ptrdiff_t)-123);
-    CHECK_FORMAT_1("%ti",           "-123",         (ptrdiff_t)-123);
-    CHECK_FORMAT_1("%jd",           "-123",          (intmax_t)-123);
-    CHECK_FORMAT_1("%ji",           "-123",          (intmax_t)-123);
-
-    // Integers: width < length
-    CHECK_FORMAT_1("%1d",            "123",                (int)123);
-    CHECK_FORMAT_1("%1i",            "123",                (int)123);
-    CHECK_FORMAT_1("%1u",            "123",       (unsigned int)123);
-    CHECK_FORMAT_1("%1ld",           "123",               (long)123);
-    CHECK_FORMAT_1("%1li",           "123",               (long)123);
-    CHECK_FORMAT_1("%1lu",           "123",      (unsigned long)123);
-    CHECK_FORMAT_1("%1lld",          "123",          (long long)123);
-    CHECK_FORMAT_1("%1lli",          "123",          (long long)123);
-    CHECK_FORMAT_1("%1llu",          "123", (unsigned long long)123);
-    CHECK_FORMAT_1("%1zd",           "123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%1zi",           "123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%1zu",           "123",             (size_t)123);
-    CHECK_FORMAT_1("%1x",             "7b",                (int)123);
-
-    CHECK_FORMAT_1("%1d",           "-123",               (int)-123);
-    CHECK_FORMAT_1("%1i",           "-123",               (int)-123);
-    CHECK_FORMAT_1("%1ld",          "-123",              (long)-123);
-    CHECK_FORMAT_1("%1li",          "-123",              (long)-123);
-    CHECK_FORMAT_1("%1lld",         "-123",         (long long)-123);
-    CHECK_FORMAT_1("%1lli",         "-123",         (long long)-123);
-    CHECK_FORMAT_1("%1zd",          "-123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%1zi",          "-123",        (Py_ssize_t)-123);
-
-    // Integers: width > length
-    CHECK_FORMAT_1("%5d",          "  123",                (int)123);
-    CHECK_FORMAT_1("%5i",          "  123",                (int)123);
-    CHECK_FORMAT_1("%5u",          "  123",       (unsigned int)123);
-    CHECK_FORMAT_1("%5ld",         "  123",               (long)123);
-    CHECK_FORMAT_1("%5li",         "  123",               (long)123);
-    CHECK_FORMAT_1("%5lu",         "  123",      (unsigned long)123);
-    CHECK_FORMAT_1("%5lld",        "  123",          (long long)123);
-    CHECK_FORMAT_1("%5lli",        "  123",          (long long)123);
-    CHECK_FORMAT_1("%5llu",        "  123", (unsigned long long)123);
-    CHECK_FORMAT_1("%5zd",         "  123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%5zi",         "  123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%5zu",         "  123",             (size_t)123);
-    CHECK_FORMAT_1("%5x",          "   7b",                (int)123);
-
-    CHECK_FORMAT_1("%5d",          " -123",               (int)-123);
-    CHECK_FORMAT_1("%5i",          " -123",               (int)-123);
-    CHECK_FORMAT_1("%5ld",         " -123",              (long)-123);
-    CHECK_FORMAT_1("%5li",         " -123",              (long)-123);
-    CHECK_FORMAT_1("%5lld",        " -123",         (long long)-123);
-    CHECK_FORMAT_1("%5lli",        " -123",         (long long)-123);
-    CHECK_FORMAT_1("%5zd",         " -123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%5zi",         " -123",        (Py_ssize_t)-123);
-
-    // Integers: width > length, 0-flag
-    CHECK_FORMAT_1("%05d",         "00123",                (int)123);
-    CHECK_FORMAT_1("%05i",         "00123",                (int)123);
-    CHECK_FORMAT_1("%05u",         "00123",       (unsigned int)123);
-    CHECK_FORMAT_1("%05ld",        "00123",               (long)123);
-    CHECK_FORMAT_1("%05li",        "00123",               (long)123);
-    CHECK_FORMAT_1("%05lu",        "00123",      (unsigned long)123);
-    CHECK_FORMAT_1("%05lld",       "00123",          (long long)123);
-    CHECK_FORMAT_1("%05lli",       "00123",          (long long)123);
-    CHECK_FORMAT_1("%05llu",       "00123", (unsigned long long)123);
-    CHECK_FORMAT_1("%05zd",        "00123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%05zi",        "00123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%05zu",        "00123",             (size_t)123);
-    CHECK_FORMAT_1("%05x",         "0007b",                (int)123);
-
-    CHECK_FORMAT_1("%05d",         "-0123",               (int)-123);
-    CHECK_FORMAT_1("%05i",         "-0123",               (int)-123);
-    CHECK_FORMAT_1("%05ld",        "-0123",              (long)-123);
-    CHECK_FORMAT_1("%05li",        "-0123",              (long)-123);
-    CHECK_FORMAT_1("%05lld",       "-0123",         (long long)-123);
-    CHECK_FORMAT_1("%05lli",       "-0123",         (long long)-123);
-    CHECK_FORMAT_1("%05zd",        "-0123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%05zi",        "-0123",        (Py_ssize_t)-123);
-
-    // Integers: precision < length
-    CHECK_FORMAT_1("%.1d",           "123",                (int)123);
-    CHECK_FORMAT_1("%.1i",           "123",                (int)123);
-    CHECK_FORMAT_1("%.1u",           "123",       (unsigned int)123);
-    CHECK_FORMAT_1("%.1ld",          "123",               (long)123);
-    CHECK_FORMAT_1("%.1li",          "123",               (long)123);
-    CHECK_FORMAT_1("%.1lu",          "123",      (unsigned long)123);
-    CHECK_FORMAT_1("%.1lld",         "123",          (long long)123);
-    CHECK_FORMAT_1("%.1lli",         "123",          (long long)123);
-    CHECK_FORMAT_1("%.1llu",         "123", (unsigned long long)123);
-    CHECK_FORMAT_1("%.1zd",          "123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%.1zi",          "123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%.1zu",          "123",             (size_t)123);
-    CHECK_FORMAT_1("%.1x",            "7b",                (int)123);
-
-    CHECK_FORMAT_1("%.1d",          "-123",               (int)-123);
-    CHECK_FORMAT_1("%.1i",          "-123",               (int)-123);
-    CHECK_FORMAT_1("%.1ld",         "-123",              (long)-123);
-    CHECK_FORMAT_1("%.1li",         "-123",              (long)-123);
-    CHECK_FORMAT_1("%.1lld",        "-123",         (long long)-123);
-    CHECK_FORMAT_1("%.1lli",        "-123",         (long long)-123);
-    CHECK_FORMAT_1("%.1zd",         "-123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%.1zi",         "-123",        (Py_ssize_t)-123);
-
-    // Integers: precision > length
-    CHECK_FORMAT_1("%.5d",         "00123",                (int)123);
-    CHECK_FORMAT_1("%.5i",         "00123",                (int)123);
-    CHECK_FORMAT_1("%.5u",         "00123",       (unsigned int)123);
-    CHECK_FORMAT_1("%.5ld",        "00123",               (long)123);
-    CHECK_FORMAT_1("%.5li",        "00123",               (long)123);
-    CHECK_FORMAT_1("%.5lu",        "00123",      (unsigned long)123);
-    CHECK_FORMAT_1("%.5lld",       "00123",          (long long)123);
-    CHECK_FORMAT_1("%.5lli",       "00123",          (long long)123);
-    CHECK_FORMAT_1("%.5llu",       "00123", (unsigned long long)123);
-    CHECK_FORMAT_1("%.5zd",        "00123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%.5zi",        "00123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%.5zu",        "00123",             (size_t)123);
-    CHECK_FORMAT_1("%.5x",         "0007b",                (int)123);
-
-    CHECK_FORMAT_1("%.5d",        "-00123",               (int)-123);
-    CHECK_FORMAT_1("%.5i",        "-00123",               (int)-123);
-    CHECK_FORMAT_1("%.5ld",       "-00123",              (long)-123);
-    CHECK_FORMAT_1("%.5li",       "-00123",              (long)-123);
-    CHECK_FORMAT_1("%.5lld",      "-00123",         (long long)-123);
-    CHECK_FORMAT_1("%.5lli",      "-00123",         (long long)-123);
-    CHECK_FORMAT_1("%.5zd",       "-00123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%.5zi",       "-00123",        (Py_ssize_t)-123);
-
-    // Integers: width > precision > length
-    CHECK_FORMAT_1("%7.5d",      "  00123",                (int)123);
-    CHECK_FORMAT_1("%7.5i",      "  00123",                (int)123);
-    CHECK_FORMAT_1("%7.5u",      "  00123",       (unsigned int)123);
-    CHECK_FORMAT_1("%7.5ld",     "  00123",               (long)123);
-    CHECK_FORMAT_1("%7.5li",     "  00123",               (long)123);
-    CHECK_FORMAT_1("%7.5lu",     "  00123",      (unsigned long)123);
-    CHECK_FORMAT_1("%7.5lld",    "  00123",          (long long)123);
-    CHECK_FORMAT_1("%7.5lli",    "  00123",          (long long)123);
-    CHECK_FORMAT_1("%7.5llu",    "  00123", (unsigned long long)123);
-    CHECK_FORMAT_1("%7.5zd",     "  00123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%7.5zi",     "  00123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%7.5zu",     "  00123",             (size_t)123);
-    CHECK_FORMAT_1("%7.5x",      "  0007b",                (int)123);
-
-    CHECK_FORMAT_1("%7.5d",      " -00123",               (int)-123);
-    CHECK_FORMAT_1("%7.5i",      " -00123",               (int)-123);
-    CHECK_FORMAT_1("%7.5ld",     " -00123",              (long)-123);
-    CHECK_FORMAT_1("%7.5li",     " -00123",              (long)-123);
-    CHECK_FORMAT_1("%7.5lld",    " -00123",         (long long)-123);
-    CHECK_FORMAT_1("%7.5lli",    " -00123",         (long long)-123);
-    CHECK_FORMAT_1("%7.5zd",     " -00123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%7.5zi",     " -00123",        (Py_ssize_t)-123);
-
-    // Integers: width > precision > length, 0-flag
-    CHECK_FORMAT_1("%07.5d",     "0000123",                (int)123);
-    CHECK_FORMAT_1("%07.5i",     "0000123",                (int)123);
-    CHECK_FORMAT_1("%07.5u",     "0000123",       (unsigned int)123);
-    CHECK_FORMAT_1("%07.5ld",    "0000123",               (long)123);
-    CHECK_FORMAT_1("%07.5li",    "0000123",               (long)123);
-    CHECK_FORMAT_1("%07.5lu",    "0000123",      (unsigned long)123);
-    CHECK_FORMAT_1("%07.5lld",   "0000123",          (long long)123);
-    CHECK_FORMAT_1("%07.5lli",   "0000123",          (long long)123);
-    CHECK_FORMAT_1("%07.5llu",   "0000123", (unsigned long long)123);
-    CHECK_FORMAT_1("%07.5zd",    "0000123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%07.5zi",    "0000123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%07.5zu",    "0000123",             (size_t)123);
-    CHECK_FORMAT_1("%07.5x",     "000007b",                (int)123);
-
-    CHECK_FORMAT_1("%07.5d",     "-000123",               (int)-123);
-    CHECK_FORMAT_1("%07.5i",     "-000123",               (int)-123);
-    CHECK_FORMAT_1("%07.5ld",    "-000123",              (long)-123);
-    CHECK_FORMAT_1("%07.5li",    "-000123",              (long)-123);
-    CHECK_FORMAT_1("%07.5lld",   "-000123",         (long long)-123);
-    CHECK_FORMAT_1("%07.5lli",   "-000123",         (long long)-123);
-    CHECK_FORMAT_1("%07.5zd",    "-000123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%07.5zi",    "-000123",        (Py_ssize_t)-123);
-
-    // Integers: precision > width > length
-    CHECK_FORMAT_1("%5.7d",      "0000123",                (int)123);
-    CHECK_FORMAT_1("%5.7i",      "0000123",                (int)123);
-    CHECK_FORMAT_1("%5.7u",      "0000123",       (unsigned int)123);
-    CHECK_FORMAT_1("%5.7ld",     "0000123",               (long)123);
-    CHECK_FORMAT_1("%5.7li",     "0000123",               (long)123);
-    CHECK_FORMAT_1("%5.7lu",     "0000123",      (unsigned long)123);
-    CHECK_FORMAT_1("%5.7lld",    "0000123",          (long long)123);
-    CHECK_FORMAT_1("%5.7lli",    "0000123",          (long long)123);
-    CHECK_FORMAT_1("%5.7llu",    "0000123", (unsigned long long)123);
-    CHECK_FORMAT_1("%5.7zd",     "0000123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%5.7zi",     "0000123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%5.7zu",     "0000123",             (size_t)123);
-    CHECK_FORMAT_1("%5.7x",      "000007b",                (int)123);
-
-    CHECK_FORMAT_1("%5.7d",     "-0000123",               (int)-123);
-    CHECK_FORMAT_1("%5.7i",     "-0000123",               (int)-123);
-    CHECK_FORMAT_1("%5.7ld",    "-0000123",              (long)-123);
-    CHECK_FORMAT_1("%5.7li",    "-0000123",              (long)-123);
-    CHECK_FORMAT_1("%5.7lld",   "-0000123",         (long long)-123);
-    CHECK_FORMAT_1("%5.7lli",   "-0000123",         (long long)-123);
-    CHECK_FORMAT_1("%5.7zd",    "-0000123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%5.7zi",    "-0000123",        (Py_ssize_t)-123);
-
-    // Integers: precision > width > length, 0-flag
-    CHECK_FORMAT_1("%05.7d",     "0000123",                (int)123);
-    CHECK_FORMAT_1("%05.7i",     "0000123",                (int)123);
-    CHECK_FORMAT_1("%05.7u",     "0000123",       (unsigned int)123);
-    CHECK_FORMAT_1("%05.7ld",    "0000123",               (long)123);
-    CHECK_FORMAT_1("%05.7li",    "0000123",               (long)123);
-    CHECK_FORMAT_1("%05.7lu",    "0000123",      (unsigned long)123);
-    CHECK_FORMAT_1("%05.7lld",   "0000123",          (long long)123);
-    CHECK_FORMAT_1("%05.7lli",   "0000123",          (long long)123);
-    CHECK_FORMAT_1("%05.7llu",   "0000123", (unsigned long long)123);
-    CHECK_FORMAT_1("%05.7zd",    "0000123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%05.7zi",    "0000123",         (Py_ssize_t)123);
-    CHECK_FORMAT_1("%05.7zu",    "0000123",             (size_t)123);
-    CHECK_FORMAT_1("%05.7x",     "000007b",                (int)123);
-
-    CHECK_FORMAT_1("%05.7d",    "-0000123",               (int)-123);
-    CHECK_FORMAT_1("%05.7i",    "-0000123",               (int)-123);
-    CHECK_FORMAT_1("%05.7ld",   "-0000123",              (long)-123);
-    CHECK_FORMAT_1("%05.7li",   "-0000123",              (long)-123);
-    CHECK_FORMAT_1("%05.7lld",  "-0000123",         (long long)-123);
-    CHECK_FORMAT_1("%05.7lli",  "-0000123",         (long long)-123);
-    CHECK_FORMAT_1("%05.7zd",   "-0000123",        (Py_ssize_t)-123);
-    CHECK_FORMAT_1("%05.7zi",   "-0000123",        (Py_ssize_t)-123);
-
-    // Integers: precision = 0, arg = 0 (empty string in C)
-    CHECK_FORMAT_1("%.0d",             "0",                  (int)0);
-    CHECK_FORMAT_1("%.0i",             "0",                  (int)0);
-    CHECK_FORMAT_1("%.0u",             "0",         (unsigned int)0);
-    CHECK_FORMAT_1("%.0ld",            "0",                 (long)0);
-    CHECK_FORMAT_1("%.0li",            "0",                 (long)0);
-    CHECK_FORMAT_1("%.0lu",            "0",        (unsigned long)0);
-    CHECK_FORMAT_1("%.0lld",           "0",            (long long)0);
-    CHECK_FORMAT_1("%.0lli",           "0",            (long long)0);
-    CHECK_FORMAT_1("%.0llu",           "0",   (unsigned long long)0);
-    CHECK_FORMAT_1("%.0zd",            "0",           (Py_ssize_t)0);
-    CHECK_FORMAT_1("%.0zi",            "0",           (Py_ssize_t)0);
-    CHECK_FORMAT_1("%.0zu",            "0",               (size_t)0);
-    CHECK_FORMAT_1("%.0x",             "0",                  (int)0);
-
-    // Strings
-    CHECK_FORMAT_1("%s",     "None",  "None");
-    CHECK_FORMAT_1("%ls",    "None", L"None");
-    CHECK_FORMAT_1("%U",     "None", unicode);
-    CHECK_FORMAT_1("%A",     "None", Py_None);
-    CHECK_FORMAT_1("%S",     "None", Py_None);
-    CHECK_FORMAT_1("%R",     "None", Py_None);
-    CHECK_FORMAT_2("%V",     "None", unicode, "ignored");
-    CHECK_FORMAT_2("%V",     "None",    NULL,    "None");
-    CHECK_FORMAT_2("%lV",    "None",    NULL,   L"None");
-
-    // Strings: width < length
-    CHECK_FORMAT_1("%1s",    "None",  "None");
-    CHECK_FORMAT_1("%1ls",   "None", L"None");
-    CHECK_FORMAT_1("%1U",    "None", unicode);
-    CHECK_FORMAT_1("%1A",    "None", Py_None);
-    CHECK_FORMAT_1("%1S",    "None", Py_None);
-    CHECK_FORMAT_1("%1R",    "None", Py_None);
-    CHECK_FORMAT_2("%1V",    "None", unicode, "ignored");
-    CHECK_FORMAT_2("%1V",    "None",    NULL,    "None");
-    CHECK_FORMAT_2("%1lV",   "None",    NULL,    L"None");
-
-    // Strings: width > length
-    CHECK_FORMAT_1("%5s",   " None",  "None");
-    CHECK_FORMAT_1("%5ls",  " None", L"None");
-    CHECK_FORMAT_1("%5U",   " None", unicode);
-    CHECK_FORMAT_1("%5A",   " None", Py_None);
-    CHECK_FORMAT_1("%5S",   " None", Py_None);
-    CHECK_FORMAT_1("%5R",   " None", Py_None);
-    CHECK_FORMAT_2("%5V",   " None", unicode, "ignored");
-    CHECK_FORMAT_2("%5V",   " None",    NULL,    "None");
-    CHECK_FORMAT_2("%5lV",  " None",    NULL,   L"None");
-
-    // Strings: precision < length
-    CHECK_FORMAT_1("%.1s",      "N",  "None");
-    CHECK_FORMAT_1("%.1ls",     "N", L"None");
-    CHECK_FORMAT_1("%.1U",      "N", unicode);
-    CHECK_FORMAT_1("%.1A",      "N", Py_None);
-    CHECK_FORMAT_1("%.1S",      "N", Py_None);
-    CHECK_FORMAT_1("%.1R",      "N", Py_None);
-    CHECK_FORMAT_2("%.1V",      "N", unicode, "ignored");
-    CHECK_FORMAT_2("%.1V",      "N",    NULL,    "None");
-    CHECK_FORMAT_2("%.1lV",     "N",    NULL,   L"None");
-
-    // Strings: precision > length
-    CHECK_FORMAT_1("%.5s",   "None",  "None");
-    CHECK_FORMAT_1("%.5ls",  "None", L"None");
-    CHECK_FORMAT_1("%.5U",   "None", unicode);
-    CHECK_FORMAT_1("%.5A",   "None", Py_None);
-    CHECK_FORMAT_1("%.5S",   "None", Py_None);
-    CHECK_FORMAT_1("%.5R",   "None", Py_None);
-    CHECK_FORMAT_2("%.5V",   "None", unicode, "ignored");
-    CHECK_FORMAT_2("%.5V",   "None",    NULL,    "None");
-    CHECK_FORMAT_2("%.5lV",  "None",    NULL,   L"None");
-
-    // Strings: precision < length, width > length
-    CHECK_FORMAT_1("%5.1s", "    N",  "None");
-    CHECK_FORMAT_1("%5.1ls","    N", L"None");
-    CHECK_FORMAT_1("%5.1U", "    N", unicode);
-    CHECK_FORMAT_1("%5.1A", "    N", Py_None);
-    CHECK_FORMAT_1("%5.1S", "    N", Py_None);
-    CHECK_FORMAT_1("%5.1R", "    N", Py_None);
-    CHECK_FORMAT_2("%5.1V", "    N", unicode, "ignored");
-    CHECK_FORMAT_2("%5.1V", "    N",    NULL,    "None");
-    CHECK_FORMAT_2("%5.1lV","    N",    NULL,   L"None");
-
-    // Strings: width < length, precision > length
-    CHECK_FORMAT_1("%1.5s",  "None",  "None");
-    CHECK_FORMAT_1("%1.5ls", "None",  L"None");
-    CHECK_FORMAT_1("%1.5U",  "None", unicode);
-    CHECK_FORMAT_1("%1.5A",  "None", Py_None);
-    CHECK_FORMAT_1("%1.5S",  "None", Py_None);
-    CHECK_FORMAT_1("%1.5R",  "None", Py_None);
-    CHECK_FORMAT_2("%1.5V",  "None", unicode, "ignored");
-    CHECK_FORMAT_2("%1.5V",  "None",    NULL,    "None");
-    CHECK_FORMAT_2("%1.5lV", "None",    NULL,   L"None");
-
-    Py_XDECREF(unicode);
-    Py_RETURN_NONE;
-
- Fail:
-    Py_XDECREF(result);
-    Py_XDECREF(unicode);
-    return NULL;
-
-#undef CHECK_FORMAT_2
-#undef CHECK_FORMAT_1
-#undef CHECK_FORMAT_0
-}
 
 static PyMethodDef TestMethods[] = {
-    {"codec_incrementalencoder", codec_incrementalencoder,       METH_VARARGS},
-    {"codec_incrementaldecoder", codec_incrementaldecoder,       METH_VARARGS},
-    {"test_unicode_compare_with_ascii",
-     test_unicode_compare_with_ascii,                            METH_NOARGS},
-    {"test_string_from_format",  test_string_from_format,        METH_NOARGS},
-    {"test_widechar",            test_widechar,                  METH_NOARGS},
     {"unicode_new",              unicode_new,                    METH_VARARGS},
     {"unicode_fill",             unicode_fill,                   METH_VARARGS},
-    {"unicode_writechar",        unicode_writechar,              METH_VARARGS},
-    {"unicode_resize",           unicode_resize,                 METH_VARARGS},
-    {"unicode_append",           unicode_append,                 METH_VARARGS},
-    {"unicode_appendanddel",     unicode_appendanddel,           METH_VARARGS},
-    {"unicode_fromstringandsize",unicode_fromstringandsize,      METH_VARARGS},
-    {"unicode_fromstring",       unicode_fromstring,             METH_O},
     {"unicode_fromkindanddata",  unicode_fromkindanddata,        METH_VARARGS},
-    {"unicode_substring",        unicode_substring,              METH_VARARGS},
-    {"unicode_getlength",        unicode_getlength,              METH_O},
-    {"unicode_readchar",         unicode_readchar,               METH_VARARGS},
-    {"unicode_fromencodedobject",unicode_fromencodedobject,      METH_VARARGS},
-    {"unicode_fromobject",       unicode_fromobject,             METH_O},
-    {"unicode_interninplace",    unicode_interninplace,          METH_O},
-    {"unicode_internfromstring", unicode_internfromstring,       METH_O},
-    {"unicode_fromwidechar",     unicode_fromwidechar,           METH_VARARGS},
-    {"unicode_aswidechar",       unicode_aswidechar,             METH_VARARGS},
-    {"unicode_aswidechar_null",  unicode_aswidechar_null,        METH_VARARGS},
-    {"unicode_aswidecharstring", unicode_aswidecharstring,       METH_VARARGS},
-    {"unicode_aswidecharstring_null",unicode_aswidecharstring_null,METH_VARARGS},
     {"unicode_asucs4",           unicode_asucs4,                 METH_VARARGS},
     {"unicode_asucs4copy",       unicode_asucs4copy,             METH_VARARGS},
-    {"unicode_fromordinal",      unicode_fromordinal,            METH_VARARGS},
     {"unicode_asutf8",           unicode_asutf8,                 METH_VARARGS},
-    {"unicode_asutf8andsize",    unicode_asutf8andsize,          METH_VARARGS},
-    {"unicode_asutf8andsize_null",unicode_asutf8andsize_null,    METH_VARARGS},
-    {"unicode_getdefaultencoding",unicode_getdefaultencoding,    METH_NOARGS},
-    {"unicode_decode",           unicode_decode,                 METH_VARARGS},
-    {"unicode_asencodedstring",  unicode_asencodedstring,        METH_VARARGS},
-    {"unicode_buildencodingmap", unicode_buildencodingmap,       METH_O},
-    {"unicode_decodeutf7",       unicode_decodeutf7,             METH_VARARGS},
-    {"unicode_decodeutf7stateful",unicode_decodeutf7stateful,    METH_VARARGS},
-    {"unicode_decodeutf8",       unicode_decodeutf8,             METH_VARARGS},
-    {"unicode_decodeutf8stateful",unicode_decodeutf8stateful,    METH_VARARGS},
-    {"unicode_asutf8string",     unicode_asutf8string,           METH_O},
-    {"unicode_decodeutf16",      unicode_decodeutf16,            METH_VARARGS},
-    {"unicode_decodeutf16stateful",unicode_decodeutf16stateful,  METH_VARARGS},
-    {"unicode_asutf16string",    unicode_asutf16string,          METH_O},
-    {"unicode_decodeutf32",      unicode_decodeutf32,            METH_VARARGS},
-    {"unicode_decodeutf32stateful",unicode_decodeutf32stateful,  METH_VARARGS},
-    {"unicode_asutf32string",    unicode_asutf32string,          METH_O},
-    {"unicode_decodeunicodeescape",unicode_decodeunicodeescape,  METH_VARARGS},
-    {"unicode_asunicodeescapestring",unicode_asunicodeescapestring,METH_O},
-    {"unicode_decoderawunicodeescape",unicode_decoderawunicodeescape,METH_VARARGS},
-    {"unicode_asrawunicodeescapestring",unicode_asrawunicodeescapestring,METH_O},
-    {"unicode_decodelatin1",     unicode_decodelatin1,           METH_VARARGS},
-    {"unicode_aslatin1string",   unicode_aslatin1string,         METH_O},
-    {"unicode_decodeascii",      unicode_decodeascii,            METH_VARARGS},
-    {"unicode_asasciistring",    unicode_asasciistring,          METH_O},
-    {"unicode_decodecharmap",    unicode_decodecharmap,          METH_VARARGS},
-    {"unicode_ascharmapstring",  unicode_ascharmapstring,        METH_VARARGS},
-#ifdef MS_WINDOWS
-    {"unicode_decodembcs",       unicode_decodembcs,             METH_VARARGS},
-    {"unicode_decodembcsstateful",unicode_decodembcsstateful,    METH_VARARGS},
-    {"unicode_decodecodepagestateful",unicode_decodecodepagestateful,METH_VARARGS},
-    {"unicode_asmbcsstring",     unicode_asmbcsstring,           METH_O},
-    {"unicode_encodecodepage",   unicode_encodecodepage,         METH_VARARGS},
-#endif /* MS_WINDOWS */
-    {"unicode_decodelocaleandsize",unicode_decodelocaleandsize,  METH_VARARGS},
-    {"unicode_decodelocale",     unicode_decodelocale,           METH_VARARGS},
-    {"unicode_encodelocale",     unicode_encodelocale,           METH_VARARGS},
-    {"unicode_decodefsdefault",  unicode_decodefsdefault,        METH_VARARGS},
-    {"unicode_decodefsdefaultandsize",unicode_decodefsdefaultandsize,METH_VARARGS},
-    {"unicode_encodefsdefault",  unicode_encodefsdefault,        METH_O},
-    {"unicode_concat",           unicode_concat,                 METH_VARARGS},
-    {"unicode_splitlines",       unicode_splitlines,             METH_VARARGS},
-    {"unicode_split",            unicode_split,                  METH_VARARGS},
-    {"unicode_rsplit",           unicode_rsplit,                 METH_VARARGS},
-    {"unicode_partition",        unicode_partition,              METH_VARARGS},
-    {"unicode_rpartition",       unicode_rpartition,             METH_VARARGS},
-    {"unicode_translate",        unicode_translate,              METH_VARARGS},
-    {"unicode_join",             unicode_join,                   METH_VARARGS},
-    {"unicode_count",            unicode_count,                  METH_VARARGS},
-    {"unicode_tailmatch",        unicode_tailmatch,              METH_VARARGS},
-    {"unicode_find",             unicode_find,                   METH_VARARGS},
-    {"unicode_findchar",         unicode_findchar,               METH_VARARGS},
-    {"unicode_replace",          unicode_replace,                METH_VARARGS},
-    {"unicode_compare",          unicode_compare,                METH_VARARGS},
-    {"unicode_comparewithasciistring",unicode_comparewithasciistring,METH_VARARGS},
-    {"unicode_equaltoutf8",      unicode_equaltoutf8,            METH_VARARGS},
-    {"unicode_equaltoutf8andsize",unicode_equaltoutf8andsize,    METH_VARARGS},
-    {"unicode_richcompare",      unicode_richcompare,            METH_VARARGS},
-    {"unicode_format",           unicode_format,                 METH_VARARGS},
-    {"unicode_contains",         unicode_contains,               METH_VARARGS},
-    {"unicode_isidentifier",     unicode_isidentifier,           METH_O},
     {"unicode_copycharacters",   unicode_copycharacters,         METH_VARARGS},
     {NULL},
 };
@@ -2099,6 +237,5 @@ _PyTestCapi_Init_Unicode(PyObject *m) {
     if (PyModule_AddFunctions(m, TestMethods) < 0) {
         return -1;
     }
-
     return 0;
 }
index 756e2fb252f2e217583cb8fe80713270196cc670..c038f7a9e2d1a5f44612e455b6a0f78dcef88214 100644 (file)
@@ -53,6 +53,9 @@ PyInit__testlimitedcapi(void)
     if (_PyTestLimitedCAPI_Init_Sys(mod) < 0) {
         return NULL;
     }
+    if (_PyTestLimitedCAPI_Init_Unicode(mod) < 0) {
+        return NULL;
+    }
     if (_PyTestLimitedCAPI_Init_VectorcallLimited(mod) < 0) {
         return NULL;
     }
index f9865e4be2c4a83dbd8ee00cbfef4db5e3f32d1a..88dc91f682ff39d77527eda48528b5e954ef99a2 100644 (file)
@@ -89,4 +89,3 @@ _PyTestLimitedCAPI_Init_Float(PyObject *mod)
 
     return 0;
 }
-
index 461fe7aa2cc3375f39c458afaed6ac4c50235285..f8b84e9388184e1a0b1fe495c474e71a1d863c99 100644 (file)
@@ -31,6 +31,7 @@ int _PyTestLimitedCAPI_Init_List(PyObject *module);
 int _PyTestLimitedCAPI_Init_PyOS(PyObject *module);
 int _PyTestLimitedCAPI_Init_Set(PyObject *module);
 int _PyTestLimitedCAPI_Init_Sys(PyObject *module);
+int _PyTestLimitedCAPI_Init_Unicode(PyObject *module);
 int _PyTestLimitedCAPI_Init_VectorcallLimited(PyObject *module);
 
 #endif // Py_TESTLIMITEDCAPI_PARTS_H
diff --git a/Modules/_testlimitedcapi/unicode.c b/Modules/_testlimitedcapi/unicode.c
new file mode 100644 (file)
index 0000000..2b70d09
--- /dev/null
@@ -0,0 +1,1938 @@
+#include "pyconfig.h"   // Py_GIL_DISABLED
+#ifndef Py_GIL_DISABLED
+   // Need limited C API 3.13 to test PyUnicode_EqualToUTF8()
+#  define Py_LIMITED_API 0x030d0000
+#endif
+
+#include "parts.h"
+#include "util.h"
+
+#include <stddef.h>               // ptrdiff_t
+#include <string.h>               // memset()
+
+
+static PyObject *
+codec_incrementalencoder(PyObject *self, PyObject *args)
+{
+    const char *encoding, *errors = NULL;
+    if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder",
+                          &encoding, &errors))
+        return NULL;
+    return PyCodec_IncrementalEncoder(encoding, errors);
+}
+
+static PyObject *
+codec_incrementaldecoder(PyObject *self, PyObject *args)
+{
+    const char *encoding, *errors = NULL;
+    if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder",
+                          &encoding, &errors))
+        return NULL;
+    return PyCodec_IncrementalDecoder(encoding, errors);
+}
+
+static PyObject *
+test_unicode_compare_with_ascii(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    PyObject *py_s = PyUnicode_FromStringAndSize("str\0", 4);
+    int result;
+    if (py_s == NULL)
+        return NULL;
+    result = PyUnicode_CompareWithASCIIString(py_s, "str");
+    Py_DECREF(py_s);
+    if (!result) {
+        PyErr_SetString(PyExc_AssertionError, "Python string ending in NULL "
+                        "should not compare equal to c string.");
+        return NULL;
+    }
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4)
+    const wchar_t wtext[2] = {(wchar_t)0x10ABCDu};
+    size_t wtextlen = 1;
+    const wchar_t invalid[1] = {(wchar_t)0x110000u};
+#else
+    const wchar_t wtext[3] = {(wchar_t)0xDBEAu, (wchar_t)0xDFCDu};
+    size_t wtextlen = 2;
+#endif
+    PyObject *wide, *utf8;
+
+    wide = PyUnicode_FromWideChar(wtext, wtextlen);
+    if (wide == NULL)
+        return NULL;
+
+    utf8 = PyUnicode_FromString("\xf4\x8a\xaf\x8d");
+    if (utf8 == NULL) {
+        Py_DECREF(wide);
+        return NULL;
+    }
+
+    if (PyUnicode_GetLength(wide) != PyUnicode_GetLength(utf8)) {
+        Py_DECREF(wide);
+        Py_DECREF(utf8);
+        PyErr_SetString(PyExc_AssertionError,
+                        "test_widechar: "
+                        "wide string and utf8 string "
+                        "have different length");
+        return NULL;
+    }
+    if (PyUnicode_Compare(wide, utf8)) {
+        Py_DECREF(wide);
+        Py_DECREF(utf8);
+        if (PyErr_Occurred())
+            return NULL;
+        PyErr_SetString(PyExc_AssertionError,
+                        "test_widechar: "
+                        "wide string and utf8 string "
+                        "are different");
+        return NULL;
+    }
+
+    Py_DECREF(wide);
+    Py_DECREF(utf8);
+
+#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4)
+    wide = PyUnicode_FromWideChar(invalid, 1);
+    if (wide == NULL)
+        PyErr_Clear();
+    else {
+        PyErr_SetString(PyExc_AssertionError,
+                        "test_widechar: "
+                        "PyUnicode_FromWideChar(L\"\\U00110000\", 1) didn't fail");
+        return NULL;
+    }
+#endif
+    Py_RETURN_NONE;
+}
+
+
+static PyObject *
+unicode_copy(PyObject *unicode)
+{
+    if (!unicode) {
+        return NULL;
+    }
+    if (!PyUnicode_Check(unicode)) {
+        Py_INCREF(unicode);
+        return unicode;
+    }
+
+    // Create a new string by encoding to UTF-8 and then decode from UTF-8
+    PyObject *utf8 = PyUnicode_AsUTF8String(unicode);
+    if (!utf8) {
+        return NULL;
+    }
+
+    PyObject *copy = PyUnicode_DecodeUTF8(
+        PyBytes_AsString(utf8),
+        PyBytes_Size(utf8),
+        NULL);
+    Py_DECREF(utf8);
+
+    return copy;
+}
+
+/* Test PyUnicode_WriteChar() */
+static PyObject *
+unicode_writechar(PyObject *self, PyObject *args)
+{
+    PyObject *to, *to_copy;
+    Py_ssize_t index;
+    unsigned int character;
+    int result;
+
+    if (!PyArg_ParseTuple(args, "OnI", &to, &index, &character)) {
+        return NULL;
+    }
+
+    NULLABLE(to);
+    if (!(to_copy = unicode_copy(to)) && to) {
+        return NULL;
+    }
+
+    result = PyUnicode_WriteChar(to_copy, index, (Py_UCS4)character);
+    if (result == -1 && PyErr_Occurred()) {
+        Py_DECREF(to_copy);
+        return NULL;
+    }
+    return Py_BuildValue("(Ni)", to_copy, result);
+}
+
+static void
+unicode_fill(PyObject *str, Py_ssize_t start, Py_ssize_t end, Py_UCS4 ch)
+{
+    assert(0 <= start);
+    assert(end <= PyUnicode_GetLength(str));
+    for (Py_ssize_t i = start; i < end; i++) {
+        int res = PyUnicode_WriteChar(str, i, ch);
+        assert(res == 0);
+    }
+}
+
+
+/* Test PyUnicode_Resize() */
+static PyObject *
+unicode_resize(PyObject *self, PyObject *args)
+{
+    PyObject *obj, *copy;
+    Py_ssize_t length;
+    int result;
+
+    if (!PyArg_ParseTuple(args, "On", &obj, &length)) {
+        return NULL;
+    }
+
+    NULLABLE(obj);
+    if (!(copy = unicode_copy(obj)) && obj) {
+        return NULL;
+    }
+    result = PyUnicode_Resize(&copy, length);
+    if (result == -1 && PyErr_Occurred()) {
+        Py_XDECREF(copy);
+        return NULL;
+    }
+    if (obj && PyUnicode_Check(obj) && length > PyUnicode_GetLength(obj)) {
+        unicode_fill(copy, PyUnicode_GetLength(obj), length, 0U);
+    }
+    return Py_BuildValue("(Ni)", copy, result);
+}
+
+/* Test PyUnicode_Append() */
+static PyObject *
+unicode_append(PyObject *self, PyObject *args)
+{
+    PyObject *left, *right, *left_copy;
+
+    if (!PyArg_ParseTuple(args, "OO", &left, &right))
+        return NULL;
+
+    NULLABLE(left);
+    NULLABLE(right);
+    if (!(left_copy = unicode_copy(left)) && left) {
+        return NULL;
+    }
+    PyUnicode_Append(&left_copy, right);
+    return left_copy;
+}
+
+/* Test PyUnicode_AppendAndDel() */
+static PyObject *
+unicode_appendanddel(PyObject *self, PyObject *args)
+{
+    PyObject *left, *right, *left_copy;
+
+    if (!PyArg_ParseTuple(args, "OO", &left, &right))
+        return NULL;
+
+    NULLABLE(left);
+    NULLABLE(right);
+    if (!(left_copy = unicode_copy(left)) && left) {
+        return NULL;
+    }
+    Py_XINCREF(right);
+    PyUnicode_AppendAndDel(&left_copy, right);
+    return left_copy;
+}
+
+/* Test PyUnicode_FromStringAndSize() */
+static PyObject *
+unicode_fromstringandsize(PyObject *self, PyObject *args)
+{
+    const char *s;
+    Py_ssize_t bsize;
+    Py_ssize_t size = -100;
+
+    if (!PyArg_ParseTuple(args, "z#|n", &s, &bsize, &size)) {
+        return NULL;
+    }
+
+    if (size == -100) {
+        size = bsize;
+    }
+    return PyUnicode_FromStringAndSize(s, size);
+}
+
+/* Test PyUnicode_FromString() */
+static PyObject *
+unicode_fromstring(PyObject *self, PyObject *arg)
+{
+    const char *s;
+    Py_ssize_t size;
+
+    if (!PyArg_Parse(arg, "z#", &s, &size)) {
+        return NULL;
+    }
+    return PyUnicode_FromString(s);
+}
+
+/* Test PyUnicode_Substring() */
+static PyObject *
+unicode_substring(PyObject *self, PyObject *args)
+{
+    PyObject *str;
+    Py_ssize_t start, end;
+
+    if (!PyArg_ParseTuple(args, "Onn", &str, &start, &end)) {
+        return NULL;
+    }
+
+    NULLABLE(str);
+    return PyUnicode_Substring(str, start, end);
+}
+
+/* Test PyUnicode_GetLength() */
+static PyObject *
+unicode_getlength(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    RETURN_SIZE(PyUnicode_GetLength(arg));
+}
+
+/* Test PyUnicode_ReadChar() */
+static PyObject *
+unicode_readchar(PyObject *self, PyObject *args)
+{
+    PyObject *unicode;
+    Py_ssize_t index;
+    Py_UCS4 result;
+
+    if (!PyArg_ParseTuple(args, "On", &unicode, &index)) {
+        return NULL;
+    }
+
+    NULLABLE(unicode);
+    result = PyUnicode_ReadChar(unicode, index);
+    if (result == (Py_UCS4)-1)
+        return NULL;
+    return PyLong_FromUnsignedLong(result);
+}
+
+/* Test PyUnicode_FromEncodedObject() */
+static PyObject *
+unicode_fromencodedobject(PyObject *self, PyObject *args)
+{
+    PyObject *obj;
+    const char *encoding;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "Oz|z", &obj, &encoding, &errors)) {
+        return NULL;
+    }
+
+    NULLABLE(obj);
+    return PyUnicode_FromEncodedObject(obj, encoding, errors);
+}
+
+/* Test PyUnicode_FromObject() */
+static PyObject *
+unicode_fromobject(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_FromObject(arg);
+}
+
+/* Test PyUnicode_InternInPlace() */
+static PyObject *
+unicode_interninplace(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    Py_XINCREF(arg);
+    PyUnicode_InternInPlace(&arg);
+    return arg;
+}
+
+/* Test PyUnicode_InternFromString() */
+static PyObject *
+unicode_internfromstring(PyObject *self, PyObject *arg)
+{
+    const char *s;
+    Py_ssize_t size;
+
+    if (!PyArg_Parse(arg, "z#", &s, &size)) {
+        return NULL;
+    }
+    return PyUnicode_InternFromString(s);
+}
+
+/* Test PyUnicode_FromWideChar() */
+static PyObject *
+unicode_fromwidechar(PyObject *self, PyObject *args)
+{
+    const char *s;
+    Py_ssize_t bsize;
+    Py_ssize_t size = -100;
+
+    if (!PyArg_ParseTuple(args, "z#|n", &s, &bsize, &size)) {
+        return NULL;
+    }
+    if (size == -100) {
+        if (bsize % SIZEOF_WCHAR_T) {
+            PyErr_SetString(PyExc_AssertionError,
+                            "invalid size in unicode_fromwidechar()");
+            return NULL;
+        }
+        size = bsize / SIZEOF_WCHAR_T;
+    }
+    return PyUnicode_FromWideChar((const wchar_t *)s, size);
+}
+
+/* Test PyUnicode_AsWideChar() */
+static PyObject *
+unicode_aswidechar(PyObject *self, PyObject *args)
+{
+    PyObject *unicode, *result;
+    Py_ssize_t buflen, size;
+    wchar_t *buffer;
+
+    if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
+        return NULL;
+    NULLABLE(unicode);
+    buffer = PyMem_New(wchar_t, buflen);
+    if (buffer == NULL)
+        return PyErr_NoMemory();
+
+    size = PyUnicode_AsWideChar(unicode, buffer, buflen);
+    if (size == -1) {
+        PyMem_Free(buffer);
+        return NULL;
+    }
+
+    if (size < buflen)
+        buflen = size + 1;
+    else
+        buflen = size;
+    result = PyUnicode_FromWideChar(buffer, buflen);
+    PyMem_Free(buffer);
+    if (result == NULL)
+        return NULL;
+
+    return Py_BuildValue("(Nn)", result, size);
+}
+
+/* Test PyUnicode_AsWideCharString() with NULL as buffer */
+static PyObject *
+unicode_aswidechar_null(PyObject *self, PyObject *args)
+{
+    PyObject *unicode;
+    Py_ssize_t buflen;
+
+    if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
+        return NULL;
+    NULLABLE(unicode);
+    RETURN_SIZE(PyUnicode_AsWideChar(unicode, NULL, buflen));
+}
+
+/* Test PyUnicode_AsWideCharString() */
+static PyObject *
+unicode_aswidecharstring(PyObject *self, PyObject *args)
+{
+    PyObject *unicode, *result;
+    Py_ssize_t size = UNINITIALIZED_SIZE;
+    wchar_t *buffer;
+
+    if (!PyArg_ParseTuple(args, "O", &unicode))
+        return NULL;
+
+    NULLABLE(unicode);
+    buffer = PyUnicode_AsWideCharString(unicode, &size);
+    if (buffer == NULL) {
+        assert(size == UNINITIALIZED_SIZE);
+        return NULL;
+    }
+
+    result = PyUnicode_FromWideChar(buffer, size + 1);
+    PyMem_Free(buffer);
+    if (result == NULL)
+        return NULL;
+    return Py_BuildValue("(Nn)", result, size);
+}
+
+/* Test PyUnicode_AsWideCharString() with NULL as the size address */
+static PyObject *
+unicode_aswidecharstring_null(PyObject *self, PyObject *args)
+{
+    PyObject *unicode, *result;
+    wchar_t *buffer;
+
+    if (!PyArg_ParseTuple(args, "O", &unicode))
+        return NULL;
+
+    NULLABLE(unicode);
+    buffer = PyUnicode_AsWideCharString(unicode, NULL);
+    if (buffer == NULL)
+        return NULL;
+
+    result = PyUnicode_FromWideChar(buffer, -1);
+    PyMem_Free(buffer);
+    if (result == NULL)
+        return NULL;
+    return result;
+}
+
+
+/* Test PyUnicode_FromOrdinal() */
+static PyObject *
+unicode_fromordinal(PyObject *self, PyObject *args)
+{
+    int ordinal;
+
+    if (!PyArg_ParseTuple(args, "i", &ordinal))
+        return NULL;
+
+    return PyUnicode_FromOrdinal(ordinal);
+}
+
+/* Test PyUnicode_AsUTF8AndSize() */
+static PyObject *
+unicode_asutf8andsize(PyObject *self, PyObject *args)
+{
+    PyObject *unicode;
+    Py_ssize_t buflen;
+    const char *s;
+    Py_ssize_t size = UNINITIALIZED_SIZE;
+
+    if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
+        return NULL;
+
+    NULLABLE(unicode);
+    s = PyUnicode_AsUTF8AndSize(unicode, &size);
+    if (s == NULL) {
+        assert(size == -1);
+        return NULL;
+    }
+
+    return Py_BuildValue("(y#n)", s, buflen, size);
+}
+
+/* Test PyUnicode_AsUTF8AndSize() with NULL as the size address */
+static PyObject *
+unicode_asutf8andsize_null(PyObject *self, PyObject *args)
+{
+    PyObject *unicode;
+    Py_ssize_t buflen;
+    const char *s;
+
+    if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
+        return NULL;
+
+    NULLABLE(unicode);
+    s = PyUnicode_AsUTF8AndSize(unicode, NULL);
+    if (s == NULL)
+        return NULL;
+
+    return PyBytes_FromStringAndSize(s, buflen);
+}
+
+/* Test PyUnicode_GetDefaultEncoding() */
+static PyObject *
+unicode_getdefaultencoding(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    const char *s = PyUnicode_GetDefaultEncoding();
+    if (s == NULL)
+        return NULL;
+
+    return PyBytes_FromString(s);
+}
+
+/* Test PyUnicode_Decode() */
+static PyObject *
+unicode_decode(PyObject *self, PyObject *args)
+{
+    const char *s;
+    Py_ssize_t size;
+    const char *encoding;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "y#z|z", &s, &size, &encoding, &errors))
+        return NULL;
+
+    return PyUnicode_Decode(s, size, encoding, errors);
+}
+
+/* Test PyUnicode_AsEncodedString() */
+static PyObject *
+unicode_asencodedstring(PyObject *self, PyObject *args)
+{
+    PyObject *unicode;
+    const char *encoding;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "Oz|z", &unicode, &encoding, &errors))
+        return NULL;
+
+    NULLABLE(unicode);
+    return PyUnicode_AsEncodedString(unicode, encoding, errors);
+}
+
+/* Test PyUnicode_BuildEncodingMap() */
+static PyObject *
+unicode_buildencodingmap(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_BuildEncodingMap(arg);
+}
+
+/* Test PyUnicode_DecodeUTF7() */
+static PyObject *
+unicode_decodeutf7(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    return PyUnicode_DecodeUTF7(data, size, errors);
+}
+
+/* Test PyUnicode_DecodeUTF7Stateful() */
+static PyObject *
+unicode_decodeutf7stateful(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    Py_ssize_t consumed = UNINITIALIZED_SIZE;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    result = PyUnicode_DecodeUTF7Stateful(data, size, errors, &consumed);
+    if (!result) {
+        assert(consumed == UNINITIALIZED_SIZE);
+        return NULL;
+    }
+    return Py_BuildValue("(Nn)", result, consumed);
+}
+
+/* Test PyUnicode_DecodeUTF8() */
+static PyObject *
+unicode_decodeutf8(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    return PyUnicode_DecodeUTF8(data, size, errors);
+}
+
+/* Test PyUnicode_DecodeUTF8Stateful() */
+static PyObject *
+unicode_decodeutf8stateful(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    Py_ssize_t consumed = UNINITIALIZED_SIZE;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    result = PyUnicode_DecodeUTF8Stateful(data, size, errors, &consumed);
+    if (!result) {
+        assert(consumed == UNINITIALIZED_SIZE);
+        return NULL;
+    }
+    return Py_BuildValue("(Nn)", result, consumed);
+}
+
+/* Test PyUnicode_AsUTF8String() */
+static PyObject *
+unicode_asutf8string(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_AsUTF8String(arg);
+}
+
+/* Test PyUnicode_DecodeUTF32() */
+static PyObject *
+unicode_decodeutf32(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = UNINITIALIZED_INT;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
+        return NULL;
+
+    result = PyUnicode_DecodeUTF32(data, size, errors, &byteorder);
+    if (!result) {
+        return NULL;
+    }
+    return Py_BuildValue("(iN)", byteorder, result);
+}
+
+/* Test PyUnicode_DecodeUTF32Stateful() */
+static PyObject *
+unicode_decodeutf32stateful(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = UNINITIALIZED_INT;
+    Py_ssize_t consumed = UNINITIALIZED_SIZE;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
+        return NULL;
+
+    result = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder, &consumed);
+    if (!result) {
+        assert(consumed == UNINITIALIZED_SIZE);
+        return NULL;
+    }
+    return Py_BuildValue("(iNn)", byteorder, result, consumed);
+}
+
+/* Test PyUnicode_AsUTF32String() */
+static PyObject *
+unicode_asutf32string(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_AsUTF32String(arg);
+}
+
+/* Test PyUnicode_DecodeUTF16() */
+static PyObject *
+unicode_decodeutf16(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = UNINITIALIZED_INT;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
+        return NULL;
+
+    result = PyUnicode_DecodeUTF16(data, size, errors, &byteorder);
+    if (!result) {
+        return NULL;
+    }
+    return Py_BuildValue("(iN)", byteorder, result);
+}
+
+/* Test PyUnicode_DecodeUTF16Stateful() */
+static PyObject *
+unicode_decodeutf16stateful(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    int byteorder = UNINITIALIZED_INT;
+    Py_ssize_t consumed = UNINITIALIZED_SIZE;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors))
+        return NULL;
+
+    result = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, &consumed);
+    if (!result) {
+        assert(consumed == UNINITIALIZED_SIZE);
+        return NULL;
+    }
+    return Py_BuildValue("(iNn)", byteorder, result, consumed);
+}
+
+/* Test PyUnicode_AsUTF16String() */
+static PyObject *
+unicode_asutf16string(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_AsUTF16String(arg);
+}
+
+/* Test PyUnicode_DecodeUnicodeEscape() */
+static PyObject *
+unicode_decodeunicodeescape(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    return PyUnicode_DecodeUnicodeEscape(data, size, errors);
+}
+
+/* Test PyUnicode_AsUnicodeEscapeString() */
+static PyObject *
+unicode_asunicodeescapestring(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_AsUnicodeEscapeString(arg);
+}
+
+static PyObject *
+unicode_decoderawunicodeescape(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    return PyUnicode_DecodeRawUnicodeEscape(data, size, errors);
+}
+
+/* Test PyUnicode_AsRawUnicodeEscapeString() */
+static PyObject *
+unicode_asrawunicodeescapestring(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_AsRawUnicodeEscapeString(arg);
+}
+
+static PyObject *
+unicode_decodelatin1(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    return PyUnicode_DecodeLatin1(data, size, errors);
+}
+
+/* Test PyUnicode_AsLatin1String() */
+static PyObject *
+unicode_aslatin1string(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_AsLatin1String(arg);
+}
+
+/* Test PyUnicode_DecodeASCII() */
+static PyObject *
+unicode_decodeascii(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    return PyUnicode_DecodeASCII(data, size, errors);
+}
+
+/* Test PyUnicode_AsASCIIString() */
+static PyObject *
+unicode_asasciistring(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_AsASCIIString(arg);
+}
+
+/* Test PyUnicode_DecodeCharmap() */
+static PyObject *
+unicode_decodecharmap(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    PyObject *mapping;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "y#O|z", &data, &size, &mapping, &errors))
+        return NULL;
+
+    NULLABLE(mapping);
+    return PyUnicode_DecodeCharmap(data, size, mapping, errors);
+}
+
+/* Test PyUnicode_AsCharmapString() */
+static PyObject *
+unicode_ascharmapstring(PyObject *self, PyObject *args)
+{
+    PyObject *unicode;
+    PyObject *mapping;
+
+    if (!PyArg_ParseTuple(args, "OO", &unicode, &mapping))
+        return NULL;
+
+    NULLABLE(unicode);
+    NULLABLE(mapping);
+    return PyUnicode_AsCharmapString(unicode, mapping);
+}
+
+#ifdef MS_WINDOWS
+
+/* Test PyUnicode_DecodeMBCS() */
+static PyObject *
+unicode_decodembcs(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    return PyUnicode_DecodeMBCS(data, size, errors);
+}
+
+/* Test PyUnicode_DecodeMBCSStateful() */
+static PyObject *
+unicode_decodembcsstateful(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    Py_ssize_t consumed = UNINITIALIZED_SIZE;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    result = PyUnicode_DecodeMBCSStateful(data, size, errors, &consumed);
+    if (!result) {
+        assert(consumed == UNINITIALIZED_SIZE);
+        return NULL;
+    }
+    return Py_BuildValue("(Nn)", result, consumed);
+}
+
+/* Test PyUnicode_DecodeCodePageStateful() */
+static PyObject *
+unicode_decodecodepagestateful(PyObject *self, PyObject *args)
+{
+    int code_page;
+    const char *data;
+    Py_ssize_t size;
+    const char *errors = NULL;
+    Py_ssize_t consumed = UNINITIALIZED_SIZE;
+    PyObject *result;
+
+    if (!PyArg_ParseTuple(args, "iy#|z", &code_page, &data, &size, &errors))
+        return NULL;
+
+    result = PyUnicode_DecodeCodePageStateful(code_page, data, size, errors, &consumed);
+    if (!result) {
+        assert(consumed == UNINITIALIZED_SIZE);
+        return NULL;
+    }
+    return Py_BuildValue("(Nn)", result, consumed);
+}
+
+/* Test PyUnicode_AsMBCSString() */
+static PyObject *
+unicode_asmbcsstring(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_AsMBCSString(arg);
+}
+
+/* Test PyUnicode_EncodeCodePage() */
+static PyObject *
+unicode_encodecodepage(PyObject *self, PyObject *args)
+{
+    int code_page;
+    PyObject *unicode;
+    const char *errors;
+
+    if (!PyArg_ParseTuple(args, "iO|z", &code_page, &unicode, &errors))
+        return NULL;
+
+    NULLABLE(unicode);
+    return PyUnicode_EncodeCodePage(code_page, unicode, errors);
+}
+
+#endif /* MS_WINDOWS */
+
+/* Test PyUnicode_DecodeLocaleAndSize() */
+static PyObject *
+unicode_decodelocaleandsize(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    return PyUnicode_DecodeLocaleAndSize(data, size, errors);
+}
+
+/* Test PyUnicode_DecodeLocale() */
+static PyObject *
+unicode_decodelocale(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+    const char *errors;
+
+    if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors))
+        return NULL;
+
+    return PyUnicode_DecodeLocale(data, errors);
+}
+
+/* Test PyUnicode_EncodeLocale() */
+static PyObject *
+unicode_encodelocale(PyObject *self, PyObject *args)
+{
+    PyObject *unicode;
+    const char *errors;
+
+    if (!PyArg_ParseTuple(args, "O|z", &unicode, &errors))
+        return NULL;
+
+    NULLABLE(unicode);
+    return PyUnicode_EncodeLocale(unicode, errors);
+}
+
+/* Test PyUnicode_DecodeFSDefault() */
+static PyObject *
+unicode_decodefsdefault(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+
+    if (!PyArg_ParseTuple(args, "y#", &data, &size))
+        return NULL;
+
+    return PyUnicode_DecodeFSDefault(data);
+}
+
+/* Test PyUnicode_DecodeFSDefaultAndSize() */
+static PyObject *
+unicode_decodefsdefaultandsize(PyObject *self, PyObject *args)
+{
+    const char *data;
+    Py_ssize_t size;
+
+    if (!PyArg_ParseTuple(args, "y#|n", &data, &size, &size))
+        return NULL;
+
+    return PyUnicode_DecodeFSDefaultAndSize(data, size);
+}
+
+/* Test PyUnicode_EncodeFSDefault() */
+static PyObject *
+unicode_encodefsdefault(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    return PyUnicode_EncodeFSDefault(arg);
+}
+
+/* Test PyUnicode_Concat() */
+static PyObject *
+unicode_concat(PyObject *self, PyObject *args)
+{
+    PyObject *left;
+    PyObject *right;
+
+    if (!PyArg_ParseTuple(args, "OO", &left, &right))
+        return NULL;
+
+    NULLABLE(left);
+    NULLABLE(right);
+    return PyUnicode_Concat(left, right);
+}
+
+/* Test PyUnicode_Split() */
+static PyObject *
+unicode_split(PyObject *self, PyObject *args)
+{
+    PyObject *s;
+    PyObject *sep;
+    Py_ssize_t maxsplit = -1;
+
+    if (!PyArg_ParseTuple(args, "OO|n", &s, &sep, &maxsplit))
+        return NULL;
+
+    NULLABLE(s);
+    NULLABLE(sep);
+    return PyUnicode_Split(s, sep, maxsplit);
+}
+
+/* Test PyUnicode_RSplit() */
+static PyObject *
+unicode_rsplit(PyObject *self, PyObject *args)
+{
+    PyObject *s;
+    PyObject *sep;
+    Py_ssize_t maxsplit = -1;
+
+    if (!PyArg_ParseTuple(args, "OO|n", &s, &sep, &maxsplit))
+        return NULL;
+
+    NULLABLE(s);
+    NULLABLE(sep);
+    return PyUnicode_RSplit(s, sep, maxsplit);
+}
+
+/* Test PyUnicode_Splitlines() */
+static PyObject *
+unicode_splitlines(PyObject *self, PyObject *args)
+{
+    PyObject *s;
+    int keepends = 0;
+
+    if (!PyArg_ParseTuple(args, "O|i", &s, &keepends))
+        return NULL;
+
+    NULLABLE(s);
+    return PyUnicode_Splitlines(s, keepends);
+}
+
+/* Test PyUnicode_Partition() */
+static PyObject *
+unicode_partition(PyObject *self, PyObject *args)
+{
+    PyObject *s;
+    PyObject *sep;
+
+    if (!PyArg_ParseTuple(args, "OO", &s, &sep))
+        return NULL;
+
+    NULLABLE(s);
+    NULLABLE(sep);
+    return PyUnicode_Partition(s, sep);
+}
+
+/* Test PyUnicode_RPartition() */
+static PyObject *
+unicode_rpartition(PyObject *self, PyObject *args)
+{
+    PyObject *s;
+    PyObject *sep;
+
+    if (!PyArg_ParseTuple(args, "OO", &s, &sep))
+        return NULL;
+
+    NULLABLE(s);
+    NULLABLE(sep);
+    return PyUnicode_RPartition(s, sep);
+}
+
+/* Test PyUnicode_Translate() */
+static PyObject *
+unicode_translate(PyObject *self, PyObject *args)
+{
+    PyObject *obj;
+    PyObject *table;
+    const char *errors = NULL;
+
+    if (!PyArg_ParseTuple(args, "OO|z", &obj, &table, &errors))
+        return NULL;
+
+    NULLABLE(obj);
+    NULLABLE(table);
+    return PyUnicode_Translate(obj, table, errors);
+}
+
+/* Test PyUnicode_Join() */
+static PyObject *
+unicode_join(PyObject *self, PyObject *args)
+{
+    PyObject *sep;
+    PyObject *seq;
+
+    if (!PyArg_ParseTuple(args, "OO", &sep, &seq))
+        return NULL;
+
+    NULLABLE(sep);
+    NULLABLE(seq);
+    return PyUnicode_Join(sep, seq);
+}
+
+/* Test PyUnicode_Count() */
+static PyObject *
+unicode_count(PyObject *self, PyObject *args)
+{
+    PyObject *str;
+    PyObject *substr;
+    Py_ssize_t start;
+    Py_ssize_t end;
+
+    if (!PyArg_ParseTuple(args, "OOnn", &str, &substr, &start, &end))
+        return NULL;
+
+    NULLABLE(str);
+    NULLABLE(substr);
+    RETURN_SIZE(PyUnicode_Count(str, substr, start, end));
+}
+
+/* Test PyUnicode_Find() */
+static PyObject *
+unicode_find(PyObject *self, PyObject *args)
+{
+    PyObject *str;
+    PyObject *substr;
+    Py_ssize_t start;
+    Py_ssize_t end;
+    int direction;
+    Py_ssize_t result;
+
+    if (!PyArg_ParseTuple(args, "OOnni", &str, &substr, &start, &end, &direction))
+        return NULL;
+
+    NULLABLE(str);
+    NULLABLE(substr);
+    result = PyUnicode_Find(str, substr, start, end, direction);
+    if (result == -2) {
+        assert(PyErr_Occurred());
+        return NULL;
+    }
+    assert(!PyErr_Occurred());
+    return PyLong_FromSsize_t(result);
+}
+
+/* Test PyUnicode_Tailmatch() */
+static PyObject *
+unicode_tailmatch(PyObject *self, PyObject *args)
+{
+    PyObject *str;
+    PyObject *substr;
+    Py_ssize_t start;
+    Py_ssize_t end;
+    int direction;
+
+    if (!PyArg_ParseTuple(args, "OOnni", &str, &substr, &start, &end, &direction))
+        return NULL;
+
+    NULLABLE(str);
+    NULLABLE(substr);
+    RETURN_SIZE(PyUnicode_Tailmatch(str, substr, start, end, direction));
+}
+
+/* Test PyUnicode_FindChar() */
+static PyObject *
+unicode_findchar(PyObject *self, PyObject *args)
+{
+    PyObject *str;
+    int direction;
+    unsigned int ch;
+    Py_ssize_t result;
+    Py_ssize_t start, end;
+
+    if (!PyArg_ParseTuple(args, "OInni:unicode_findchar", &str, &ch,
+                          &start, &end, &direction)) {
+        return NULL;
+    }
+    NULLABLE(str);
+    result = PyUnicode_FindChar(str, (Py_UCS4)ch, start, end, direction);
+    if (result == -2) {
+        assert(PyErr_Occurred());
+        return NULL;
+    }
+    assert(!PyErr_Occurred());
+    return PyLong_FromSsize_t(result);
+}
+
+/* Test PyUnicode_Replace() */
+static PyObject *
+unicode_replace(PyObject *self, PyObject *args)
+{
+    PyObject *str;
+    PyObject *substr;
+    PyObject *replstr;
+    Py_ssize_t maxcount = -1;
+
+    if (!PyArg_ParseTuple(args, "OOO|n", &str, &substr, &replstr, &maxcount))
+        return NULL;
+
+    NULLABLE(str);
+    NULLABLE(substr);
+    NULLABLE(replstr);
+    return PyUnicode_Replace(str, substr, replstr, maxcount);
+}
+
+/* Test PyUnicode_Compare() */
+static PyObject *
+unicode_compare(PyObject *self, PyObject *args)
+{
+    PyObject *left;
+    PyObject *right;
+    int result;
+
+    if (!PyArg_ParseTuple(args, "OO", &left, &right))
+        return NULL;
+
+    NULLABLE(left);
+    NULLABLE(right);
+    result = PyUnicode_Compare(left, right);
+    if (result == -1 && PyErr_Occurred()) {
+        return NULL;
+    }
+    assert(!PyErr_Occurred());
+    return PyLong_FromLong(result);
+}
+
+/* Test PyUnicode_CompareWithASCIIString() */
+static PyObject *
+unicode_comparewithasciistring(PyObject *self, PyObject *args)
+{
+    PyObject *left;
+    const char *right = NULL;
+    Py_ssize_t right_len;
+    int result;
+
+    if (!PyArg_ParseTuple(args, "O|y#", &left, &right, &right_len))
+        return NULL;
+
+    NULLABLE(left);
+    result = PyUnicode_CompareWithASCIIString(left, right);
+    if (result == -1 && PyErr_Occurred()) {
+        return NULL;
+    }
+    return PyLong_FromLong(result);
+}
+
+/* Test PyUnicode_EqualToUTF8() */
+static PyObject *
+unicode_equaltoutf8(PyObject *self, PyObject *args)
+{
+    PyObject *left;
+    const char *right = NULL;
+    Py_ssize_t right_len;
+    int result;
+
+    if (!PyArg_ParseTuple(args, "Oz#", &left, &right, &right_len)) {
+        return NULL;
+    }
+
+    NULLABLE(left);
+    result = PyUnicode_EqualToUTF8(left, right);
+    assert(!PyErr_Occurred());
+    return PyLong_FromLong(result);
+}
+
+/* Test PyUnicode_EqualToUTF8AndSize() */
+static PyObject *
+unicode_equaltoutf8andsize(PyObject *self, PyObject *args)
+{
+    PyObject *left;
+    const char *right = NULL;
+    Py_ssize_t right_len;
+    Py_ssize_t size = -100;
+    int result;
+
+    if (!PyArg_ParseTuple(args, "Oz#|n", &left, &right, &right_len, &size)) {
+        return NULL;
+    }
+
+    NULLABLE(left);
+    if (size == -100) {
+        size = right_len;
+    }
+    result = PyUnicode_EqualToUTF8AndSize(left, right, size);
+    assert(!PyErr_Occurred());
+    return PyLong_FromLong(result);
+}
+
+/* Test PyUnicode_RichCompare() */
+static PyObject *
+unicode_richcompare(PyObject *self, PyObject *args)
+{
+    PyObject *left;
+    PyObject *right;
+    int op;
+
+    if (!PyArg_ParseTuple(args, "OOi", &left, &right, &op))
+        return NULL;
+
+    NULLABLE(left);
+    NULLABLE(right);
+    return PyUnicode_RichCompare(left, right, op);
+}
+
+/* Test PyUnicode_Format() */
+static PyObject *
+unicode_format(PyObject *self, PyObject *args)
+{
+    PyObject *format;
+    PyObject *fargs;
+
+    if (!PyArg_ParseTuple(args, "OO", &format, &fargs))
+        return NULL;
+
+    NULLABLE(format);
+    NULLABLE(fargs);
+    return PyUnicode_Format(format, fargs);
+}
+
+/* Test PyUnicode_Contains() */
+static PyObject *
+unicode_contains(PyObject *self, PyObject *args)
+{
+    PyObject *container;
+    PyObject *element;
+
+    if (!PyArg_ParseTuple(args, "OO", &container, &element))
+        return NULL;
+
+    NULLABLE(container);
+    NULLABLE(element);
+    RETURN_INT(PyUnicode_Contains(container, element));
+}
+
+/* Test PyUnicode_IsIdentifier() */
+static PyObject *
+unicode_isidentifier(PyObject *self, PyObject *arg)
+{
+    NULLABLE(arg);
+    RETURN_INT(PyUnicode_IsIdentifier(arg));
+}
+
+
+static int
+check_raised_systemerror(PyObject *result, char* msg)
+{
+    if (result) {
+        // no exception
+        PyErr_Format(PyExc_AssertionError,
+                     "SystemError not raised: %s",
+                     msg);
+        return 0;
+    }
+    if (PyErr_ExceptionMatches(PyExc_SystemError)) {
+        // expected exception
+        PyErr_Clear();
+        return 1;
+    }
+    // unexpected exception
+    return 0;
+}
+
+static PyObject *
+test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    PyObject *result;
+    PyObject *unicode = PyUnicode_FromString("None");
+
+#define CHECK_FORMAT_2(FORMAT, EXPECTED, ARG1, ARG2)                \
+    result = PyUnicode_FromFormat(FORMAT, ARG1, ARG2);              \
+    if (EXPECTED == NULL) {                                         \
+        if (!check_raised_systemerror(result, FORMAT)) {            \
+            goto Fail;                                              \
+        }                                                           \
+    }                                                               \
+    else if (result == NULL)                                        \
+        return NULL;                                                \
+    else if (PyUnicode_CompareWithASCIIString(result, EXPECTED) != 0) { \
+        PyObject *utf8 = PyUnicode_AsUTF8String(result);            \
+        PyErr_Format(PyExc_AssertionError,                          \
+                     "test_string_from_format: failed at \"%s\" "   \
+                     "expected \"%s\" got \"%s\"",                  \
+                     FORMAT, EXPECTED, utf8);                       \
+        Py_XDECREF(utf8);                                           \
+        goto Fail;                                                  \
+    }                                                               \
+    Py_XDECREF(result)
+
+#define CHECK_FORMAT_1(FORMAT, EXPECTED, ARG)                       \
+    CHECK_FORMAT_2(FORMAT, EXPECTED, ARG, 0)
+
+#define CHECK_FORMAT_0(FORMAT, EXPECTED)                            \
+    CHECK_FORMAT_2(FORMAT, EXPECTED, 0, 0)
+
+    // Unrecognized
+    CHECK_FORMAT_2("%u %? %u", NULL, 1, 2);
+
+    // "%%" (options are rejected)
+    CHECK_FORMAT_0(  "%%", "%");
+    CHECK_FORMAT_0( "%0%", NULL);
+    CHECK_FORMAT_0("%00%", NULL);
+    CHECK_FORMAT_0( "%2%", NULL);
+    CHECK_FORMAT_0("%02%", NULL);
+    CHECK_FORMAT_0("%.0%", NULL);
+    CHECK_FORMAT_0("%.2%", NULL);
+
+    // "%c"
+    CHECK_FORMAT_1(  "%c", "c", 'c');
+    CHECK_FORMAT_1( "%0c", "c", 'c');
+    CHECK_FORMAT_1("%00c", "c", 'c');
+    CHECK_FORMAT_1( "%2c", NULL, 'c');
+    CHECK_FORMAT_1("%02c", NULL, 'c');
+    CHECK_FORMAT_1("%.0c", NULL, 'c');
+    CHECK_FORMAT_1("%.2c", NULL, 'c');
+
+    // Integers
+    CHECK_FORMAT_1("%d",             "123",                (int)123);
+    CHECK_FORMAT_1("%i",             "123",                (int)123);
+    CHECK_FORMAT_1("%u",             "123",       (unsigned int)123);
+    CHECK_FORMAT_1("%x",              "7b",       (unsigned int)123);
+    CHECK_FORMAT_1("%X",              "7B",       (unsigned int)123);
+    CHECK_FORMAT_1("%o",             "173",       (unsigned int)123);
+    CHECK_FORMAT_1("%ld",            "123",               (long)123);
+    CHECK_FORMAT_1("%li",            "123",               (long)123);
+    CHECK_FORMAT_1("%lu",            "123",      (unsigned long)123);
+    CHECK_FORMAT_1("%lx",             "7b",      (unsigned long)123);
+    CHECK_FORMAT_1("%lX",             "7B",      (unsigned long)123);
+    CHECK_FORMAT_1("%lo",            "173",      (unsigned long)123);
+    CHECK_FORMAT_1("%lld",           "123",          (long long)123);
+    CHECK_FORMAT_1("%lli",           "123",          (long long)123);
+    CHECK_FORMAT_1("%llu",           "123", (unsigned long long)123);
+    CHECK_FORMAT_1("%llx",            "7b", (unsigned long long)123);
+    CHECK_FORMAT_1("%llX",            "7B", (unsigned long long)123);
+    CHECK_FORMAT_1("%llo",           "173", (unsigned long long)123);
+    CHECK_FORMAT_1("%zd",            "123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%zi",            "123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%zu",            "123",             (size_t)123);
+    CHECK_FORMAT_1("%zx",             "7b",             (size_t)123);
+    CHECK_FORMAT_1("%zX",             "7B",             (size_t)123);
+    CHECK_FORMAT_1("%zo",            "173",             (size_t)123);
+    CHECK_FORMAT_1("%td",            "123",          (ptrdiff_t)123);
+    CHECK_FORMAT_1("%ti",            "123",          (ptrdiff_t)123);
+    CHECK_FORMAT_1("%tu",            "123",          (ptrdiff_t)123);
+    CHECK_FORMAT_1("%tx",             "7b",          (ptrdiff_t)123);
+    CHECK_FORMAT_1("%tX",             "7B",          (ptrdiff_t)123);
+    CHECK_FORMAT_1("%to",            "173",          (ptrdiff_t)123);
+    CHECK_FORMAT_1("%jd",            "123",           (intmax_t)123);
+    CHECK_FORMAT_1("%ji",            "123",           (intmax_t)123);
+    CHECK_FORMAT_1("%ju",            "123",          (uintmax_t)123);
+    CHECK_FORMAT_1("%jx",             "7b",          (uintmax_t)123);
+    CHECK_FORMAT_1("%jX",             "7B",          (uintmax_t)123);
+    CHECK_FORMAT_1("%jo",            "173",          (uintmax_t)123);
+
+    CHECK_FORMAT_1("%d",            "-123",               (int)-123);
+    CHECK_FORMAT_1("%i",            "-123",               (int)-123);
+    CHECK_FORMAT_1("%ld",           "-123",              (long)-123);
+    CHECK_FORMAT_1("%li",           "-123",              (long)-123);
+    CHECK_FORMAT_1("%lld",          "-123",         (long long)-123);
+    CHECK_FORMAT_1("%lli",          "-123",         (long long)-123);
+    CHECK_FORMAT_1("%zd",           "-123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%zi",           "-123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%td",           "-123",         (ptrdiff_t)-123);
+    CHECK_FORMAT_1("%ti",           "-123",         (ptrdiff_t)-123);
+    CHECK_FORMAT_1("%jd",           "-123",          (intmax_t)-123);
+    CHECK_FORMAT_1("%ji",           "-123",          (intmax_t)-123);
+
+    // Integers: width < length
+    CHECK_FORMAT_1("%1d",            "123",                (int)123);
+    CHECK_FORMAT_1("%1i",            "123",                (int)123);
+    CHECK_FORMAT_1("%1u",            "123",       (unsigned int)123);
+    CHECK_FORMAT_1("%1ld",           "123",               (long)123);
+    CHECK_FORMAT_1("%1li",           "123",               (long)123);
+    CHECK_FORMAT_1("%1lu",           "123",      (unsigned long)123);
+    CHECK_FORMAT_1("%1lld",          "123",          (long long)123);
+    CHECK_FORMAT_1("%1lli",          "123",          (long long)123);
+    CHECK_FORMAT_1("%1llu",          "123", (unsigned long long)123);
+    CHECK_FORMAT_1("%1zd",           "123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%1zi",           "123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%1zu",           "123",             (size_t)123);
+    CHECK_FORMAT_1("%1x",             "7b",                (int)123);
+
+    CHECK_FORMAT_1("%1d",           "-123",               (int)-123);
+    CHECK_FORMAT_1("%1i",           "-123",               (int)-123);
+    CHECK_FORMAT_1("%1ld",          "-123",              (long)-123);
+    CHECK_FORMAT_1("%1li",          "-123",              (long)-123);
+    CHECK_FORMAT_1("%1lld",         "-123",         (long long)-123);
+    CHECK_FORMAT_1("%1lli",         "-123",         (long long)-123);
+    CHECK_FORMAT_1("%1zd",          "-123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%1zi",          "-123",        (Py_ssize_t)-123);
+
+    // Integers: width > length
+    CHECK_FORMAT_1("%5d",          "  123",                (int)123);
+    CHECK_FORMAT_1("%5i",          "  123",                (int)123);
+    CHECK_FORMAT_1("%5u",          "  123",       (unsigned int)123);
+    CHECK_FORMAT_1("%5ld",         "  123",               (long)123);
+    CHECK_FORMAT_1("%5li",         "  123",               (long)123);
+    CHECK_FORMAT_1("%5lu",         "  123",      (unsigned long)123);
+    CHECK_FORMAT_1("%5lld",        "  123",          (long long)123);
+    CHECK_FORMAT_1("%5lli",        "  123",          (long long)123);
+    CHECK_FORMAT_1("%5llu",        "  123", (unsigned long long)123);
+    CHECK_FORMAT_1("%5zd",         "  123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%5zi",         "  123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%5zu",         "  123",             (size_t)123);
+    CHECK_FORMAT_1("%5x",          "   7b",                (int)123);
+
+    CHECK_FORMAT_1("%5d",          " -123",               (int)-123);
+    CHECK_FORMAT_1("%5i",          " -123",               (int)-123);
+    CHECK_FORMAT_1("%5ld",         " -123",              (long)-123);
+    CHECK_FORMAT_1("%5li",         " -123",              (long)-123);
+    CHECK_FORMAT_1("%5lld",        " -123",         (long long)-123);
+    CHECK_FORMAT_1("%5lli",        " -123",         (long long)-123);
+    CHECK_FORMAT_1("%5zd",         " -123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%5zi",         " -123",        (Py_ssize_t)-123);
+
+    // Integers: width > length, 0-flag
+    CHECK_FORMAT_1("%05d",         "00123",                (int)123);
+    CHECK_FORMAT_1("%05i",         "00123",                (int)123);
+    CHECK_FORMAT_1("%05u",         "00123",       (unsigned int)123);
+    CHECK_FORMAT_1("%05ld",        "00123",               (long)123);
+    CHECK_FORMAT_1("%05li",        "00123",               (long)123);
+    CHECK_FORMAT_1("%05lu",        "00123",      (unsigned long)123);
+    CHECK_FORMAT_1("%05lld",       "00123",          (long long)123);
+    CHECK_FORMAT_1("%05lli",       "00123",          (long long)123);
+    CHECK_FORMAT_1("%05llu",       "00123", (unsigned long long)123);
+    CHECK_FORMAT_1("%05zd",        "00123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%05zi",        "00123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%05zu",        "00123",             (size_t)123);
+    CHECK_FORMAT_1("%05x",         "0007b",                (int)123);
+
+    CHECK_FORMAT_1("%05d",         "-0123",               (int)-123);
+    CHECK_FORMAT_1("%05i",         "-0123",               (int)-123);
+    CHECK_FORMAT_1("%05ld",        "-0123",              (long)-123);
+    CHECK_FORMAT_1("%05li",        "-0123",              (long)-123);
+    CHECK_FORMAT_1("%05lld",       "-0123",         (long long)-123);
+    CHECK_FORMAT_1("%05lli",       "-0123",         (long long)-123);
+    CHECK_FORMAT_1("%05zd",        "-0123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%05zi",        "-0123",        (Py_ssize_t)-123);
+
+    // Integers: precision < length
+    CHECK_FORMAT_1("%.1d",           "123",                (int)123);
+    CHECK_FORMAT_1("%.1i",           "123",                (int)123);
+    CHECK_FORMAT_1("%.1u",           "123",       (unsigned int)123);
+    CHECK_FORMAT_1("%.1ld",          "123",               (long)123);
+    CHECK_FORMAT_1("%.1li",          "123",               (long)123);
+    CHECK_FORMAT_1("%.1lu",          "123",      (unsigned long)123);
+    CHECK_FORMAT_1("%.1lld",         "123",          (long long)123);
+    CHECK_FORMAT_1("%.1lli",         "123",          (long long)123);
+    CHECK_FORMAT_1("%.1llu",         "123", (unsigned long long)123);
+    CHECK_FORMAT_1("%.1zd",          "123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%.1zi",          "123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%.1zu",          "123",             (size_t)123);
+    CHECK_FORMAT_1("%.1x",            "7b",                (int)123);
+
+    CHECK_FORMAT_1("%.1d",          "-123",               (int)-123);
+    CHECK_FORMAT_1("%.1i",          "-123",               (int)-123);
+    CHECK_FORMAT_1("%.1ld",         "-123",              (long)-123);
+    CHECK_FORMAT_1("%.1li",         "-123",              (long)-123);
+    CHECK_FORMAT_1("%.1lld",        "-123",         (long long)-123);
+    CHECK_FORMAT_1("%.1lli",        "-123",         (long long)-123);
+    CHECK_FORMAT_1("%.1zd",         "-123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%.1zi",         "-123",        (Py_ssize_t)-123);
+
+    // Integers: precision > length
+    CHECK_FORMAT_1("%.5d",         "00123",                (int)123);
+    CHECK_FORMAT_1("%.5i",         "00123",                (int)123);
+    CHECK_FORMAT_1("%.5u",         "00123",       (unsigned int)123);
+    CHECK_FORMAT_1("%.5ld",        "00123",               (long)123);
+    CHECK_FORMAT_1("%.5li",        "00123",               (long)123);
+    CHECK_FORMAT_1("%.5lu",        "00123",      (unsigned long)123);
+    CHECK_FORMAT_1("%.5lld",       "00123",          (long long)123);
+    CHECK_FORMAT_1("%.5lli",       "00123",          (long long)123);
+    CHECK_FORMAT_1("%.5llu",       "00123", (unsigned long long)123);
+    CHECK_FORMAT_1("%.5zd",        "00123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%.5zi",        "00123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%.5zu",        "00123",             (size_t)123);
+    CHECK_FORMAT_1("%.5x",         "0007b",                (int)123);
+
+    CHECK_FORMAT_1("%.5d",        "-00123",               (int)-123);
+    CHECK_FORMAT_1("%.5i",        "-00123",               (int)-123);
+    CHECK_FORMAT_1("%.5ld",       "-00123",              (long)-123);
+    CHECK_FORMAT_1("%.5li",       "-00123",              (long)-123);
+    CHECK_FORMAT_1("%.5lld",      "-00123",         (long long)-123);
+    CHECK_FORMAT_1("%.5lli",      "-00123",         (long long)-123);
+    CHECK_FORMAT_1("%.5zd",       "-00123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%.5zi",       "-00123",        (Py_ssize_t)-123);
+
+    // Integers: width > precision > length
+    CHECK_FORMAT_1("%7.5d",      "  00123",                (int)123);
+    CHECK_FORMAT_1("%7.5i",      "  00123",                (int)123);
+    CHECK_FORMAT_1("%7.5u",      "  00123",       (unsigned int)123);
+    CHECK_FORMAT_1("%7.5ld",     "  00123",               (long)123);
+    CHECK_FORMAT_1("%7.5li",     "  00123",               (long)123);
+    CHECK_FORMAT_1("%7.5lu",     "  00123",      (unsigned long)123);
+    CHECK_FORMAT_1("%7.5lld",    "  00123",          (long long)123);
+    CHECK_FORMAT_1("%7.5lli",    "  00123",          (long long)123);
+    CHECK_FORMAT_1("%7.5llu",    "  00123", (unsigned long long)123);
+    CHECK_FORMAT_1("%7.5zd",     "  00123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%7.5zi",     "  00123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%7.5zu",     "  00123",             (size_t)123);
+    CHECK_FORMAT_1("%7.5x",      "  0007b",                (int)123);
+
+    CHECK_FORMAT_1("%7.5d",      " -00123",               (int)-123);
+    CHECK_FORMAT_1("%7.5i",      " -00123",               (int)-123);
+    CHECK_FORMAT_1("%7.5ld",     " -00123",              (long)-123);
+    CHECK_FORMAT_1("%7.5li",     " -00123",              (long)-123);
+    CHECK_FORMAT_1("%7.5lld",    " -00123",         (long long)-123);
+    CHECK_FORMAT_1("%7.5lli",    " -00123",         (long long)-123);
+    CHECK_FORMAT_1("%7.5zd",     " -00123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%7.5zi",     " -00123",        (Py_ssize_t)-123);
+
+    // Integers: width > precision > length, 0-flag
+    CHECK_FORMAT_1("%07.5d",     "0000123",                (int)123);
+    CHECK_FORMAT_1("%07.5i",     "0000123",                (int)123);
+    CHECK_FORMAT_1("%07.5u",     "0000123",       (unsigned int)123);
+    CHECK_FORMAT_1("%07.5ld",    "0000123",               (long)123);
+    CHECK_FORMAT_1("%07.5li",    "0000123",               (long)123);
+    CHECK_FORMAT_1("%07.5lu",    "0000123",      (unsigned long)123);
+    CHECK_FORMAT_1("%07.5lld",   "0000123",          (long long)123);
+    CHECK_FORMAT_1("%07.5lli",   "0000123",          (long long)123);
+    CHECK_FORMAT_1("%07.5llu",   "0000123", (unsigned long long)123);
+    CHECK_FORMAT_1("%07.5zd",    "0000123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%07.5zi",    "0000123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%07.5zu",    "0000123",             (size_t)123);
+    CHECK_FORMAT_1("%07.5x",     "000007b",                (int)123);
+
+    CHECK_FORMAT_1("%07.5d",     "-000123",               (int)-123);
+    CHECK_FORMAT_1("%07.5i",     "-000123",               (int)-123);
+    CHECK_FORMAT_1("%07.5ld",    "-000123",              (long)-123);
+    CHECK_FORMAT_1("%07.5li",    "-000123",              (long)-123);
+    CHECK_FORMAT_1("%07.5lld",   "-000123",         (long long)-123);
+    CHECK_FORMAT_1("%07.5lli",   "-000123",         (long long)-123);
+    CHECK_FORMAT_1("%07.5zd",    "-000123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%07.5zi",    "-000123",        (Py_ssize_t)-123);
+
+    // Integers: precision > width > length
+    CHECK_FORMAT_1("%5.7d",      "0000123",                (int)123);
+    CHECK_FORMAT_1("%5.7i",      "0000123",                (int)123);
+    CHECK_FORMAT_1("%5.7u",      "0000123",       (unsigned int)123);
+    CHECK_FORMAT_1("%5.7ld",     "0000123",               (long)123);
+    CHECK_FORMAT_1("%5.7li",     "0000123",               (long)123);
+    CHECK_FORMAT_1("%5.7lu",     "0000123",      (unsigned long)123);
+    CHECK_FORMAT_1("%5.7lld",    "0000123",          (long long)123);
+    CHECK_FORMAT_1("%5.7lli",    "0000123",          (long long)123);
+    CHECK_FORMAT_1("%5.7llu",    "0000123", (unsigned long long)123);
+    CHECK_FORMAT_1("%5.7zd",     "0000123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%5.7zi",     "0000123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%5.7zu",     "0000123",             (size_t)123);
+    CHECK_FORMAT_1("%5.7x",      "000007b",                (int)123);
+
+    CHECK_FORMAT_1("%5.7d",     "-0000123",               (int)-123);
+    CHECK_FORMAT_1("%5.7i",     "-0000123",               (int)-123);
+    CHECK_FORMAT_1("%5.7ld",    "-0000123",              (long)-123);
+    CHECK_FORMAT_1("%5.7li",    "-0000123",              (long)-123);
+    CHECK_FORMAT_1("%5.7lld",   "-0000123",         (long long)-123);
+    CHECK_FORMAT_1("%5.7lli",   "-0000123",         (long long)-123);
+    CHECK_FORMAT_1("%5.7zd",    "-0000123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%5.7zi",    "-0000123",        (Py_ssize_t)-123);
+
+    // Integers: precision > width > length, 0-flag
+    CHECK_FORMAT_1("%05.7d",     "0000123",                (int)123);
+    CHECK_FORMAT_1("%05.7i",     "0000123",                (int)123);
+    CHECK_FORMAT_1("%05.7u",     "0000123",       (unsigned int)123);
+    CHECK_FORMAT_1("%05.7ld",    "0000123",               (long)123);
+    CHECK_FORMAT_1("%05.7li",    "0000123",               (long)123);
+    CHECK_FORMAT_1("%05.7lu",    "0000123",      (unsigned long)123);
+    CHECK_FORMAT_1("%05.7lld",   "0000123",          (long long)123);
+    CHECK_FORMAT_1("%05.7lli",   "0000123",          (long long)123);
+    CHECK_FORMAT_1("%05.7llu",   "0000123", (unsigned long long)123);
+    CHECK_FORMAT_1("%05.7zd",    "0000123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%05.7zi",    "0000123",         (Py_ssize_t)123);
+    CHECK_FORMAT_1("%05.7zu",    "0000123",             (size_t)123);
+    CHECK_FORMAT_1("%05.7x",     "000007b",                (int)123);
+
+    CHECK_FORMAT_1("%05.7d",    "-0000123",               (int)-123);
+    CHECK_FORMAT_1("%05.7i",    "-0000123",               (int)-123);
+    CHECK_FORMAT_1("%05.7ld",   "-0000123",              (long)-123);
+    CHECK_FORMAT_1("%05.7li",   "-0000123",              (long)-123);
+    CHECK_FORMAT_1("%05.7lld",  "-0000123",         (long long)-123);
+    CHECK_FORMAT_1("%05.7lli",  "-0000123",         (long long)-123);
+    CHECK_FORMAT_1("%05.7zd",   "-0000123",        (Py_ssize_t)-123);
+    CHECK_FORMAT_1("%05.7zi",   "-0000123",        (Py_ssize_t)-123);
+
+    // Integers: precision = 0, arg = 0 (empty string in C)
+    CHECK_FORMAT_1("%.0d",             "0",                  (int)0);
+    CHECK_FORMAT_1("%.0i",             "0",                  (int)0);
+    CHECK_FORMAT_1("%.0u",             "0",         (unsigned int)0);
+    CHECK_FORMAT_1("%.0ld",            "0",                 (long)0);
+    CHECK_FORMAT_1("%.0li",            "0",                 (long)0);
+    CHECK_FORMAT_1("%.0lu",            "0",        (unsigned long)0);
+    CHECK_FORMAT_1("%.0lld",           "0",            (long long)0);
+    CHECK_FORMAT_1("%.0lli",           "0",            (long long)0);
+    CHECK_FORMAT_1("%.0llu",           "0",   (unsigned long long)0);
+    CHECK_FORMAT_1("%.0zd",            "0",           (Py_ssize_t)0);
+    CHECK_FORMAT_1("%.0zi",            "0",           (Py_ssize_t)0);
+    CHECK_FORMAT_1("%.0zu",            "0",               (size_t)0);
+    CHECK_FORMAT_1("%.0x",             "0",                  (int)0);
+
+    // Strings
+    CHECK_FORMAT_1("%s",     "None",  "None");
+    CHECK_FORMAT_1("%ls",    "None", L"None");
+    CHECK_FORMAT_1("%U",     "None", unicode);
+    CHECK_FORMAT_1("%A",     "None", Py_None);
+    CHECK_FORMAT_1("%S",     "None", Py_None);
+    CHECK_FORMAT_1("%R",     "None", Py_None);
+    CHECK_FORMAT_2("%V",     "None", unicode, "ignored");
+    CHECK_FORMAT_2("%V",     "None",    NULL,    "None");
+    CHECK_FORMAT_2("%lV",    "None",    NULL,   L"None");
+
+    // Strings: width < length
+    CHECK_FORMAT_1("%1s",    "None",  "None");
+    CHECK_FORMAT_1("%1ls",   "None", L"None");
+    CHECK_FORMAT_1("%1U",    "None", unicode);
+    CHECK_FORMAT_1("%1A",    "None", Py_None);
+    CHECK_FORMAT_1("%1S",    "None", Py_None);
+    CHECK_FORMAT_1("%1R",    "None", Py_None);
+    CHECK_FORMAT_2("%1V",    "None", unicode, "ignored");
+    CHECK_FORMAT_2("%1V",    "None",    NULL,    "None");
+    CHECK_FORMAT_2("%1lV",   "None",    NULL,    L"None");
+
+    // Strings: width > length
+    CHECK_FORMAT_1("%5s",   " None",  "None");
+    CHECK_FORMAT_1("%5ls",  " None", L"None");
+    CHECK_FORMAT_1("%5U",   " None", unicode);
+    CHECK_FORMAT_1("%5A",   " None", Py_None);
+    CHECK_FORMAT_1("%5S",   " None", Py_None);
+    CHECK_FORMAT_1("%5R",   " None", Py_None);
+    CHECK_FORMAT_2("%5V",   " None", unicode, "ignored");
+    CHECK_FORMAT_2("%5V",   " None",    NULL,    "None");
+    CHECK_FORMAT_2("%5lV",  " None",    NULL,   L"None");
+
+    // Strings: precision < length
+    CHECK_FORMAT_1("%.1s",      "N",  "None");
+    CHECK_FORMAT_1("%.1ls",     "N", L"None");
+    CHECK_FORMAT_1("%.1U",      "N", unicode);
+    CHECK_FORMAT_1("%.1A",      "N", Py_None);
+    CHECK_FORMAT_1("%.1S",      "N", Py_None);
+    CHECK_FORMAT_1("%.1R",      "N", Py_None);
+    CHECK_FORMAT_2("%.1V",      "N", unicode, "ignored");
+    CHECK_FORMAT_2("%.1V",      "N",    NULL,    "None");
+    CHECK_FORMAT_2("%.1lV",     "N",    NULL,   L"None");
+
+    // Strings: precision > length
+    CHECK_FORMAT_1("%.5s",   "None",  "None");
+    CHECK_FORMAT_1("%.5ls",  "None", L"None");
+    CHECK_FORMAT_1("%.5U",   "None", unicode);
+    CHECK_FORMAT_1("%.5A",   "None", Py_None);
+    CHECK_FORMAT_1("%.5S",   "None", Py_None);
+    CHECK_FORMAT_1("%.5R",   "None", Py_None);
+    CHECK_FORMAT_2("%.5V",   "None", unicode, "ignored");
+    CHECK_FORMAT_2("%.5V",   "None",    NULL,    "None");
+    CHECK_FORMAT_2("%.5lV",  "None",    NULL,   L"None");
+
+    // Strings: precision < length, width > length
+    CHECK_FORMAT_1("%5.1s", "    N",  "None");
+    CHECK_FORMAT_1("%5.1ls","    N", L"None");
+    CHECK_FORMAT_1("%5.1U", "    N", unicode);
+    CHECK_FORMAT_1("%5.1A", "    N", Py_None);
+    CHECK_FORMAT_1("%5.1S", "    N", Py_None);
+    CHECK_FORMAT_1("%5.1R", "    N", Py_None);
+    CHECK_FORMAT_2("%5.1V", "    N", unicode, "ignored");
+    CHECK_FORMAT_2("%5.1V", "    N",    NULL,    "None");
+    CHECK_FORMAT_2("%5.1lV","    N",    NULL,   L"None");
+
+    // Strings: width < length, precision > length
+    CHECK_FORMAT_1("%1.5s",  "None",  "None");
+    CHECK_FORMAT_1("%1.5ls", "None",  L"None");
+    CHECK_FORMAT_1("%1.5U",  "None", unicode);
+    CHECK_FORMAT_1("%1.5A",  "None", Py_None);
+    CHECK_FORMAT_1("%1.5S",  "None", Py_None);
+    CHECK_FORMAT_1("%1.5R",  "None", Py_None);
+    CHECK_FORMAT_2("%1.5V",  "None", unicode, "ignored");
+    CHECK_FORMAT_2("%1.5V",  "None",    NULL,    "None");
+    CHECK_FORMAT_2("%1.5lV", "None",    NULL,   L"None");
+
+    Py_XDECREF(unicode);
+    Py_RETURN_NONE;
+
+ Fail:
+    Py_XDECREF(result);
+    Py_XDECREF(unicode);
+    return NULL;
+
+#undef CHECK_FORMAT_2
+#undef CHECK_FORMAT_1
+#undef CHECK_FORMAT_0
+}
+
+static PyMethodDef TestMethods[] = {
+    {"codec_incrementalencoder", codec_incrementalencoder,       METH_VARARGS},
+    {"codec_incrementaldecoder", codec_incrementaldecoder,       METH_VARARGS},
+    {"test_unicode_compare_with_ascii",
+     test_unicode_compare_with_ascii,                            METH_NOARGS},
+    {"test_string_from_format",  test_string_from_format,        METH_NOARGS},
+    {"test_widechar",            test_widechar,                  METH_NOARGS},
+    {"unicode_writechar",        unicode_writechar,              METH_VARARGS},
+    {"unicode_resize",           unicode_resize,                 METH_VARARGS},
+    {"unicode_append",           unicode_append,                 METH_VARARGS},
+    {"unicode_appendanddel",     unicode_appendanddel,           METH_VARARGS},
+    {"unicode_fromstringandsize",unicode_fromstringandsize,      METH_VARARGS},
+    {"unicode_fromstring",       unicode_fromstring,             METH_O},
+    {"unicode_substring",        unicode_substring,              METH_VARARGS},
+    {"unicode_getlength",        unicode_getlength,              METH_O},
+    {"unicode_readchar",         unicode_readchar,               METH_VARARGS},
+    {"unicode_fromencodedobject",unicode_fromencodedobject,      METH_VARARGS},
+    {"unicode_fromobject",       unicode_fromobject,             METH_O},
+    {"unicode_interninplace",    unicode_interninplace,          METH_O},
+    {"unicode_internfromstring", unicode_internfromstring,       METH_O},
+    {"unicode_fromwidechar",     unicode_fromwidechar,           METH_VARARGS},
+    {"unicode_aswidechar",       unicode_aswidechar,             METH_VARARGS},
+    {"unicode_aswidechar_null",  unicode_aswidechar_null,        METH_VARARGS},
+    {"unicode_aswidecharstring", unicode_aswidecharstring,       METH_VARARGS},
+    {"unicode_aswidecharstring_null",unicode_aswidecharstring_null,METH_VARARGS},
+    {"unicode_fromordinal",      unicode_fromordinal,            METH_VARARGS},
+    {"unicode_asutf8andsize",    unicode_asutf8andsize,          METH_VARARGS},
+    {"unicode_asutf8andsize_null",unicode_asutf8andsize_null,    METH_VARARGS},
+    {"unicode_getdefaultencoding",unicode_getdefaultencoding,    METH_NOARGS},
+    {"unicode_decode",           unicode_decode,                 METH_VARARGS},
+    {"unicode_asencodedstring",  unicode_asencodedstring,        METH_VARARGS},
+    {"unicode_buildencodingmap", unicode_buildencodingmap,       METH_O},
+    {"unicode_decodeutf7",       unicode_decodeutf7,             METH_VARARGS},
+    {"unicode_decodeutf7stateful",unicode_decodeutf7stateful,    METH_VARARGS},
+    {"unicode_decodeutf8",       unicode_decodeutf8,             METH_VARARGS},
+    {"unicode_decodeutf8stateful",unicode_decodeutf8stateful,    METH_VARARGS},
+    {"unicode_asutf8string",     unicode_asutf8string,           METH_O},
+    {"unicode_decodeutf16",      unicode_decodeutf16,            METH_VARARGS},
+    {"unicode_decodeutf16stateful",unicode_decodeutf16stateful,  METH_VARARGS},
+    {"unicode_asutf16string",    unicode_asutf16string,          METH_O},
+    {"unicode_decodeutf32",      unicode_decodeutf32,            METH_VARARGS},
+    {"unicode_decodeutf32stateful",unicode_decodeutf32stateful,  METH_VARARGS},
+    {"unicode_asutf32string",    unicode_asutf32string,          METH_O},
+    {"unicode_decodeunicodeescape",unicode_decodeunicodeescape,  METH_VARARGS},
+    {"unicode_asunicodeescapestring",unicode_asunicodeescapestring,METH_O},
+    {"unicode_decoderawunicodeescape",unicode_decoderawunicodeescape,METH_VARARGS},
+    {"unicode_asrawunicodeescapestring",unicode_asrawunicodeescapestring,METH_O},
+    {"unicode_decodelatin1",     unicode_decodelatin1,           METH_VARARGS},
+    {"unicode_aslatin1string",   unicode_aslatin1string,         METH_O},
+    {"unicode_decodeascii",      unicode_decodeascii,            METH_VARARGS},
+    {"unicode_asasciistring",    unicode_asasciistring,          METH_O},
+    {"unicode_decodecharmap",    unicode_decodecharmap,          METH_VARARGS},
+    {"unicode_ascharmapstring",  unicode_ascharmapstring,        METH_VARARGS},
+#ifdef MS_WINDOWS
+    {"unicode_decodembcs",       unicode_decodembcs,             METH_VARARGS},
+    {"unicode_decodembcsstateful",unicode_decodembcsstateful,    METH_VARARGS},
+    {"unicode_decodecodepagestateful",unicode_decodecodepagestateful,METH_VARARGS},
+    {"unicode_asmbcsstring",     unicode_asmbcsstring,           METH_O},
+    {"unicode_encodecodepage",   unicode_encodecodepage,         METH_VARARGS},
+#endif /* MS_WINDOWS */
+    {"unicode_decodelocaleandsize",unicode_decodelocaleandsize,  METH_VARARGS},
+    {"unicode_decodelocale",     unicode_decodelocale,           METH_VARARGS},
+    {"unicode_encodelocale",     unicode_encodelocale,           METH_VARARGS},
+    {"unicode_decodefsdefault",  unicode_decodefsdefault,        METH_VARARGS},
+    {"unicode_decodefsdefaultandsize",unicode_decodefsdefaultandsize,METH_VARARGS},
+    {"unicode_encodefsdefault",  unicode_encodefsdefault,        METH_O},
+    {"unicode_concat",           unicode_concat,                 METH_VARARGS},
+    {"unicode_splitlines",       unicode_splitlines,             METH_VARARGS},
+    {"unicode_split",            unicode_split,                  METH_VARARGS},
+    {"unicode_rsplit",           unicode_rsplit,                 METH_VARARGS},
+    {"unicode_partition",        unicode_partition,              METH_VARARGS},
+    {"unicode_rpartition",       unicode_rpartition,             METH_VARARGS},
+    {"unicode_translate",        unicode_translate,              METH_VARARGS},
+    {"unicode_join",             unicode_join,                   METH_VARARGS},
+    {"unicode_count",            unicode_count,                  METH_VARARGS},
+    {"unicode_tailmatch",        unicode_tailmatch,              METH_VARARGS},
+    {"unicode_find",             unicode_find,                   METH_VARARGS},
+    {"unicode_findchar",         unicode_findchar,               METH_VARARGS},
+    {"unicode_replace",          unicode_replace,                METH_VARARGS},
+    {"unicode_compare",          unicode_compare,                METH_VARARGS},
+    {"unicode_comparewithasciistring",unicode_comparewithasciistring,METH_VARARGS},
+    {"unicode_equaltoutf8",      unicode_equaltoutf8,            METH_VARARGS},
+    {"unicode_equaltoutf8andsize",unicode_equaltoutf8andsize,    METH_VARARGS},
+    {"unicode_richcompare",      unicode_richcompare,            METH_VARARGS},
+    {"unicode_format",           unicode_format,                 METH_VARARGS},
+    {"unicode_contains",         unicode_contains,               METH_VARARGS},
+    {"unicode_isidentifier",     unicode_isidentifier,           METH_O},
+    {NULL},
+};
+
+int
+_PyTestLimitedCAPI_Init_Unicode(PyObject *m)
+{
+    if (PyModule_AddFunctions(m, TestMethods) < 0) {
+        return -1;
+    }
+
+    return 0;
+}
index 43136697c5dac049fbf46b74605aa2dfe60af196..3715d82f1e35ab12b78091723ea2159eafb6f7dc 100644 (file)
     <ClCompile Include="..\Modules\_testlimitedcapi\pyos.c" />
     <ClCompile Include="..\Modules\_testlimitedcapi\set.c" />
     <ClCompile Include="..\Modules\_testlimitedcapi\sys.c" />
+    <ClCompile Include="..\Modules\_testlimitedcapi\unicode.c" />
     <ClCompile Include="..\Modules\_testlimitedcapi\vectorcall_limited.c" />
   </ItemGroup>
   <ItemGroup>
index d3cdc47957eed5c44685685685036c8a9702158f..29177dfcc44067453d7fdd921bbe8d579f99b58f 100644 (file)
@@ -18,6 +18,7 @@
     <ClCompile Include="..\Modules\_testlimitedcapi\pyos.c" />
     <ClCompile Include="..\Modules\_testlimitedcapi\set.c" />
     <ClCompile Include="..\Modules\_testlimitedcapi\sys.c" />
+    <ClCompile Include="..\Modules\_testlimitedcapi\unicode.c" />
     <ClCompile Include="..\Modules\_testlimitedcapi\vectorcall_limited.c" />
     <ClCompile Include="..\Modules\_testlimitedcapi.c" />
   </ItemGroup>