blob: cb527b50f7c2471e52666417b578fc091c224814 [file] [log] [blame] [edit]
[case testLibrtVecsTInterpreted_librt_experimental]
# Test cases for vec[<ref type>], using generic operations (simulates use from interpreted code).
import sys
from typing import cast, List, Any
import typing
import librt.vecs
import mypy_extensions
from testutil import assertRaises, is_gil_disabled, is_64_bit_platform
from helpers import ClassWithCustomMeta
vec: Any = librt.vecs.vec
append: Any = librt.vecs.append
remove: Any = librt.vecs.remove
pop: Any = librt.vecs.pop
getsizeof: Any = getattr(sys, "getsizeof")
i64: Any = mypy_extensions.i64
version_info: Any = sys.version_info
# Work around test stub limitations
Optional: Any = getattr(getattr(sys, "modules")["typing"], "Optional")
def assert_eq(x: object, y: object) -> None:
assert x == y
assert y == x
b = x != y
assert not b
b = y != x
assert not b
def assert_neq(x: object, y: object) -> None:
assert x != y
assert y != x
b = x == y
assert not b
b = y == x
assert not b
@mypy_extensions.mypyc_attr(native_class=False)
class StringSubclass(str):
pass
class ClassWithRaisingEq:
def __eq__(self, other):
raise RuntimeError()
def test_vec_indexing() -> None:
assert vec[str] is not vec[i64]
assert type(vec[str]) is not type
assert type(vec[Optional[str]]) is type(vec[str])
def test_type_str() -> None:
assert str(vec[str]) == "<class_proxy 'vec[str]'>"
assert str(vec[Optional[str]]) == "<class_proxy 'vec[str | None]'>"
def test_construct_empty() -> None:
v = vec[str]()
assert len(v) == 0
v2 = vec[Optional[str]]()
assert len(v2) == 0
assert type(v) is type(v2)
def test_construct_or_union() -> None:
if version_info >= (3, 10):
v = vec[str | None]()
assert len(v) == 0
assert str(v) == 'vec[str | None]([])'
def test_construct_from_initializer() -> None:
v = vec[str](['xyz'])
assert len(v) == 1
assert v[0] == 'xyz'
v = vec[str](x + '!' for x in ['x', '', 'foo', 'bar'])
assert len(v) == 4
assert v[0] == 'x!'
assert v[1] == '!'
assert v[2] == 'foo!'
assert v[3] == 'bar!'
with assertRaises(TypeError):
vec[str](1)
with assertRaises(TypeError):
vec[str]([1])
with assertRaises(TypeError):
vec[str]([None])
def test_construct_from_initializer_optional() -> None:
v = vec[Optional[str]]([None, 'xyz'])
assert len(v) == 2
assert v[0] is None
assert v[1] == 'xyz'
v = vec[Optional[str]](x for x in ['x', None, 'foo', 'bar'])
assert len(v) == 4
assert v[0] == 'x'
assert v[1] is None
assert v[2] == 'foo'
assert v[3] == 'bar'
with assertRaises(TypeError):
vec[Optional[str]](1)
with assertRaises(TypeError):
vec[Optional[str]]([1])
def test_isinstance() -> None:
assert isinstance(vec[str](), vec)
assert isinstance(vec[Optional[str]](), vec)
def test_append() -> None:
v = vec[str]()
v = append(v, '1')
assert str(v) == "vec[str](['1'])"
for n in range(2, 10):
v = append(v, str(n))
assert str(v) == "vec[str](['1', '2', '3', '4', '5', '6', '7', '8', '9'])"
v2 = vec[Optional[str]]()
v2 = append(v2, 'x')
v2 = append(v2, None)
assert str(v2) == "vec[str | None](['x', None])"
def test_append_error() -> None:
v: Any = vec[str]()
with assertRaises(TypeError):
v = append(v, b'x')
with assertRaises(TypeError):
v = append(v, ['x'])
with assertRaises(TypeError):
v = append(v, None)
assert len(v) == 0
v2: Any = vec[Optional[str]]()
with assertRaises(TypeError):
v2 = append(v2, b'x')
def test_repr() -> None:
assert str(vec[str]()) == "vec[str]([])"
assert str(vec[Optional[str]]([None, 'x'])) == "vec[str | None]([None, 'x'])"
def test_size() -> None:
# Only test on 64-bit, non-free-threading builds
if not is_gil_disabled() and is_64_bit_platform():
v = vec[str]()
assert getsizeof(v) == 48
v = append(v, '123')
assert getsizeof(v) == 48
def test_get_item() -> None:
v = append(vec[str](), '44')
assert v[0] == '44'
v = append(v, '56')
assert v[0] == '44'
assert v[1] == '56'
v2 = vec[Optional[str]]([None, '12'])
assert v2[0] is None
assert v2[1] == '12'
def test_get_item_error() -> None:
v = append(vec[str](), '1')
v = append(v, '2')
v = append(v, '3')
with assertRaises(IndexError):
v[3]
with assertRaises(IndexError):
v[-4]
n = 2 ** 100
with assertRaises(IndexError):
v[n]
def test_get_item_negative() -> None:
v = vec[str](['2', '5', '7'])
assert v[-1] == '7'
assert v[-2] == '5'
assert v[-3] == '2'
with assertRaises(IndexError):
v[-4]
with assertRaises(IndexError):
v[-2**62]
def test_len() -> None:
v = vec[str]()
assert len(v) == 0
v = append(v, '1')
assert len(v) == 1
v = append(v, '2')
assert len(v) == 2
for i in range(100):
v = append(v, 'i')
assert len(v) == i + 3
def test_set_item() -> None:
v = vec[str]()
v = append(v, '1')
v = append(v, '2')
v[0] = '3'
assert v[0] == '3'
assert v[1] == '2'
v[1] = '5'
assert v[0] == '3'
assert v[1] == '5'
def test_set_item_optional() -> None:
v = vec[Optional[str]]()
v = append(v, '1')
v = append(v, None)
v[0] = '3'
assert v[0] == '3'
assert v[1 + int()] is None # TODO: The '+ int()' is due to mypy type narrowing bug
v[1] = '5'
assert v[0] == '3'
assert v[1] == '5'
v[1] = None
assert v[0] == '3'
assert v[1] is None
def test_set_item_error() -> None:
v = append(vec[str](), '1')
v = append(v, '2')
v = append(v, '3')
with assertRaises(IndexError):
v[3] = '1'
with assertRaises(TypeError):
v[0] = b'x'
with assertRaises(TypeError):
v[0] = vec[str]()
with assertRaises(TypeError):
v[0] = None
assert v[0] == '1'
def test_set_item_error_optional() -> None:
v = append(vec[Optional[str]](), '1')
v = append(v, None)
v = append(v, '3')
with assertRaises(IndexError):
v[3] = '1'
with assertRaises(IndexError):
v[3] = None
with assertRaises(IndexError):
v[-4] = '1'
with assertRaises(IndexError):
v[-4] = None
with assertRaises(TypeError):
v[0] = b'x'
with assertRaises(TypeError):
v[0] = vec[str]()
with assertRaises(TypeError):
v[0] = vec[Optional[str]]()
assert v[0] == '1'
def test_set_item_negative() -> None:
v = vec[str]()
v = append(v, '1')
v = append(v, '2')
v[-2] = '3'
assert v[0] == '3'
assert v[1] == '2'
v[-1] = '5'
assert v[0] == '3'
assert v[1] == '5'
with assertRaises(IndexError):
v[-3] = '1'
def test_nested_in_type() -> None:
cast(List[vec[str]], [])
def test_cannot_overload_isinstance() -> None:
assert isinstance('', ClassWithCustomMeta)
v = vec[ClassWithCustomMeta]()
v = append(v, ClassWithCustomMeta())
with assertRaises(TypeError):
v = append(v, '')
with assertRaises(TypeError):
v[0] = ''
def test_add_subclass_instance() -> None:
v = vec[str]()
v = append(v, StringSubclass())
v[0] = StringSubclass()
v2 = vec[StringSubclass]()
with assertRaises(TypeError):
v2 = append(v2, '')
def test_equality() -> None:
assert_eq(vec[str](), vec[str]())
assert_eq(vec[str](['x']), vec[str](['x']))
v = vec[str](['x'])
assert_eq(v, v)
assert_eq(vec[str](['x', 'y']), vec[str](['x', 'y']))
assert_neq(vec[str](), vec[str](['x']))
assert_neq(vec[str](['x', 'y']), vec[str](['x']))
assert_neq(vec[str](['x']), vec[str](['y']))
assert_neq(vec[str](['x', 'y']), vec[str](['y', 'y']))
assert_neq(vec[str](['x', 'y']), vec[str](['x', 'x']))
assert_eq(vec[Optional[str]](), vec[Optional[str]]())
assert_eq(vec[Optional[str]](['x', None]), vec[Optional[str]](['x', None]))
assert_neq(vec[Optional[str]](['x', None]), vec[Optional[str]](['x', 'y']))
def test_equality_different_types() -> None:
assert_neq(vec[str](['x']), ['x'])
assert_neq(vec[str](['x']), ('x',))
assert_neq(vec[str](['x']), vec[object](['x']))
assert_neq(vec[str](), vec[object]())
assert_neq(vec[str](), vec[Optional[str]]())
def test_exception_from_eq() -> None:
with assertRaises(RuntimeError):
vec[ClassWithRaisingEq]([ClassWithRaisingEq()]) == vec[ClassWithRaisingEq]([ClassWithRaisingEq()])
def test_iteration() -> None:
for x in vec[str]():
assert False
a = []
for x in vec[str](['x']):
a.append(x)
assert a == ['x']
a = []
for x in vec[str](['11', '23', '45', '64']):
a.append(x)
assert a == ['11', '23', '45', '64']
a = []
for x in vec[Optional[str]](['11', None, '45', '64']):
a.append(x)
assert a == ['11', None, '45', '64']
def test_slicing() -> None:
v = vec[str](str(i) for i in range(5))
assert v[1:4] == vec[str](['1', '2', '3'])
assert v[2:-1] == vec[str](['2', '3'])
assert v[-2:-1] == vec[str](['3'])
assert v[1:] == vec[str](['1', '2', '3', '4'])
assert v[:-1] == vec[str](['0', '1', '2', '3'])
assert v[:] == v
assert v[:] is not v
assert v[0:5] ==v
assert v[0:5] is not v
assert v[2:100] == vec[str](['2', '3', '4'])
assert v[-100:2] == vec[str](['0', '1'])
assert v[5:100] == vec[str]([])
assert v[50:100] == vec[str]([])
assert v[-100:-50] == vec[str]([])
def test_slicing_optional() -> None:
v = vec[Optional[str]](['x', None, 'y'])
assert v[:2] == vec[Optional[str]](['x', None])
def test_slicing_with_step() -> None:
v = vec[str](str(i) for i in range(10))
assert v[1:5:2] == vec[str](['1', '3'])
assert v[1:6:2] == vec[str](['1', '3', '5'])
assert v[5:1:-2] == vec[str](['5', '3'])
assert v[6:1:-2] == vec[str](['6', '4', '2'])
v = vec[str](str(i) for i in range(5))
assert v[::-1] == vec[str](['4', '3', '2', '1', '0'])
with assertRaises(ValueError):
v[1:3:0]
def test_contains() -> None:
v = vec[str](str(i) for i in range(2, 7))
for i in range(2, 7):
assert str(i) in v
assert 'x' not in v
assert '22' not in v
vv = vec[str]()
assert '3' not in vv
v2 = vec[Optional[str]]()
assert '3' not in v2
assert None not in v2
v2 = vec[Optional[str]](['3', None])
assert '3' in v2
assert None in v2
assert '4' not in v2
def test_remove() -> None:
a = ['4x', '7x', '9x']
for i in a:
v = vec[str](a)
v = remove(v, i)
assert v == vec[str]([j for j in a if j != i])
v = vec[str](a)
# Make sure we have a different id
v = remove(v, (i + 'x')[:-1])
assert v == vec[str]([j for j in a if j != i])
v = vec[str](a)
v = remove(v, '4x')
v = remove(v, '7x')
v = remove(v, '9x')
assert v == vec[str]()
with assertRaises(ValueError):
remove(v, '4')
v = append(v, '5')
with assertRaises(ValueError):
remove(v, '7')
v = remove(v, '5')
assert len(v) == 0
v = vec[str](['x', 'x', 'x'])
v = remove(v, 'x')
assert v == vec[str](['x', 'x'])
v = remove(v, 'x')
assert v == vec[str](['x'])
v = remove(v, 'x')
assert v == vec[str]()
b: Any = b'x'
with assertRaises(TypeError):
remove(v, b)
def test_remove_optional() -> None:
v = vec[Optional[str]](['x', None])
v = remove(v, 'x')
assert str(v) == "vec[str | None]([None])"
v = remove(v, None)
assert str(v) == "vec[str | None]([])"
def test_pop_last() -> None:
v = vec[str](['4', '7', '9'])
v, item = pop(v)
assert item == '9'
assert v == vec[str](['4', '7'])
v, item = pop(v)
assert item == '7'
assert v == vec[str](['4'])
v, item = pop(v)
assert item == '4'
assert v == vec[str]()
with assertRaises(IndexError):
pop(v)
def test_pop_index() -> None:
v = vec[str](['4', '7', '9', '15', '22'])
v, item = pop(v, 0)
assert item == '4'
assert v == vec[str](['7', '9', '15', '22'])
v, item = pop(v, -1)
assert item == '22'
assert v == vec[str](['7', '9', '15'])
v, item = pop(v, 1)
assert item == '9'
assert v == vec[str](['7', '15'])
with assertRaises(IndexError):
pop(v, 2)
with assertRaises(IndexError):
pop(v, -3)
v, item = pop(v, -2)
assert item == '7'
assert v == vec[str](['15'])
v, item = pop(v, 0)
assert item == '15'
assert v == vec[str]()
[file helpers.py]
# Test helper classes
class MetaWithInstanceCheck(type):
def __instancecheck__(cls, instance):
return isinstance(instance, str)
class ClassWithCustomMeta(metaclass=MetaWithInstanceCheck):
pass