mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Update str related tests from 3.13.5 (#5953)
* Update str related tests from 3.13.5 * Apply RustPython patches * Mark new failing tests
This commit is contained in:
1 parent
fef660e6b3
commit
e75aebb967
8 files changed
+464
-163
No files matched your search
Vendored
+83
-30
@@ -8,18 +8,12 @@ from test.support import import_helper
|
||||
from collections import UserList
|
||||
import random
|
||||
|
||||
|
||||
class Sequence:
|
||||
def __init__(self, seq='wxyz'): self.seq = seq
|
||||
def __len__(self): return len(self.seq)
|
||||
def __getitem__(self, i): return self.seq[i]
|
||||
|
||||
class BadSeq1(Sequence):
|
||||
def __init__(self): self.seq = [7, 'hello', 123]
|
||||
def __str__(self): return '{0} {1} {2}'.format(*self.seq)
|
||||
|
||||
class BadSeq2(Sequence):
|
||||
def __init__(self): self.seq = ['a', 'b', 'c']
|
||||
def __len__(self): return 8
|
||||
|
||||
class BaseTest:
|
||||
# These tests are for buffers of values (bytes) and not
|
||||
@@ -27,7 +21,7 @@ class BaseTest:
|
||||
# and various string implementations
|
||||
|
||||
# The type to be tested
|
||||
# Change in subclasses to change the behaviour of fixtesttype()
|
||||
# Change in subclasses to change the behaviour of fixtype()
|
||||
type2test = None
|
||||
|
||||
# Whether the "contained items" of the container are integers in
|
||||
@@ -36,7 +30,7 @@ class BaseTest:
|
||||
contains_bytes = False
|
||||
|
||||
# All tests pass their arguments to the testing methods
|
||||
# as str objects. fixtesttype() can be used to propagate
|
||||
# as str objects. fixtype() can be used to propagate
|
||||
# these arguments to the appropriate type
|
||||
def fixtype(self, obj):
|
||||
if isinstance(obj, str):
|
||||
@@ -160,6 +154,14 @@ class BaseTest:
|
||||
self.assertEqual(rem, 0, '%s != 0 for %s' % (rem, i))
|
||||
self.assertEqual(r1, r2, '%s != %s for %s' % (r1, r2, i))
|
||||
|
||||
# TODO: RUSTPYTHON; TypeError: Unexpected keyword argument count
|
||||
@unittest.expectedFailure
|
||||
def test_count_keyword(self):
|
||||
self.assertEqual('aa'.replace('a', 'b', 0), 'aa'.replace('a', 'b', count=0))
|
||||
self.assertEqual('aa'.replace('a', 'b', 1), 'aa'.replace('a', 'b', count=1))
|
||||
self.assertEqual('aa'.replace('a', 'b', 2), 'aa'.replace('a', 'b', count=2))
|
||||
self.assertEqual('aa'.replace('a', 'b', 3), 'aa'.replace('a', 'b', count=3))
|
||||
|
||||
def test_find(self):
|
||||
self.checkequal(0, 'abcdefghiabc', 'find', 'abc')
|
||||
self.checkequal(9, 'abcdefghiabc', 'find', 'abc', 1)
|
||||
@@ -327,11 +329,12 @@ class BaseTest:
|
||||
for i in range(len(s)):
|
||||
if s.startswith(p, i):
|
||||
return i
|
||||
if p == '' and s == '':
|
||||
return 0
|
||||
return -1
|
||||
|
||||
rr = random.randrange
|
||||
choices = random.choices
|
||||
for _ in range(1000):
|
||||
def check_pattern(rr):
|
||||
choices = random.choices
|
||||
p0 = ''.join(choices('abcde', k=rr(10))) * rr(10, 20)
|
||||
p = p0[:len(p0) - rr(10)] # pop off some characters
|
||||
left = ''.join(choices('abcdef', k=rr(2000)))
|
||||
@@ -341,6 +344,49 @@ class BaseTest:
|
||||
self.checkequal(reference_find(p, text),
|
||||
text, 'find', p)
|
||||
|
||||
rr = random.randrange
|
||||
for _ in range(1000):
|
||||
check_pattern(rr)
|
||||
|
||||
# Test that empty string always work:
|
||||
check_pattern(lambda *args: 0)
|
||||
|
||||
def test_find_many_lengths(self):
|
||||
haystack_repeats = [a * 10**e for e in range(6) for a in (1,2,5)]
|
||||
haystacks = [(n, self.fixtype("abcab"*n + "da")) for n in haystack_repeats]
|
||||
|
||||
needle_repeats = [a * 10**e for e in range(6) for a in (1, 3)]
|
||||
needles = [(m, self.fixtype("abcab"*m + "da")) for m in needle_repeats]
|
||||
|
||||
for n, haystack1 in haystacks:
|
||||
haystack2 = haystack1[:-1]
|
||||
for m, needle in needles:
|
||||
answer1 = 5 * (n - m) if m <= n else -1
|
||||
self.assertEqual(haystack1.find(needle), answer1, msg=(n,m))
|
||||
self.assertEqual(haystack2.find(needle), -1, msg=(n,m))
|
||||
|
||||
def test_adaptive_find(self):
|
||||
# This would be very slow for the naive algorithm,
|
||||
# but str.find() should be O(n + m).
|
||||
for N in 1000, 10_000, 100_000, 1_000_000:
|
||||
A, B = 'a' * N, 'b' * N
|
||||
haystack = A + A + B + A + A
|
||||
needle = A + B + B + A
|
||||
self.checkequal(-1, haystack, 'find', needle)
|
||||
self.checkequal(0, haystack, 'count', needle)
|
||||
self.checkequal(len(haystack), haystack + needle, 'find', needle)
|
||||
self.checkequal(1, haystack + needle, 'count', needle)
|
||||
|
||||
def test_find_with_memory(self):
|
||||
# Test the "Skip with memory" path in the two-way algorithm.
|
||||
for N in 1000, 3000, 10_000, 30_000:
|
||||
needle = 'ab' * N
|
||||
haystack = ('ab'*(N-1) + 'b') * 2
|
||||
self.checkequal(-1, haystack, 'find', needle)
|
||||
self.checkequal(0, haystack, 'count', needle)
|
||||
self.checkequal(len(haystack), haystack + needle, 'find', needle)
|
||||
self.checkequal(1, haystack + needle, 'count', needle)
|
||||
|
||||
def test_find_shift_table_overflow(self):
|
||||
"""When the table of 8-bit shifts overflows."""
|
||||
N = 2**8 + 100
|
||||
@@ -724,6 +770,18 @@ class BaseTest:
|
||||
self.checkraises(TypeError, 'hello', 'replace', 42, 'h')
|
||||
self.checkraises(TypeError, 'hello', 'replace', 'h', 42)
|
||||
|
||||
def test_replace_uses_two_way_maxcount(self):
|
||||
# Test that maxcount works in _two_way_count in fastsearch.h
|
||||
A, B = "A"*1000, "B"*1000
|
||||
AABAA = A + A + B + A + A
|
||||
ABBA = A + B + B + A
|
||||
self.checkequal(AABAA + ABBA,
|
||||
AABAA + ABBA, 'replace', ABBA, "ccc", 0)
|
||||
self.checkequal(AABAA + "ccc",
|
||||
AABAA + ABBA, 'replace', ABBA, "ccc", 1)
|
||||
self.checkequal(AABAA + "ccc",
|
||||
AABAA + ABBA, 'replace', ABBA, "ccc", 2)
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON, may only apply to 32-bit platforms")
|
||||
@unittest.skipIf(sys.maxsize > (1 << 32) or struct.calcsize('P') != 4,
|
||||
'only applies to 32-bit platforms')
|
||||
@@ -734,8 +792,6 @@ class BaseTest:
|
||||
self.checkraises(OverflowError, A2_16, "replace", "A", A2_16)
|
||||
self.checkraises(OverflowError, A2_16, "replace", "AA", A2_16+A2_16)
|
||||
|
||||
|
||||
# Python 3.9
|
||||
def test_removeprefix(self):
|
||||
self.checkequal('am', 'spam', 'removeprefix', 'sp')
|
||||
self.checkequal('spamspam', 'spamspamspam', 'removeprefix', 'spam')
|
||||
@@ -754,7 +810,6 @@ class BaseTest:
|
||||
self.checkraises(TypeError, 'hello', 'removeprefix', 'h', 42)
|
||||
self.checkraises(TypeError, 'hello', 'removeprefix', ("he", "l"))
|
||||
|
||||
# Python 3.9
|
||||
def test_removesuffix(self):
|
||||
self.checkequal('sp', 'spam', 'removesuffix', 'am')
|
||||
self.checkequal('spamspam', 'spamspamspam', 'removesuffix', 'spam')
|
||||
@@ -1053,7 +1108,7 @@ class BaseTest:
|
||||
self.checkraises(TypeError, 'abc', 'splitlines', 42, 42)
|
||||
|
||||
|
||||
class CommonTest(BaseTest):
|
||||
class StringLikeTest(BaseTest):
|
||||
# This testcase contains tests that can be used in all
|
||||
# stringlike classes. Currently this is str and UserString.
|
||||
|
||||
@@ -1084,11 +1139,6 @@ class CommonTest(BaseTest):
|
||||
self.checkequal('\u019b\u1d00\u1d86\u0221\u1fb7',
|
||||
'\u019b\u1d00\u1d86\u0221\u1fb7', 'capitalize')
|
||||
|
||||
|
||||
class MixinStrUnicodeUserStringTest:
|
||||
# additional tests that only work for
|
||||
# stringlike objects, i.e. str, UserString
|
||||
|
||||
def test_startswith(self):
|
||||
self.checkequal(True, 'hello', 'startswith', 'he')
|
||||
self.checkequal(True, 'hello', 'startswith', 'hello')
|
||||
@@ -1273,8 +1323,11 @@ class MixinStrUnicodeUserStringTest:
|
||||
self.checkequal(((('a' * i) + '-') * i)[:-1], '-', 'join',
|
||||
('a' * i,) * i)
|
||||
|
||||
#self.checkequal(str(BadSeq1()), ' ', 'join', BadSeq1())
|
||||
self.checkequal('a b c', ' ', 'join', BadSeq2())
|
||||
class LiesAboutLengthSeq(Sequence):
|
||||
def __init__(self): self.seq = ['a', 'b', 'c']
|
||||
def __len__(self): return 8
|
||||
|
||||
self.checkequal('a b c', ' ', 'join', LiesAboutLengthSeq())
|
||||
|
||||
self.checkraises(TypeError, ' ', 'join')
|
||||
self.checkraises(TypeError, ' ', 'join', None)
|
||||
@@ -1459,19 +1512,19 @@ class MixinStrUnicodeUserStringTest:
|
||||
# issue 11828
|
||||
s = 'hello'
|
||||
x = 'x'
|
||||
self.assertRaisesRegex(TypeError, r'^find\(', s.find,
|
||||
self.assertRaisesRegex(TypeError, r'^find\b', s.find,
|
||||
x, None, None, None)
|
||||
self.assertRaisesRegex(TypeError, r'^rfind\(', s.rfind,
|
||||
self.assertRaisesRegex(TypeError, r'^rfind\b', s.rfind,
|
||||
x, None, None, None)
|
||||
self.assertRaisesRegex(TypeError, r'^index\(', s.index,
|
||||
self.assertRaisesRegex(TypeError, r'^index\b', s.index,
|
||||
x, None, None, None)
|
||||
self.assertRaisesRegex(TypeError, r'^rindex\(', s.rindex,
|
||||
self.assertRaisesRegex(TypeError, r'^rindex\b', s.rindex,
|
||||
x, None, None, None)
|
||||
self.assertRaisesRegex(TypeError, r'^count\(', s.count,
|
||||
self.assertRaisesRegex(TypeError, r'^count\b', s.count,
|
||||
x, None, None, None)
|
||||
self.assertRaisesRegex(TypeError, r'^startswith\(', s.startswith,
|
||||
self.assertRaisesRegex(TypeError, r'^startswith\b', s.startswith,
|
||||
x, None, None, None)
|
||||
self.assertRaisesRegex(TypeError, r'^endswith\(', s.endswith,
|
||||
self.assertRaisesRegex(TypeError, r'^endswith\b', s.endswith,
|
||||
x, None, None, None)
|
||||
|
||||
# issue #15534
|
||||
|
||||
Vendored
+172
-67
@@ -10,6 +10,7 @@ import re
|
||||
import sys
|
||||
import copy
|
||||
import functools
|
||||
import operator
|
||||
import pickle
|
||||
import tempfile
|
||||
import textwrap
|
||||
@@ -46,6 +47,10 @@ class Indexable:
|
||||
|
||||
class BaseBytesTest:
|
||||
|
||||
def assertTypedEqual(self, actual, expected):
|
||||
self.assertIs(type(actual), type(expected))
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
def test_basics(self):
|
||||
b = self.type2test()
|
||||
self.assertEqual(type(b), self.type2test)
|
||||
@@ -737,6 +742,37 @@ class BaseBytesTest:
|
||||
check(b'%i%b %*.*b', (10, b'3', 5, 3, b'abc',), b'103 abc')
|
||||
check(b'%c', b'a', b'a')
|
||||
|
||||
class PseudoFloat:
|
||||
def __init__(self, value):
|
||||
self.value = float(value)
|
||||
def __int__(self):
|
||||
return int(self.value)
|
||||
|
||||
pi = PseudoFloat(3.1415)
|
||||
|
||||
exceptions_params = [
|
||||
('%x format: an integer is required, not float', b'%x', 3.14),
|
||||
('%X format: an integer is required, not float', b'%X', 2.11),
|
||||
('%o format: an integer is required, not float', b'%o', 1.79),
|
||||
('%x format: an integer is required, not PseudoFloat', b'%x', pi),
|
||||
('%x format: an integer is required, not complex', b'%x', 3j),
|
||||
('%X format: an integer is required, not complex', b'%X', 2j),
|
||||
('%o format: an integer is required, not complex', b'%o', 1j),
|
||||
('%u format: a real number is required, not complex', b'%u', 3j),
|
||||
# See https://github.com/python/cpython/issues/130928 as for why
|
||||
# the exception message contains '%d' instead of '%i'.
|
||||
('%d format: a real number is required, not complex', b'%i', 2j),
|
||||
('%d format: a real number is required, not complex', b'%d', 2j),
|
||||
(
|
||||
r'%c requires an integer in range\(256\) or a single byte',
|
||||
b'%c', pi
|
||||
),
|
||||
]
|
||||
|
||||
for msg, format_bytes, value in exceptions_params:
|
||||
with self.assertRaisesRegex(TypeError, msg):
|
||||
operator.mod(format_bytes, value)
|
||||
|
||||
def test_imod(self):
|
||||
b = self.type2test(b'hello, %b!')
|
||||
orig = b
|
||||
@@ -995,13 +1031,13 @@ class BaseBytesTest:
|
||||
self.assertEqual(c, b'hllo')
|
||||
|
||||
def test_sq_item(self):
|
||||
_testcapi = import_helper.import_module('_testcapi')
|
||||
_testlimitedcapi = import_helper.import_module('_testlimitedcapi')
|
||||
obj = self.type2test((42,))
|
||||
with self.assertRaises(IndexError):
|
||||
_testcapi.sequence_getitem(obj, -2)
|
||||
_testlimitedcapi.sequence_getitem(obj, -2)
|
||||
with self.assertRaises(IndexError):
|
||||
_testcapi.sequence_getitem(obj, 1)
|
||||
self.assertEqual(_testcapi.sequence_getitem(obj, 0), 42)
|
||||
_testlimitedcapi.sequence_getitem(obj, 1)
|
||||
self.assertEqual(_testlimitedcapi.sequence_getitem(obj, 0), 42)
|
||||
|
||||
|
||||
class BytesTest(BaseBytesTest, unittest.TestCase):
|
||||
@@ -1031,36 +1067,63 @@ class BytesTest(BaseBytesTest, unittest.TestCase):
|
||||
self.assertRaises(TypeError, f.readinto, b"")
|
||||
|
||||
def test_custom(self):
|
||||
class A:
|
||||
def __bytes__(self):
|
||||
return b'abc'
|
||||
self.assertEqual(bytes(A()), b'abc')
|
||||
class A: pass
|
||||
self.assertRaises(TypeError, bytes, A())
|
||||
class A:
|
||||
def __bytes__(self):
|
||||
return None
|
||||
self.assertRaises(TypeError, bytes, A())
|
||||
class A:
|
||||
self.assertEqual(bytes(BytesSubclass(b'abc')), b'abc')
|
||||
self.assertEqual(BytesSubclass(OtherBytesSubclass(b'abc')),
|
||||
BytesSubclass(b'abc'))
|
||||
self.assertEqual(bytes(WithBytes(b'abc')), b'abc')
|
||||
self.assertEqual(BytesSubclass(WithBytes(b'abc')), BytesSubclass(b'abc'))
|
||||
|
||||
class NoBytes: pass
|
||||
self.assertRaises(TypeError, bytes, NoBytes())
|
||||
self.assertRaises(TypeError, bytes, WithBytes('abc'))
|
||||
self.assertRaises(TypeError, bytes, WithBytes(None))
|
||||
class IndexWithBytes:
|
||||
def __bytes__(self):
|
||||
return b'a'
|
||||
def __index__(self):
|
||||
return 42
|
||||
self.assertEqual(bytes(A()), b'a')
|
||||
self.assertEqual(bytes(IndexWithBytes()), b'a')
|
||||
# Issue #25766
|
||||
class A(str):
|
||||
class StrWithBytes(str):
|
||||
def __new__(cls, value):
|
||||
self = str.__new__(cls, '\u20ac')
|
||||
self.value = value
|
||||
return self
|
||||
def __bytes__(self):
|
||||
return b'abc'
|
||||
self.assertEqual(bytes(A('\u20ac')), b'abc')
|
||||
self.assertEqual(bytes(A('\u20ac'), 'iso8859-15'), b'\xa4')
|
||||
return self.value
|
||||
self.assertEqual(bytes(StrWithBytes(b'abc')), b'abc')
|
||||
self.assertEqual(bytes(StrWithBytes(b'abc'), 'iso8859-15'), b'\xa4')
|
||||
self.assertEqual(bytes(StrWithBytes(BytesSubclass(b'abc'))), b'abc')
|
||||
self.assertEqual(BytesSubclass(StrWithBytes(b'abc')), BytesSubclass(b'abc'))
|
||||
self.assertEqual(BytesSubclass(StrWithBytes(b'abc'), 'iso8859-15'),
|
||||
BytesSubclass(b'\xa4'))
|
||||
self.assertEqual(BytesSubclass(StrWithBytes(BytesSubclass(b'abc'))),
|
||||
BytesSubclass(b'abc'))
|
||||
self.assertEqual(BytesSubclass(StrWithBytes(OtherBytesSubclass(b'abc'))),
|
||||
BytesSubclass(b'abc'))
|
||||
# Issue #24731
|
||||
class A:
|
||||
self.assertTypedEqual(bytes(WithBytes(BytesSubclass(b'abc'))), BytesSubclass(b'abc'))
|
||||
self.assertTypedEqual(BytesSubclass(WithBytes(BytesSubclass(b'abc'))),
|
||||
BytesSubclass(b'abc'))
|
||||
self.assertTypedEqual(BytesSubclass(WithBytes(OtherBytesSubclass(b'abc'))),
|
||||
BytesSubclass(b'abc'))
|
||||
|
||||
class BytesWithBytes(bytes):
|
||||
def __new__(cls, value):
|
||||
self = bytes.__new__(cls, b'\xa4')
|
||||
self.value = value
|
||||
return self
|
||||
def __bytes__(self):
|
||||
return OtherBytesSubclass(b'abc')
|
||||
self.assertEqual(bytes(A()), b'abc')
|
||||
self.assertIs(type(bytes(A())), OtherBytesSubclass)
|
||||
self.assertEqual(BytesSubclass(A()), b'abc')
|
||||
self.assertIs(type(BytesSubclass(A())), BytesSubclass)
|
||||
return self.value
|
||||
self.assertTypedEqual(bytes(BytesWithBytes(b'abc')), b'abc')
|
||||
self.assertTypedEqual(BytesSubclass(BytesWithBytes(b'abc')),
|
||||
BytesSubclass(b'abc'))
|
||||
self.assertTypedEqual(bytes(BytesWithBytes(BytesSubclass(b'abc'))),
|
||||
BytesSubclass(b'abc'))
|
||||
self.assertTypedEqual(BytesSubclass(BytesWithBytes(BytesSubclass(b'abc'))),
|
||||
BytesSubclass(b'abc'))
|
||||
self.assertTypedEqual(BytesSubclass(BytesWithBytes(OtherBytesSubclass(b'abc'))),
|
||||
BytesSubclass(b'abc'))
|
||||
|
||||
# Test PyBytes_FromFormat()
|
||||
def test_from_format(self):
|
||||
@@ -1233,6 +1296,8 @@ class BytesTest(BaseBytesTest, unittest.TestCase):
|
||||
class ByteArrayTest(BaseBytesTest, unittest.TestCase):
|
||||
type2test = bytearray
|
||||
|
||||
_testlimitedcapi = import_helper.import_module('_testlimitedcapi')
|
||||
|
||||
def test_getitem_error(self):
|
||||
b = bytearray(b'python')
|
||||
msg = "bytearray indices must be integers or slices"
|
||||
@@ -1325,47 +1390,73 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
|
||||
self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")])
|
||||
|
||||
def test_setitem(self):
|
||||
b = bytearray([1, 2, 3])
|
||||
b[1] = 100
|
||||
self.assertEqual(b, bytearray([1, 100, 3]))
|
||||
b[-1] = 200
|
||||
self.assertEqual(b, bytearray([1, 100, 200]))
|
||||
b[0] = Indexable(10)
|
||||
self.assertEqual(b, bytearray([10, 100, 200]))
|
||||
try:
|
||||
b[3] = 0
|
||||
self.fail("Didn't raise IndexError")
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
b[-10] = 0
|
||||
self.fail("Didn't raise IndexError")
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
b[0] = 256
|
||||
self.fail("Didn't raise ValueError")
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
b[0] = Indexable(-1)
|
||||
self.fail("Didn't raise ValueError")
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
b[0] = None
|
||||
self.fail("Didn't raise TypeError")
|
||||
except TypeError:
|
||||
pass
|
||||
def setitem_as_mapping(b, i, val):
|
||||
b[i] = val
|
||||
|
||||
def setitem_as_sequence(b, i, val):
|
||||
self._testlimitedcapi.sequence_setitem(b, i, val)
|
||||
|
||||
def do_tests(setitem):
|
||||
b = bytearray([1, 2, 3])
|
||||
setitem(b, 1, 100)
|
||||
self.assertEqual(b, bytearray([1, 100, 3]))
|
||||
setitem(b, -1, 200)
|
||||
self.assertEqual(b, bytearray([1, 100, 200]))
|
||||
setitem(b, 0, Indexable(10))
|
||||
self.assertEqual(b, bytearray([10, 100, 200]))
|
||||
try:
|
||||
setitem(b, 3, 0)
|
||||
self.fail("Didn't raise IndexError")
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
setitem(b, -10, 0)
|
||||
self.fail("Didn't raise IndexError")
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
setitem(b, 0, 256)
|
||||
self.fail("Didn't raise ValueError")
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
setitem(b, 0, Indexable(-1))
|
||||
self.fail("Didn't raise ValueError")
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
setitem(b, 0, object())
|
||||
self.fail("Didn't raise TypeError")
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
with self.subTest("tp_as_mapping"):
|
||||
do_tests(setitem_as_mapping)
|
||||
|
||||
with self.subTest("tp_as_sequence"):
|
||||
do_tests(setitem_as_sequence)
|
||||
|
||||
def test_delitem(self):
|
||||
b = bytearray(range(10))
|
||||
del b[0]
|
||||
self.assertEqual(b, bytearray(range(1, 10)))
|
||||
del b[-1]
|
||||
self.assertEqual(b, bytearray(range(1, 9)))
|
||||
del b[4]
|
||||
self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
|
||||
def del_as_mapping(b, i):
|
||||
del b[i]
|
||||
|
||||
def del_as_sequence(b, i):
|
||||
self._testlimitedcapi.sequence_delitem(b, i)
|
||||
|
||||
def do_tests(delete):
|
||||
b = bytearray(range(10))
|
||||
delete(b, 0)
|
||||
self.assertEqual(b, bytearray(range(1, 10)))
|
||||
delete(b, -1)
|
||||
self.assertEqual(b, bytearray(range(1, 9)))
|
||||
delete(b, 4)
|
||||
self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8]))
|
||||
|
||||
with self.subTest("tp_as_mapping"):
|
||||
do_tests(del_as_mapping)
|
||||
|
||||
with self.subTest("tp_as_sequence"):
|
||||
do_tests(del_as_sequence)
|
||||
|
||||
def test_setslice(self):
|
||||
b = bytearray(range(10))
|
||||
@@ -1558,6 +1649,13 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
|
||||
a = bytearray(b'')
|
||||
a.extend([Indexable(ord('a'))])
|
||||
self.assertEqual(a, b'a')
|
||||
a = bytearray(b'abc')
|
||||
self.assertRaisesRegex(TypeError, # Override for string.
|
||||
"expected iterable of integers; got: 'str'",
|
||||
a.extend, 'def')
|
||||
self.assertRaisesRegex(TypeError, # But not for others.
|
||||
"can't extend bytearray with float",
|
||||
a.extend, 1.0)
|
||||
|
||||
def test_remove(self):
|
||||
b = bytearray(b'hello')
|
||||
@@ -1747,6 +1845,8 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
|
||||
self.assertEqual(b3, b'xcxcxc')
|
||||
|
||||
def test_mutating_index(self):
|
||||
# See gh-91153
|
||||
|
||||
class Boom:
|
||||
def __index__(self):
|
||||
b.clear()
|
||||
@@ -1758,10 +1858,9 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
|
||||
b[0] = Boom()
|
||||
|
||||
with self.subTest("tp_as_sequence"):
|
||||
_testcapi = import_helper.import_module('_testcapi')
|
||||
b = bytearray(b'Now you see me...')
|
||||
with self.assertRaises(IndexError):
|
||||
_testcapi.sequence_setitem(b, 0, Boom())
|
||||
self._testlimitedcapi.sequence_setitem(b, 0, Boom())
|
||||
|
||||
|
||||
class AssortedBytesTest(unittest.TestCase):
|
||||
@@ -2060,6 +2159,12 @@ class BytesSubclass(bytes):
|
||||
class OtherBytesSubclass(bytes):
|
||||
pass
|
||||
|
||||
class WithBytes:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __bytes__(self):
|
||||
return self.value
|
||||
|
||||
class ByteArraySubclassTest(SubclassTest, unittest.TestCase):
|
||||
basetype = bytearray
|
||||
type2test = ByteArraySubclass
|
||||
|
||||
+142
-50
@@ -7,6 +7,7 @@ Written by Marc-Andre Lemburg (mal@lemburg.com).
|
||||
"""
|
||||
import _string
|
||||
import codecs
|
||||
import datetime
|
||||
import itertools
|
||||
import operator
|
||||
import pickle
|
||||
@@ -55,8 +56,22 @@ def duplicate_string(text):
|
||||
class StrSubclass(str):
|
||||
pass
|
||||
|
||||
class UnicodeTest(string_tests.CommonTest,
|
||||
string_tests.MixinStrUnicodeUserStringTest,
|
||||
class OtherStrSubclass(str):
|
||||
pass
|
||||
|
||||
class WithStr:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
class WithRepr:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __repr__(self):
|
||||
return self.value
|
||||
|
||||
class StrTest(string_tests.StringLikeTest,
|
||||
string_tests.MixinStrUnicodeTest,
|
||||
unittest.TestCase):
|
||||
|
||||
@@ -84,6 +99,10 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertEqual(realresult, result)
|
||||
self.assertTrue(object is not realresult)
|
||||
|
||||
def assertTypedEqual(self, actual, expected):
|
||||
self.assertIs(type(actual), type(expected))
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
def test_literals(self):
|
||||
self.assertEqual('\xff', '\u00ff')
|
||||
self.assertEqual('\uffff', '\U0000ffff')
|
||||
@@ -93,6 +112,8 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
# raw strings should not have unicode escapes
|
||||
self.assertNotEqual(r"\u0020", " ")
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_ascii(self):
|
||||
self.assertEqual(ascii('abc'), "'abc'")
|
||||
self.assertEqual(ascii('ab\\c'), "'ab\\\\c'")
|
||||
@@ -128,10 +149,13 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertEqual(ascii("\U00010000" * 39 + "\uffff" * 4096),
|
||||
ascii("\U00010000" * 39 + "\uffff" * 4096))
|
||||
|
||||
class WrongRepr:
|
||||
def __repr__(self):
|
||||
return b'byte-repr'
|
||||
self.assertRaises(TypeError, ascii, WrongRepr())
|
||||
self.assertTypedEqual(ascii('\U0001f40d'), r"'\U0001f40d'")
|
||||
self.assertTypedEqual(ascii(StrSubclass('abc')), "'abc'")
|
||||
self.assertTypedEqual(ascii(WithRepr('<abc>')), '<abc>')
|
||||
self.assertTypedEqual(ascii(WithRepr(StrSubclass('<abc>'))), StrSubclass('<abc>'))
|
||||
self.assertTypedEqual(ascii(WithRepr('<\U0001f40d>')), r'<\U0001f40d>')
|
||||
self.assertTypedEqual(ascii(WithRepr(StrSubclass('<\U0001f40d>'))), r'<\U0001f40d>')
|
||||
self.assertRaises(TypeError, ascii, WithRepr(b'byte-repr'))
|
||||
|
||||
def test_repr(self):
|
||||
# Test basic sanity of repr()
|
||||
@@ -169,10 +193,13 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertEqual(repr("\U00010000" * 39 + "\uffff" * 4096),
|
||||
repr("\U00010000" * 39 + "\uffff" * 4096))
|
||||
|
||||
class WrongRepr:
|
||||
def __repr__(self):
|
||||
return b'byte-repr'
|
||||
self.assertRaises(TypeError, repr, WrongRepr())
|
||||
self.assertTypedEqual(repr('\U0001f40d'), "'\U0001f40d'")
|
||||
self.assertTypedEqual(repr(StrSubclass('abc')), "'abc'")
|
||||
self.assertTypedEqual(repr(WithRepr('<abc>')), '<abc>')
|
||||
self.assertTypedEqual(repr(WithRepr(StrSubclass('<abc>'))), StrSubclass('<abc>'))
|
||||
self.assertTypedEqual(repr(WithRepr('<\U0001f40d>')), '<\U0001f40d>')
|
||||
self.assertTypedEqual(repr(WithRepr(StrSubclass('<\U0001f40d>'))), StrSubclass('<\U0001f40d>'))
|
||||
self.assertRaises(TypeError, repr, WithRepr(b'byte-repr'))
|
||||
|
||||
def test_iterators(self):
|
||||
# Make sure unicode objects have an __iter__ method
|
||||
@@ -213,7 +240,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertEqual(case, pickled)
|
||||
|
||||
def test_count(self):
|
||||
string_tests.CommonTest.test_count(self)
|
||||
string_tests.StringLikeTest.test_count(self)
|
||||
# check mixed argument types
|
||||
self.checkequalnofix(3, 'aaa', 'count', 'a')
|
||||
self.checkequalnofix(0, 'aaa', 'count', 'b')
|
||||
@@ -243,7 +270,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.checkequal(3, MyStr('aaa'), 'count', 'a')
|
||||
|
||||
def test_find(self):
|
||||
string_tests.CommonTest.test_find(self)
|
||||
string_tests.StringLikeTest.test_find(self)
|
||||
# test implementation details of the memchr fast path
|
||||
self.checkequal(100, 'a' * 100 + '\u0102', 'find', '\u0102')
|
||||
self.checkequal(-1, 'a' * 100 + '\u0102', 'find', '\u0201')
|
||||
@@ -288,7 +315,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.checkequal(-1, '\u0102' * 100, 'find', '\u0102\U00100304')
|
||||
|
||||
def test_rfind(self):
|
||||
string_tests.CommonTest.test_rfind(self)
|
||||
string_tests.StringLikeTest.test_rfind(self)
|
||||
# test implementation details of the memrchr fast path
|
||||
self.checkequal(0, '\u0102' + 'a' * 100 , 'rfind', '\u0102')
|
||||
self.checkequal(-1, '\u0102' + 'a' * 100 , 'rfind', '\u0201')
|
||||
@@ -329,7 +356,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.checkequal(-1, '\u0102' * 100, 'rfind', '\U00100304\u0102')
|
||||
|
||||
def test_index(self):
|
||||
string_tests.CommonTest.test_index(self)
|
||||
string_tests.StringLikeTest.test_index(self)
|
||||
self.checkequalnofix(0, 'abcdefghiabc', 'index', '')
|
||||
self.checkequalnofix(3, 'abcdefghiabc', 'index', 'def')
|
||||
self.checkequalnofix(0, 'abcdefghiabc', 'index', 'abc')
|
||||
@@ -353,7 +380,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertRaises(ValueError, ('\u0102' * 100).index, '\u0102\U00100304')
|
||||
|
||||
def test_rindex(self):
|
||||
string_tests.CommonTest.test_rindex(self)
|
||||
string_tests.StringLikeTest.test_rindex(self)
|
||||
self.checkequalnofix(12, 'abcdefghiabc', 'rindex', '')
|
||||
self.checkequalnofix(3, 'abcdefghiabc', 'rindex', 'def')
|
||||
self.checkequalnofix(9, 'abcdefghiabc', 'rindex', 'abc')
|
||||
@@ -449,7 +476,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertRaises(TypeError, 'abababc'.translate, 'abc', 'xyz')
|
||||
|
||||
def test_split(self):
|
||||
string_tests.CommonTest.test_split(self)
|
||||
string_tests.StringLikeTest.test_split(self)
|
||||
|
||||
# test mixed kinds
|
||||
for left, right in ('ba', '\u0101\u0100', '\U00010301\U00010300'):
|
||||
@@ -466,7 +493,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
left + delim * 2 + right, 'split', delim *2)
|
||||
|
||||
def test_rsplit(self):
|
||||
string_tests.CommonTest.test_rsplit(self)
|
||||
string_tests.StringLikeTest.test_rsplit(self)
|
||||
# test mixed kinds
|
||||
for left, right in ('ba', 'юё', '\u0101\u0100', '\U00010301\U00010300'):
|
||||
left *= 9
|
||||
@@ -486,7 +513,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
left + right, 'rsplit', None)
|
||||
|
||||
def test_partition(self):
|
||||
string_tests.MixinStrUnicodeUserStringTest.test_partition(self)
|
||||
string_tests.StringLikeTest.test_partition(self)
|
||||
# test mixed kinds
|
||||
self.checkequal(('ABCDEFGH', '', ''), 'ABCDEFGH', 'partition', '\u4200')
|
||||
for left, right in ('ba', '\u0101\u0100', '\U00010301\U00010300'):
|
||||
@@ -503,7 +530,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
left + delim * 2 + right, 'partition', delim * 2)
|
||||
|
||||
def test_rpartition(self):
|
||||
string_tests.MixinStrUnicodeUserStringTest.test_rpartition(self)
|
||||
string_tests.StringLikeTest.test_rpartition(self)
|
||||
# test mixed kinds
|
||||
self.checkequal(('', '', 'ABCDEFGH'), 'ABCDEFGH', 'rpartition', '\u4200')
|
||||
for left, right in ('ba', '\u0101\u0100', '\U00010301\U00010300'):
|
||||
@@ -520,7 +547,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
left + delim * 2 + right, 'rpartition', delim * 2)
|
||||
|
||||
def test_join(self):
|
||||
string_tests.MixinStrUnicodeUserStringTest.test_join(self)
|
||||
string_tests.StringLikeTest.test_join(self)
|
||||
|
||||
class MyWrapper:
|
||||
def __init__(self, sval): self.sval = sval
|
||||
@@ -548,7 +575,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertRaises(OverflowError, ''.join, seq)
|
||||
|
||||
def test_replace(self):
|
||||
string_tests.CommonTest.test_replace(self)
|
||||
string_tests.StringLikeTest.test_replace(self)
|
||||
|
||||
# method call forwarded from str implementation because of unicode argument
|
||||
self.checkequalnofix('one@two!three!', 'one!two!three!', 'replace', '!', '@', 1)
|
||||
@@ -831,6 +858,15 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertTrue('\U0001F46F'.isprintable())
|
||||
self.assertFalse('\U000E0020'.isprintable())
|
||||
|
||||
@support.requires_resource('cpu')
|
||||
def test_isprintable_invariant(self):
|
||||
for codepoint in range(sys.maxunicode + 1):
|
||||
char = chr(codepoint)
|
||||
category = unicodedata.category(char)
|
||||
self.assertEqual(char.isprintable(),
|
||||
category[0] not in ('C', 'Z')
|
||||
or char == ' ')
|
||||
|
||||
def test_surrogates(self):
|
||||
for s in ('a\uD800b\uDFFF', 'a\uDFFFb\uD800',
|
||||
'a\uD800b\uDFFFa', 'a\uDFFFb\uD800a'):
|
||||
@@ -859,7 +895,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
|
||||
|
||||
def test_lower(self):
|
||||
string_tests.CommonTest.test_lower(self)
|
||||
string_tests.StringLikeTest.test_lower(self)
|
||||
self.assertEqual('\U00010427'.lower(), '\U0001044F')
|
||||
self.assertEqual('\U00010427\U00010427'.lower(),
|
||||
'\U0001044F\U0001044F')
|
||||
@@ -890,7 +926,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertEqual('\u00b5'.casefold(), '\u03bc')
|
||||
|
||||
def test_upper(self):
|
||||
string_tests.CommonTest.test_upper(self)
|
||||
string_tests.StringLikeTest.test_upper(self)
|
||||
self.assertEqual('\U0001044F'.upper(), '\U00010427')
|
||||
self.assertEqual('\U0001044F\U0001044F'.upper(),
|
||||
'\U00010427\U00010427')
|
||||
@@ -909,7 +945,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_capitalize(self):
|
||||
string_tests.CommonTest.test_capitalize(self)
|
||||
string_tests.StringLikeTest.test_capitalize(self)
|
||||
self.assertEqual('\U0001044F'.capitalize(), '\U00010427')
|
||||
self.assertEqual('\U0001044F\U0001044F'.capitalize(),
|
||||
'\U00010427\U0001044F')
|
||||
@@ -947,7 +983,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_swapcase(self):
|
||||
string_tests.CommonTest.test_swapcase(self)
|
||||
string_tests.StringLikeTest.test_swapcase(self)
|
||||
self.assertEqual('\U0001044F'.swapcase(), '\U00010427')
|
||||
self.assertEqual('\U00010427'.swapcase(), '\U0001044F')
|
||||
self.assertEqual('\U0001044F\U0001044F'.swapcase(),
|
||||
@@ -973,7 +1009,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertEqual('\u1fd2'.swapcase(), '\u0399\u0308\u0300')
|
||||
|
||||
def test_center(self):
|
||||
string_tests.CommonTest.test_center(self)
|
||||
string_tests.StringLikeTest.test_center(self)
|
||||
self.assertEqual('x'.center(2, '\U0010FFFF'),
|
||||
'x\U0010FFFF')
|
||||
self.assertEqual('x'.center(3, '\U0010FFFF'),
|
||||
@@ -1483,7 +1519,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_formatting(self):
|
||||
string_tests.MixinStrUnicodeUserStringTest.test_formatting(self)
|
||||
string_tests.StringLikeTest.test_formatting(self)
|
||||
# Testing Unicode formatting strings...
|
||||
self.assertEqual("%s, %s" % ("abc", "abc"), 'abc, abc')
|
||||
self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", 1, 2, 3), 'abc, abc, 1, 2.000000, 3.00')
|
||||
@@ -1659,7 +1695,7 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertIn('str', exc)
|
||||
self.assertIn('tuple', exc)
|
||||
|
||||
@support.run_with_locale('LC_ALL', 'de_DE', 'fr_FR')
|
||||
@support.run_with_locale('LC_ALL', 'de_DE', 'fr_FR', '')
|
||||
def test_format_float(self):
|
||||
# should not format with a comma, but always with C locale
|
||||
self.assertEqual('1.0', '%.1f' % 1.0)
|
||||
@@ -1730,8 +1766,6 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
'character buffers are decoded to unicode'
|
||||
)
|
||||
|
||||
self.assertRaises(TypeError, str, 42, 42, 42)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_constructor_keyword_args(self):
|
||||
@@ -1910,6 +1944,12 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.assertRaises(UnicodeDecodeError,
|
||||
(b'\xF4'+cb+b'\xBF\xBF').decode, 'utf-8')
|
||||
|
||||
def test_issue127903(self):
|
||||
# gh-127903: ``_copy_characters`` crashes on DEBUG builds when
|
||||
# there is nothing to copy.
|
||||
d = datetime.datetime(2013, 11, 10, 14, 20, 59)
|
||||
self.assertEqual(d.strftime('%z'), '')
|
||||
|
||||
def test_issue8271(self):
|
||||
# Issue #8271: during the decoding of an invalid UTF-8 byte sequence,
|
||||
# only the start byte and the continuation byte(s) are now considered
|
||||
@@ -2396,28 +2436,37 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
@unittest.expectedFailure
|
||||
def test_conversion(self):
|
||||
# Make sure __str__() works properly
|
||||
class ObjectToStr:
|
||||
def __str__(self):
|
||||
return "foo"
|
||||
|
||||
class StrSubclassToStr(str):
|
||||
def __str__(self):
|
||||
return "foo"
|
||||
|
||||
class StrSubclassToStrSubclass(str):
|
||||
def __new__(cls, content=""):
|
||||
return str.__new__(cls, 2*content)
|
||||
def __str__(self):
|
||||
class StrWithStr(str):
|
||||
def __new__(cls, value):
|
||||
self = str.__new__(cls, "")
|
||||
self.value = value
|
||||
return self
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
self.assertEqual(str(ObjectToStr()), "foo")
|
||||
self.assertEqual(str(StrSubclassToStr("bar")), "foo")
|
||||
s = str(StrSubclassToStrSubclass("foo"))
|
||||
self.assertEqual(s, "foofoo")
|
||||
self.assertIs(type(s), StrSubclassToStrSubclass)
|
||||
s = StrSubclass(StrSubclassToStrSubclass("foo"))
|
||||
self.assertEqual(s, "foofoo")
|
||||
self.assertIs(type(s), StrSubclass)
|
||||
self.assertTypedEqual(str(WithStr('abc')), 'abc')
|
||||
self.assertTypedEqual(str(WithStr(StrSubclass('abc'))), StrSubclass('abc'))
|
||||
self.assertTypedEqual(StrSubclass(WithStr('abc')), StrSubclass('abc'))
|
||||
self.assertTypedEqual(StrSubclass(WithStr(StrSubclass('abc'))),
|
||||
StrSubclass('abc'))
|
||||
self.assertTypedEqual(StrSubclass(WithStr(OtherStrSubclass('abc'))),
|
||||
StrSubclass('abc'))
|
||||
|
||||
self.assertTypedEqual(str(StrWithStr('abc')), 'abc')
|
||||
self.assertTypedEqual(str(StrWithStr(StrSubclass('abc'))), StrSubclass('abc'))
|
||||
self.assertTypedEqual(StrSubclass(StrWithStr('abc')), StrSubclass('abc'))
|
||||
self.assertTypedEqual(StrSubclass(StrWithStr(StrSubclass('abc'))),
|
||||
StrSubclass('abc'))
|
||||
self.assertTypedEqual(StrSubclass(StrWithStr(OtherStrSubclass('abc'))),
|
||||
StrSubclass('abc'))
|
||||
|
||||
self.assertTypedEqual(str(WithRepr('<abc>')), '<abc>')
|
||||
self.assertTypedEqual(str(WithRepr(StrSubclass('<abc>'))), StrSubclass('<abc>'))
|
||||
self.assertTypedEqual(StrSubclass(WithRepr('<abc>')), StrSubclass('<abc>'))
|
||||
self.assertTypedEqual(StrSubclass(WithRepr(StrSubclass('<abc>'))),
|
||||
StrSubclass('<abc>'))
|
||||
self.assertTypedEqual(StrSubclass(WithRepr(OtherStrSubclass('<abc>'))),
|
||||
StrSubclass('<abc>'))
|
||||
|
||||
def test_unicode_repr(self):
|
||||
class s1:
|
||||
@@ -2652,6 +2701,49 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
proc = assert_python_failure('-X', 'dev', '-c', code)
|
||||
self.assertEqual(proc.rc, 10, proc)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_str_invalid_call(self):
|
||||
# too many args
|
||||
with self.assertRaisesRegex(TypeError, r"str expected at most 3 arguments, got 4"):
|
||||
str("too", "many", "argu", "ments")
|
||||
with self.assertRaisesRegex(TypeError, r"str expected at most 3 arguments, got 4"):
|
||||
str(1, "", "", 1)
|
||||
|
||||
# no such kw arg
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) got an unexpected keyword argument 'test'"):
|
||||
str(test=1)
|
||||
|
||||
# 'encoding' must be str
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not int"):
|
||||
str(1, 1)
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not int"):
|
||||
str(1, encoding=1)
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not bytes"):
|
||||
str(b"x", b"ascii")
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not bytes"):
|
||||
str(b"x", encoding=b"ascii")
|
||||
|
||||
# 'errors' must be str
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'encoding' must be str, not int"):
|
||||
str(1, 1, 1)
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not int"):
|
||||
str(1, errors=1)
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not int"):
|
||||
str(1, "", errors=1)
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not bytes"):
|
||||
str(b"x", "ascii", b"strict")
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) argument 'errors' must be str, not bytes"):
|
||||
str(b"x", "ascii", errors=b"strict")
|
||||
|
||||
# both positional and kwarg
|
||||
with self.assertRaisesRegex(TypeError, r"argument for str\(\) given by name \('encoding'\) and position \(2\)"):
|
||||
str(b"x", "utf-8", encoding="ascii")
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) takes at most 3 arguments \(4 given\)"):
|
||||
str(b"x", "utf-8", "ignore", encoding="ascii")
|
||||
with self.assertRaisesRegex(TypeError, r"str\(\) takes at most 3 arguments \(4 given\)"):
|
||||
str(b"x", "utf-8", "strict", errors="ignore")
|
||||
|
||||
|
||||
class StringModuleTest(unittest.TestCase):
|
||||
def test_formatter_parser(self):
|
||||
Vendored
+1
-1
@@ -110,7 +110,7 @@ class TestUnicodeFiles(unittest.TestCase):
|
||||
os.unlink(filename)
|
||||
self.assertTrue(not os.path.exists(filename))
|
||||
# and again with os.open.
|
||||
f = os.open(filename, os.O_CREAT)
|
||||
f = os.open(filename, os.O_CREAT | os.O_WRONLY)
|
||||
os.close(f)
|
||||
try:
|
||||
self._do_single(filename)
|
||||
|
||||
+7
-7
@@ -5,7 +5,7 @@ import sys
|
||||
import unittest
|
||||
import warnings
|
||||
from unicodedata import normalize
|
||||
from test.support import os_helper
|
||||
from test.support import is_apple, os_helper
|
||||
from test import support
|
||||
|
||||
|
||||
@@ -23,13 +23,13 @@ filenames = [
|
||||
'10_\u1fee\u1ffd',
|
||||
]
|
||||
|
||||
# Mac OS X decomposes Unicode names, using Normal Form D.
|
||||
# Apple platforms decompose Unicode names, using Normal Form D.
|
||||
# http://developer.apple.com/mac/library/qa/qa2001/qa1173.html
|
||||
# "However, most volume formats do not follow the exact specification for
|
||||
# these normal forms. For example, HFS Plus uses a variant of Normal Form D
|
||||
# in which U+2000 through U+2FFF, U+F900 through U+FAFF, and U+2F800 through
|
||||
# U+2FAFF are not decomposed."
|
||||
if sys.platform != 'darwin':
|
||||
if not is_apple:
|
||||
filenames.extend([
|
||||
# Specific code points: NFC(fn), NFD(fn), NFKC(fn) and NFKD(fn) all different
|
||||
'11_\u0385\u03d3\u03d4',
|
||||
@@ -119,11 +119,11 @@ class UnicodeFileTests(unittest.TestCase):
|
||||
os.stat(name)
|
||||
self._apply_failure(os.listdir, name, self._listdir_failure)
|
||||
|
||||
# Skip the test on darwin, because darwin does normalize the filename to
|
||||
# Skip the test on Apple platforms, because they don't normalize the filename to
|
||||
# NFD (a variant of Unicode NFD form). Normalize the filename to NFC, NFKC,
|
||||
# NFKD in Python is useless, because darwin will normalize it later and so
|
||||
# open(), os.stat(), etc. don't raise any exception.
|
||||
@unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X')
|
||||
@unittest.skipIf(is_apple, 'irrelevant test on Apple platforms')
|
||||
@unittest.skipIf(
|
||||
support.is_emscripten or support.is_wasi,
|
||||
"test fails on Emscripten/WASI when host platform is macOS."
|
||||
@@ -142,10 +142,10 @@ class UnicodeFileTests(unittest.TestCase):
|
||||
self._apply_failure(os.remove, name)
|
||||
self._apply_failure(os.listdir, name)
|
||||
|
||||
# Skip the test on darwin, because darwin uses a normalization different
|
||||
# Skip the test on Apple platforms, because they use a normalization different
|
||||
# than Python NFD normalization: filenames are different even if we use
|
||||
# Python NFD normalization.
|
||||
@unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X')
|
||||
@unittest.skipIf(is_apple, 'irrelevant test on Apple platforms')
|
||||
def test_listdir(self):
|
||||
sf0 = set(self.files)
|
||||
with warnings.catch_warnings():
|
||||
|
||||
Vendored
+1
-1
@@ -21,7 +21,7 @@ class PEP3131Test(unittest.TestCase):
|
||||
@unittest.expectedFailure
|
||||
def test_invalid(self):
|
||||
try:
|
||||
from test import badsyntax_3131
|
||||
from test.tokenizedata import badsyntax_3131
|
||||
except SyntaxError as err:
|
||||
self.assertEqual(str(err),
|
||||
"invalid character '€' (U+20AC) (badsyntax_3131.py, line 2)")
|
||||
|
||||
Vendored
+57
-5
@@ -11,15 +11,20 @@ from http.client import HTTPException
|
||||
import sys
|
||||
import unicodedata
|
||||
import unittest
|
||||
from test.support import (open_urlresource, requires_resource, script_helper,
|
||||
cpython_only, check_disallow_instantiation,
|
||||
ResourceDenied)
|
||||
from test.support import (
|
||||
open_urlresource,
|
||||
requires_resource,
|
||||
script_helper,
|
||||
cpython_only,
|
||||
check_disallow_instantiation,
|
||||
force_not_colorized,
|
||||
)
|
||||
|
||||
|
||||
class UnicodeMethodsTest(unittest.TestCase):
|
||||
|
||||
# update this, if the database changes
|
||||
expectedchecksum = '4739770dd4d0e5f1b1677accfc3552ed3c8ef326'
|
||||
expectedchecksum = '63aa77dcb36b0e1df082ee2a6071caeda7f0955e'
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@@ -74,7 +79,8 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest):
|
||||
|
||||
# Update this if the database changes. Make sure to do a full rebuild
|
||||
# (e.g. 'make distclean && make') to get the correct checksum.
|
||||
expectedchecksum = '98d602e1f69d5c5bb8a5910c40bbbad4e18e8370'
|
||||
expectedchecksum = '232affd2a50ec4bd69d2482aa0291385cbdefaba'
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@requires_resource('cpu')
|
||||
@@ -94,6 +100,8 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest):
|
||||
self.db.decomposition(char),
|
||||
str(self.db.mirrored(char)),
|
||||
str(self.db.combining(char)),
|
||||
unicodedata.east_asian_width(char),
|
||||
self.db.name(char, ""),
|
||||
]
|
||||
h.update(''.join(data).encode("ascii"))
|
||||
result = h.hexdigest()
|
||||
@@ -106,6 +114,28 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest):
|
||||
if looked_name := self.db.name(char, None):
|
||||
self.assertEqual(self.db.lookup(looked_name), char)
|
||||
|
||||
def test_no_names_in_pua(self):
|
||||
puas = [*range(0xe000, 0xf8ff),
|
||||
*range(0xf0000, 0xfffff),
|
||||
*range(0x100000, 0x10ffff)]
|
||||
for i in puas:
|
||||
char = chr(i)
|
||||
self.assertRaises(ValueError, self.db.name, char)
|
||||
|
||||
# TODO: RUSTPYTHON; LookupError: undefined character name 'LATIN SMLL LETR A'
|
||||
@unittest.expectedFailure
|
||||
def test_lookup_nonexistant(self):
|
||||
# just make sure that lookup can fail
|
||||
for nonexistant in [
|
||||
"LATIN SMLL LETR A",
|
||||
"OPEN HANDS SIGHS",
|
||||
"DREGS",
|
||||
"HANDBUG",
|
||||
"MODIFIER LETTER CYRILLIC SMALL QUESTION MARK",
|
||||
"???",
|
||||
]:
|
||||
self.assertRaises(KeyError, self.db.lookup, nonexistant)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_digit(self):
|
||||
@@ -245,6 +275,25 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest):
|
||||
self.assertEqual(eaw('\u2010'), 'A')
|
||||
self.assertEqual(eaw('\U00020000'), 'W')
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_east_asian_width_unassigned(self):
|
||||
eaw = self.db.east_asian_width
|
||||
# unassigned
|
||||
for char in '\u0530\u0ecf\u10c6\u20fc\uaaca\U000107bd\U000115f2':
|
||||
self.assertEqual(eaw(char), 'N')
|
||||
self.assertIs(self.db.name(char, None), None)
|
||||
|
||||
# unassigned but reserved for CJK
|
||||
for char in '\uFA6E\uFADA\U0002A6E0\U0002FA20\U0003134B\U0003FFFD':
|
||||
self.assertEqual(eaw(char), 'W')
|
||||
self.assertIs(self.db.name(char, None), None)
|
||||
|
||||
# private use areas
|
||||
for char in '\uE000\uF800\U000F0000\U000FFFEE\U00100000\U0010FFF0':
|
||||
self.assertEqual(eaw(char), 'A')
|
||||
self.assertIs(self.db.name(char, None), None)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_east_asian_width_9_0_changes(self):
|
||||
@@ -260,6 +309,7 @@ class UnicodeMiscTest(UnicodeDatabaseTest):
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@force_not_colorized
|
||||
def test_failed_import_during_compiling(self):
|
||||
# Issue 4367
|
||||
# Decoding \N escapes requires the unicodedata module. If it can't be
|
||||
@@ -322,6 +372,7 @@ class UnicodeMiscTest(UnicodeDatabaseTest):
|
||||
self.assertTrue("\u1d79".upper()=='\ua77d')
|
||||
self.assertTrue(".".upper()=='.')
|
||||
|
||||
@requires_resource('cpu')
|
||||
def test_bug_5828(self):
|
||||
self.assertEqual("\u1d79".lower(), "\u1d79")
|
||||
# Only U+0000 should have U+0000 as its upper/lower/titlecase variant
|
||||
@@ -364,6 +415,7 @@ class NormalizationTest(unittest.TestCase):
|
||||
return "".join([chr(x) for x in data])
|
||||
|
||||
@requires_resource('network')
|
||||
@requires_resource('cpu')
|
||||
def test_normalization(self):
|
||||
TESTDATAFILE = "NormalizationTest.txt"
|
||||
TESTDATAURL = f"http://www.pythontest.net/unicode/{unicodedata.unidata_version}/{TESTDATAFILE}"
|
||||
|
||||
Vendored
+1
-2
@@ -7,8 +7,7 @@ from test import string_tests
|
||||
from collections import UserString
|
||||
|
||||
class UserStringTest(
|
||||
string_tests.CommonTest,
|
||||
string_tests.MixinStrUnicodeUserStringTest,
|
||||
string_tests.StringLikeTest,
|
||||
unittest.TestCase
|
||||
):
|
||||
|
||||
|
||||
Reference in new issue
Block a user