mirror of
https://github.com/RYDE-WORK/pybind11.git
synced 2026-01-20 13:43:27 +08:00
* Adds set_name method of pybind11::capsule class This calls PyCapsule_SetName on the underlying capsule object. modified destructors to query capsules's Name [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Handle possible exception thrown by PyCapsule_GetName Also removed accidentally reintroduced use of `const char *&`. [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Fixed function name * Introduced private static function to reuse get_name_or_throw * added tests for capsule renaming * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * handle python error in flight * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Initialized PyObject * variables to nullptr * use write-unraisable if PyCapsule_GetName raises * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * get_name_or_throw->get_name_no_throw If PyCapsule_GetName raises an error we should write as unraisable to consume it and notify user, and then restore the error in flight if any. This way this method called from destructor would not modify interpreter error state. * used error_scope struct * Renamed get_name_no_throw->get_name_in_error_scope Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
668 lines
18 KiB
Python
668 lines
18 KiB
Python
import contextlib
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
import env
|
|
from pybind11_tests import debug_enabled
|
|
from pybind11_tests import pytypes as m
|
|
|
|
|
|
def test_bool(doc):
|
|
assert doc(m.get_bool) == "get_bool() -> bool"
|
|
|
|
|
|
def test_int(doc):
|
|
assert doc(m.get_int) == "get_int() -> int"
|
|
|
|
|
|
def test_iterator(doc):
|
|
assert doc(m.get_iterator) == "get_iterator() -> Iterator"
|
|
|
|
|
|
def test_iterable(doc):
|
|
assert doc(m.get_iterable) == "get_iterable() -> Iterable"
|
|
|
|
|
|
def test_float(doc):
|
|
assert doc(m.get_float) == "get_float() -> float"
|
|
|
|
|
|
def test_list(capture, doc):
|
|
assert m.list_no_args() == []
|
|
assert m.list_ssize_t() == []
|
|
assert m.list_size_t() == []
|
|
lins = [1, 2]
|
|
m.list_insert_ssize_t(lins)
|
|
assert lins == [1, 83, 2]
|
|
m.list_insert_size_t(lins)
|
|
assert lins == [1, 83, 2, 57]
|
|
|
|
with capture:
|
|
lst = m.get_list()
|
|
assert lst == ["inserted-0", "overwritten", "inserted-2"]
|
|
|
|
lst.append("value2")
|
|
m.print_list(lst)
|
|
assert (
|
|
capture.unordered
|
|
== """
|
|
Entry at position 0: value
|
|
list item 0: inserted-0
|
|
list item 1: overwritten
|
|
list item 2: inserted-2
|
|
list item 3: value2
|
|
"""
|
|
)
|
|
|
|
assert doc(m.get_list) == "get_list() -> list"
|
|
assert doc(m.print_list) == "print_list(arg0: list) -> None"
|
|
|
|
|
|
def test_none(capture, doc):
|
|
assert doc(m.get_none) == "get_none() -> None"
|
|
assert doc(m.print_none) == "print_none(arg0: None) -> None"
|
|
|
|
|
|
def test_set(capture, doc):
|
|
s = m.get_set()
|
|
assert s == {"key1", "key2", "key3"}
|
|
|
|
with capture:
|
|
s.add("key4")
|
|
m.print_set(s)
|
|
assert (
|
|
capture.unordered
|
|
== """
|
|
key: key1
|
|
key: key2
|
|
key: key3
|
|
key: key4
|
|
"""
|
|
)
|
|
|
|
assert not m.set_contains(set(), 42)
|
|
assert m.set_contains({42}, 42)
|
|
assert m.set_contains({"foo"}, "foo")
|
|
|
|
assert doc(m.get_list) == "get_list() -> list"
|
|
assert doc(m.print_list) == "print_list(arg0: list) -> None"
|
|
|
|
|
|
def test_dict(capture, doc):
|
|
d = m.get_dict()
|
|
assert d == {"key": "value"}
|
|
|
|
with capture:
|
|
d["key2"] = "value2"
|
|
m.print_dict(d)
|
|
assert (
|
|
capture.unordered
|
|
== """
|
|
key: key, value=value
|
|
key: key2, value=value2
|
|
"""
|
|
)
|
|
|
|
assert not m.dict_contains({}, 42)
|
|
assert m.dict_contains({42: None}, 42)
|
|
assert m.dict_contains({"foo": None}, "foo")
|
|
|
|
assert doc(m.get_dict) == "get_dict() -> dict"
|
|
assert doc(m.print_dict) == "print_dict(arg0: dict) -> None"
|
|
|
|
assert m.dict_keyword_constructor() == {"x": 1, "y": 2, "z": 3}
|
|
|
|
|
|
def test_tuple():
|
|
assert m.tuple_no_args() == ()
|
|
assert m.tuple_ssize_t() == ()
|
|
assert m.tuple_size_t() == ()
|
|
assert m.get_tuple() == (42, None, "spam")
|
|
|
|
|
|
def test_simple_namespace():
|
|
ns = m.get_simple_namespace()
|
|
assert ns.attr == 42
|
|
assert ns.x == "foo"
|
|
assert ns.right == 2
|
|
assert not hasattr(ns, "wrong")
|
|
|
|
|
|
def test_str(doc):
|
|
assert m.str_from_char_ssize_t().encode().decode() == "red"
|
|
assert m.str_from_char_size_t().encode().decode() == "blue"
|
|
assert m.str_from_string().encode().decode() == "baz"
|
|
assert m.str_from_bytes().encode().decode() == "boo"
|
|
|
|
assert doc(m.str_from_bytes) == "str_from_bytes() -> str"
|
|
|
|
class A:
|
|
def __str__(self):
|
|
return "this is a str"
|
|
|
|
def __repr__(self):
|
|
return "this is a repr"
|
|
|
|
assert m.str_from_object(A()) == "this is a str"
|
|
assert m.repr_from_object(A()) == "this is a repr"
|
|
assert m.str_from_handle(A()) == "this is a str"
|
|
|
|
s1, s2 = m.str_format()
|
|
assert s1 == "1 + 2 = 3"
|
|
assert s1 == s2
|
|
|
|
malformed_utf8 = b"\x80"
|
|
if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
|
|
assert m.str_from_object(malformed_utf8) is malformed_utf8
|
|
else:
|
|
assert m.str_from_object(malformed_utf8) == "b'\\x80'"
|
|
assert m.str_from_handle(malformed_utf8) == "b'\\x80'"
|
|
|
|
assert m.str_from_string_from_str("this is a str") == "this is a str"
|
|
ucs_surrogates_str = "\udcc3"
|
|
with pytest.raises(UnicodeEncodeError):
|
|
m.str_from_string_from_str(ucs_surrogates_str)
|
|
|
|
|
|
def test_bytes(doc):
|
|
assert m.bytes_from_char_ssize_t().decode() == "green"
|
|
assert m.bytes_from_char_size_t().decode() == "purple"
|
|
assert m.bytes_from_string().decode() == "foo"
|
|
assert m.bytes_from_str().decode() == "bar"
|
|
|
|
assert doc(m.bytes_from_str) == "bytes_from_str() -> bytes"
|
|
|
|
|
|
def test_bytearray(doc):
|
|
assert m.bytearray_from_char_ssize_t().decode() == "$%"
|
|
assert m.bytearray_from_char_size_t().decode() == "@$!"
|
|
assert m.bytearray_from_string().decode() == "foo"
|
|
assert m.bytearray_size() == len("foo")
|
|
|
|
|
|
def test_capsule(capture):
|
|
pytest.gc_collect()
|
|
with capture:
|
|
a = m.return_capsule_with_destructor()
|
|
del a
|
|
pytest.gc_collect()
|
|
assert (
|
|
capture.unordered
|
|
== """
|
|
creating capsule
|
|
destructing capsule
|
|
"""
|
|
)
|
|
|
|
with capture:
|
|
a = m.return_renamed_capsule_with_destructor()
|
|
del a
|
|
pytest.gc_collect()
|
|
assert (
|
|
capture.unordered
|
|
== """
|
|
creating capsule
|
|
renaming capsule
|
|
destructing capsule
|
|
"""
|
|
)
|
|
|
|
with capture:
|
|
a = m.return_capsule_with_destructor_2()
|
|
del a
|
|
pytest.gc_collect()
|
|
assert (
|
|
capture.unordered
|
|
== """
|
|
creating capsule
|
|
destructing capsule: 1234
|
|
"""
|
|
)
|
|
|
|
with capture:
|
|
a = m.return_renamed_capsule_with_destructor_2()
|
|
del a
|
|
pytest.gc_collect()
|
|
assert (
|
|
capture.unordered
|
|
== """
|
|
creating capsule
|
|
renaming capsule
|
|
destructing capsule: 1234
|
|
"""
|
|
)
|
|
|
|
with capture:
|
|
a = m.return_capsule_with_name_and_destructor()
|
|
del a
|
|
pytest.gc_collect()
|
|
assert (
|
|
capture.unordered
|
|
== """
|
|
created capsule (1234, 'pointer type description')
|
|
destructing capsule (1234, 'pointer type description')
|
|
"""
|
|
)
|
|
|
|
|
|
def test_accessors():
|
|
class SubTestObject:
|
|
attr_obj = 1
|
|
attr_char = 2
|
|
|
|
class TestObject:
|
|
basic_attr = 1
|
|
begin_end = [1, 2, 3]
|
|
d = {"operator[object]": 1, "operator[char *]": 2}
|
|
sub = SubTestObject()
|
|
|
|
def func(self, x, *args):
|
|
return self.basic_attr + x + sum(args)
|
|
|
|
d = m.accessor_api(TestObject())
|
|
assert d["basic_attr"] == 1
|
|
assert d["begin_end"] == [1, 2, 3]
|
|
assert d["operator[object]"] == 1
|
|
assert d["operator[char *]"] == 2
|
|
assert d["attr(object)"] == 1
|
|
assert d["attr(char *)"] == 2
|
|
assert d["missing_attr_ptr"] == "raised"
|
|
assert d["missing_attr_chain"] == "raised"
|
|
assert d["is_none"] is False
|
|
assert d["operator()"] == 2
|
|
assert d["operator*"] == 7
|
|
assert d["implicit_list"] == [1, 2, 3]
|
|
assert all(x in TestObject.__dict__ for x in d["implicit_dict"])
|
|
|
|
assert m.tuple_accessor(tuple()) == (0, 1, 2)
|
|
|
|
d = m.accessor_assignment()
|
|
assert d["get"] == 0
|
|
assert d["deferred_get"] == 0
|
|
assert d["set"] == 1
|
|
assert d["deferred_set"] == 1
|
|
assert d["var"] == 99
|
|
|
|
|
|
def test_constructors():
|
|
"""C++ default and converting constructors are equivalent to type calls in Python"""
|
|
types = [bytes, bytearray, str, bool, int, float, tuple, list, dict, set]
|
|
expected = {t.__name__: t() for t in types}
|
|
assert m.default_constructors() == expected
|
|
|
|
data = {
|
|
bytes: b"41", # Currently no supported or working conversions.
|
|
bytearray: bytearray(b"41"),
|
|
str: 42,
|
|
bool: "Not empty",
|
|
int: "42",
|
|
float: "+1e3",
|
|
tuple: range(3),
|
|
list: range(3),
|
|
dict: [("two", 2), ("one", 1), ("three", 3)],
|
|
set: [4, 4, 5, 6, 6, 6],
|
|
memoryview: b"abc",
|
|
}
|
|
inputs = {k.__name__: v for k, v in data.items()}
|
|
expected = {k.__name__: k(v) for k, v in data.items()}
|
|
|
|
assert m.converting_constructors(inputs) == expected
|
|
assert m.cast_functions(inputs) == expected
|
|
|
|
# Converting constructors and cast functions should just reference rather
|
|
# than copy when no conversion is needed:
|
|
noconv1 = m.converting_constructors(expected)
|
|
for k in noconv1:
|
|
assert noconv1[k] is expected[k]
|
|
|
|
noconv2 = m.cast_functions(expected)
|
|
for k in noconv2:
|
|
assert noconv2[k] is expected[k]
|
|
|
|
|
|
def test_non_converting_constructors():
|
|
non_converting_test_cases = [
|
|
("bytes", range(10)),
|
|
("none", 42),
|
|
("ellipsis", 42),
|
|
("type", 42),
|
|
]
|
|
for t, v in non_converting_test_cases:
|
|
for move in [True, False]:
|
|
with pytest.raises(TypeError) as excinfo:
|
|
m.nonconverting_constructor(t, v, move)
|
|
expected_error = (
|
|
f"Object of type '{type(v).__name__}' is not an instance of '{t}'"
|
|
)
|
|
assert str(excinfo.value) == expected_error
|
|
|
|
|
|
def test_pybind11_str_raw_str():
|
|
# specifically to exercise pybind11::str::raw_str
|
|
cvt = m.convert_to_pybind11_str
|
|
assert cvt("Str") == "Str"
|
|
assert cvt(b"Bytes") == "b'Bytes'"
|
|
assert cvt(None) == "None"
|
|
assert cvt(False) == "False"
|
|
assert cvt(True) == "True"
|
|
assert cvt(42) == "42"
|
|
assert cvt(2**65) == "36893488147419103232"
|
|
assert cvt(-1.50) == "-1.5"
|
|
assert cvt(()) == "()"
|
|
assert cvt((18,)) == "(18,)"
|
|
assert cvt([]) == "[]"
|
|
assert cvt([28]) == "[28]"
|
|
assert cvt({}) == "{}"
|
|
assert cvt({3: 4}) == "{3: 4}"
|
|
assert cvt(set()) == "set()"
|
|
assert cvt({3, 3}) == "{3}"
|
|
|
|
valid_orig = "DZ"
|
|
valid_utf8 = valid_orig.encode("utf-8")
|
|
valid_cvt = cvt(valid_utf8)
|
|
if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
|
|
assert valid_cvt is valid_utf8
|
|
else:
|
|
assert type(valid_cvt) is str
|
|
assert valid_cvt == "b'\\xc7\\xb1'"
|
|
|
|
malformed_utf8 = b"\x80"
|
|
if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
|
|
assert cvt(malformed_utf8) is malformed_utf8
|
|
else:
|
|
malformed_cvt = cvt(malformed_utf8)
|
|
assert type(malformed_cvt) is str
|
|
assert malformed_cvt == "b'\\x80'"
|
|
|
|
|
|
def test_implicit_casting():
|
|
"""Tests implicit casting when assigning or appending to dicts and lists."""
|
|
z = m.get_implicit_casting()
|
|
assert z["d"] == {
|
|
"char*_i1": "abc",
|
|
"char*_i2": "abc",
|
|
"char*_e": "abc",
|
|
"char*_p": "abc",
|
|
"str_i1": "str",
|
|
"str_i2": "str1",
|
|
"str_e": "str2",
|
|
"str_p": "str3",
|
|
"int_i1": 42,
|
|
"int_i2": 42,
|
|
"int_e": 43,
|
|
"int_p": 44,
|
|
}
|
|
assert z["l"] == [3, 6, 9, 12, 15]
|
|
|
|
|
|
def test_print(capture):
|
|
with capture:
|
|
m.print_function()
|
|
assert (
|
|
capture
|
|
== """
|
|
Hello, World!
|
|
1 2.0 three True -- multiple args
|
|
*args-and-a-custom-separator
|
|
no new line here -- next print
|
|
flush
|
|
py::print + str.format = this
|
|
"""
|
|
)
|
|
assert capture.stderr == "this goes to stderr"
|
|
|
|
with pytest.raises(RuntimeError) as excinfo:
|
|
m.print_failure()
|
|
assert str(excinfo.value) == "Unable to convert call argument " + (
|
|
"'1' of type 'UnregisteredType' to Python object"
|
|
if debug_enabled
|
|
else "to Python object (compile in debug mode for details)"
|
|
)
|
|
|
|
|
|
def test_hash():
|
|
class Hashable:
|
|
def __init__(self, value):
|
|
self.value = value
|
|
|
|
def __hash__(self):
|
|
return self.value
|
|
|
|
class Unhashable:
|
|
__hash__ = None
|
|
|
|
assert m.hash_function(Hashable(42)) == 42
|
|
with pytest.raises(TypeError):
|
|
m.hash_function(Unhashable())
|
|
|
|
|
|
def test_number_protocol():
|
|
for a, b in [(1, 1), (3, 5)]:
|
|
li = [
|
|
a == b,
|
|
a != b,
|
|
a < b,
|
|
a <= b,
|
|
a > b,
|
|
a >= b,
|
|
a + b,
|
|
a - b,
|
|
a * b,
|
|
a / b,
|
|
a | b,
|
|
a & b,
|
|
a ^ b,
|
|
a >> b,
|
|
a << b,
|
|
]
|
|
assert m.test_number_protocol(a, b) == li
|
|
|
|
|
|
def test_list_slicing():
|
|
li = list(range(100))
|
|
assert li[::2] == m.test_list_slicing(li)
|
|
|
|
|
|
def test_issue2361():
|
|
# See issue #2361
|
|
assert m.issue2361_str_implicit_copy_none() == "None"
|
|
with pytest.raises(TypeError) as excinfo:
|
|
assert m.issue2361_dict_implicit_copy_none()
|
|
assert "NoneType" in str(excinfo.value)
|
|
assert "iterable" in str(excinfo.value)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"method, args, fmt, expected_view",
|
|
[
|
|
(m.test_memoryview_object, (b"red",), "B", b"red"),
|
|
(m.test_memoryview_buffer_info, (b"green",), "B", b"green"),
|
|
(m.test_memoryview_from_buffer, (False,), "h", [3, 1, 4, 1, 5]),
|
|
(m.test_memoryview_from_buffer, (True,), "H", [2, 7, 1, 8]),
|
|
(m.test_memoryview_from_buffer_nativeformat, (), "@i", [4, 7, 5]),
|
|
],
|
|
)
|
|
def test_memoryview(method, args, fmt, expected_view):
|
|
view = method(*args)
|
|
assert isinstance(view, memoryview)
|
|
assert view.format == fmt
|
|
assert list(view) == list(expected_view)
|
|
|
|
|
|
@pytest.mark.xfail("env.PYPY", reason="getrefcount is not available")
|
|
@pytest.mark.parametrize(
|
|
"method",
|
|
[
|
|
m.test_memoryview_object,
|
|
m.test_memoryview_buffer_info,
|
|
],
|
|
)
|
|
def test_memoryview_refcount(method):
|
|
buf = b"\x0a\x0b\x0c\x0d"
|
|
ref_before = sys.getrefcount(buf)
|
|
view = method(buf)
|
|
ref_after = sys.getrefcount(buf)
|
|
assert ref_before < ref_after
|
|
assert list(view) == list(buf)
|
|
|
|
|
|
def test_memoryview_from_buffer_empty_shape():
|
|
view = m.test_memoryview_from_buffer_empty_shape()
|
|
assert isinstance(view, memoryview)
|
|
assert view.format == "B"
|
|
assert bytes(view) == b""
|
|
|
|
|
|
def test_test_memoryview_from_buffer_invalid_strides():
|
|
with pytest.raises(RuntimeError):
|
|
m.test_memoryview_from_buffer_invalid_strides()
|
|
|
|
|
|
def test_test_memoryview_from_buffer_nullptr():
|
|
with pytest.raises(ValueError):
|
|
m.test_memoryview_from_buffer_nullptr()
|
|
|
|
|
|
def test_memoryview_from_memory():
|
|
view = m.test_memoryview_from_memory()
|
|
assert isinstance(view, memoryview)
|
|
assert view.format == "B"
|
|
assert bytes(view) == b"\xff\xe1\xab\x37"
|
|
|
|
|
|
def test_builtin_functions():
|
|
assert m.get_len([i for i in range(42)]) == 42
|
|
with pytest.raises(TypeError) as exc_info:
|
|
m.get_len(i for i in range(42))
|
|
assert str(exc_info.value) in [
|
|
"object of type 'generator' has no len()",
|
|
"'generator' has no length",
|
|
] # PyPy
|
|
|
|
|
|
def test_isinstance_string_types():
|
|
assert m.isinstance_pybind11_bytes(b"")
|
|
assert not m.isinstance_pybind11_bytes("")
|
|
|
|
assert m.isinstance_pybind11_str("")
|
|
if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
|
|
assert m.isinstance_pybind11_str(b"")
|
|
else:
|
|
assert not m.isinstance_pybind11_str(b"")
|
|
|
|
|
|
def test_pass_bytes_or_unicode_to_string_types():
|
|
assert m.pass_to_pybind11_bytes(b"Bytes") == 5
|
|
with pytest.raises(TypeError):
|
|
m.pass_to_pybind11_bytes("Str")
|
|
|
|
if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
|
|
assert m.pass_to_pybind11_str(b"Bytes") == 5
|
|
else:
|
|
with pytest.raises(TypeError):
|
|
m.pass_to_pybind11_str(b"Bytes")
|
|
assert m.pass_to_pybind11_str("Str") == 3
|
|
|
|
assert m.pass_to_std_string(b"Bytes") == 5
|
|
assert m.pass_to_std_string("Str") == 3
|
|
|
|
malformed_utf8 = b"\x80"
|
|
if hasattr(m, "PYBIND11_STR_LEGACY_PERMISSIVE"):
|
|
assert m.pass_to_pybind11_str(malformed_utf8) == 1
|
|
else:
|
|
with pytest.raises(TypeError):
|
|
m.pass_to_pybind11_str(malformed_utf8)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"create_weakref, create_weakref_with_callback",
|
|
[
|
|
(m.weakref_from_handle, m.weakref_from_handle_and_function),
|
|
(m.weakref_from_object, m.weakref_from_object_and_function),
|
|
],
|
|
)
|
|
def test_weakref(create_weakref, create_weakref_with_callback):
|
|
from weakref import getweakrefcount
|
|
|
|
# Apparently, you cannot weakly reference an object()
|
|
class WeaklyReferenced:
|
|
pass
|
|
|
|
callback_called = False
|
|
|
|
def callback(wr):
|
|
nonlocal callback_called
|
|
callback_called = True
|
|
|
|
obj = WeaklyReferenced()
|
|
assert getweakrefcount(obj) == 0
|
|
wr = create_weakref(obj)
|
|
assert getweakrefcount(obj) == 1
|
|
|
|
obj = WeaklyReferenced()
|
|
assert getweakrefcount(obj) == 0
|
|
wr = create_weakref_with_callback(obj, callback) # noqa: F841
|
|
assert getweakrefcount(obj) == 1
|
|
assert not callback_called
|
|
del obj
|
|
pytest.gc_collect()
|
|
assert callback_called
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"create_weakref, has_callback",
|
|
[
|
|
(m.weakref_from_handle, False),
|
|
(m.weakref_from_object, False),
|
|
(m.weakref_from_handle_and_function, True),
|
|
(m.weakref_from_object_and_function, True),
|
|
],
|
|
)
|
|
def test_weakref_err(create_weakref, has_callback):
|
|
class C:
|
|
__slots__ = []
|
|
|
|
def callback(_):
|
|
pass
|
|
|
|
ob = C()
|
|
# Should raise TypeError on CPython
|
|
with pytest.raises(TypeError) if not env.PYPY else contextlib.nullcontext():
|
|
if has_callback:
|
|
_ = create_weakref(ob, callback)
|
|
else:
|
|
_ = create_weakref(ob)
|
|
|
|
|
|
def test_cpp_iterators():
|
|
assert m.tuple_iterator() == 12
|
|
assert m.dict_iterator() == 305 + 711
|
|
assert m.passed_iterator(iter((-7, 3))) == -4
|
|
|
|
|
|
def test_implementation_details():
|
|
lst = [39, 43, 92, 49, 22, 29, 93, 98, 26, 57, 8]
|
|
tup = tuple(lst)
|
|
assert m.sequence_item_get_ssize_t(lst) == 43
|
|
assert m.sequence_item_set_ssize_t(lst) is None
|
|
assert lst[1] == "peppa"
|
|
assert m.sequence_item_get_size_t(lst) == 92
|
|
assert m.sequence_item_set_size_t(lst) is None
|
|
assert lst[2] == "george"
|
|
assert m.list_item_get_ssize_t(lst) == 49
|
|
assert m.list_item_set_ssize_t(lst) is None
|
|
assert lst[3] == "rebecca"
|
|
assert m.list_item_get_size_t(lst) == 22
|
|
assert m.list_item_set_size_t(lst) is None
|
|
assert lst[4] == "richard"
|
|
assert m.tuple_item_get_ssize_t(tup) == 29
|
|
assert m.tuple_item_set_ssize_t() == ("emely", "edmond")
|
|
assert m.tuple_item_get_size_t(tup) == 93
|
|
assert m.tuple_item_set_size_t() == ("candy", "cat")
|
|
|
|
|
|
def test_external_float_():
|
|
r1 = m.square_float_(2.0)
|
|
assert r1 == 4.0
|