1 from __future__
import annotations
10 from pybind11_tests
import detailed_error_messages_enabled
11 from pybind11_tests
import pytypes
as m
15 assert m.obj_class_name(
None) ==
"NoneType"
16 assert m.obj_class_name(list) ==
"list"
17 assert m.obj_class_name([]) ==
"list"
21 assert m.handle_from_move_only_type_with_operator_PyObject_ncnst()
22 assert m.handle_from_move_only_type_with_operator_PyObject_const()
26 assert doc(m.get_bool) ==
"get_bool() -> bool"
30 assert doc(m.get_int) ==
"get_int() -> int"
34 assert doc(m.get_iterator) ==
"get_iterator() -> Iterator"
37 @pytest.mark.parametrize(
38 (
"pytype",
"from_iter_func"),
40 (frozenset, m.get_frozenset_from_iterable),
41 (list, m.get_list_from_iterable),
42 (set, m.get_set_from_iterable),
43 (tuple, m.get_tuple_from_iterable),
48 s = from_iter_func(my_iter)
49 assert type(s) == pytype
50 assert s == pytype(
range(10))
54 assert doc(m.get_iterable) ==
"get_iterable() -> Iterable"
58 assert doc(m.get_float) ==
"get_float() -> float"
62 assert m.list_no_args() == []
63 assert m.list_ssize_t() == []
64 assert m.list_size_t() == []
66 m.list_insert_ssize_t(lins)
67 assert lins == [1, 83, 2]
68 m.list_insert_size_t(lins)
69 assert lins == [1, 83, 2, 57]
75 assert lst == [
"inserted-0",
"overwritten",
"inserted-2"]
82 Entry at position 0: value
83 list item 0: inserted-0
84 list item 1: overwritten
85 list item 2: inserted-2
90 assert doc(m.get_list) ==
"get_list() -> list"
91 assert doc(m.print_list) ==
"print_list(arg0: list) -> None"
95 assert doc(m.get_none) ==
"get_none() -> None"
96 assert doc(m.print_none) ==
"print_none(arg0: None) -> None"
102 assert s == {
"key1",
"key2",
"key3"}
118 assert m.anyset_size(s) == 5
121 assert m.anyset_empty(s)
123 assert not m.anyset_contains(
set(), 42)
124 assert m.anyset_contains({42}, 42)
125 assert m.anyset_contains({
"foo"},
"foo")
127 assert doc(m.get_set) ==
"get_set() -> set"
128 assert doc(m.print_anyset) ==
"print_anyset(arg0: Union[set, frozenset]) -> None"
132 s = m.get_frozenset()
134 assert s ==
frozenset({
"key1",
"key2",
"key3"})
146 assert m.anyset_size(s) == 3
147 assert not m.anyset_empty(s)
149 assert not m.anyset_contains(
frozenset(), 42)
150 assert m.anyset_contains(
frozenset({42}), 42)
151 assert m.anyset_contains(
frozenset({
"foo"}),
"foo")
153 assert doc(m.get_frozenset) ==
"get_frozenset() -> frozenset"
158 assert d == {
"key":
"value"}
166 key: key, value=value
167 key: key2, value=value2
171 assert not m.dict_contains({}, 42)
172 assert m.dict_contains({42:
None}, 42)
173 assert m.dict_contains({
"foo":
None},
"foo")
175 assert doc(m.get_dict) ==
"get_dict() -> dict"
176 assert doc(m.print_dict) ==
"print_dict(arg0: dict) -> None"
178 assert m.dict_keyword_constructor() == {
"x": 1,
"y": 2,
"z": 3}
188 @pytest.mark.parametrize(
191 (
set(), m.anyset_contains),
192 ({}, m.dict_contains),
196 @pytest.mark.xfail(
"env.PYPY and sys.pypy_version_info < (7, 3, 10)", strict=
False)
201 with pytest.raises(TypeError)
as exc_info:
202 func(arg, Unhashable())
203 assert "unhashable type:" in str(exc_info.value)
207 assert m.tuple_no_args() == ()
208 assert m.tuple_ssize_t() == ()
209 assert m.tuple_size_t() == ()
210 assert m.get_tuple() == (42,
None,
"spam")
214 ns = m.get_simple_namespace()
218 assert not hasattr(ns,
"wrong")
222 assert m.str_from_char_ssize_t().
encode().
decode() ==
"red"
223 assert m.str_from_char_size_t().
encode().
decode() ==
"blue"
227 assert doc(m.str_from_bytes) ==
"str_from_bytes() -> str"
231 return "this is a str"
234 return "this is a repr"
236 assert m.str_from_object(
A()) ==
"this is a str"
237 assert m.repr_from_object(
A()) ==
"this is a repr"
238 assert m.str_from_handle(
A()) ==
"this is a str"
240 s1, s2 = m.str_format()
241 assert s1 ==
"1 + 2 = 3"
244 malformed_utf8 = b
"\x80"
245 if hasattr(m,
"PYBIND11_STR_LEGACY_PERMISSIVE"):
246 assert m.str_from_object(malformed_utf8)
is malformed_utf8
248 assert m.str_from_object(malformed_utf8) ==
"b'\\x80'"
249 assert m.str_from_handle(malformed_utf8) ==
"b'\\x80'"
251 assert m.str_from_string_from_str(
"this is a str") ==
"this is a str"
252 ucs_surrogates_str =
"\udcc3"
253 with pytest.raises(UnicodeEncodeError):
254 m.str_from_string_from_str(ucs_surrogates_str)
257 @pytest.mark.parametrize(
260 m.str_from_bytes_input,
261 m.str_from_cstr_input,
262 m.str_from_std_string_input,
266 input_str =
"\ud83d\ude4f".
encode(
"utf-8",
"surrogatepass")
267 with pytest.raises(UnicodeDecodeError):
272 assert m.bytes_from_char_ssize_t().
decode() ==
"green"
273 assert m.bytes_from_char_size_t().
decode() ==
"purple"
274 assert m.bytes_from_string().
decode() ==
"foo"
275 assert m.bytes_from_str().
decode() ==
"bar"
277 assert doc(m.bytes_from_str) ==
"bytes_from_str() -> bytes"
281 assert m.bytearray_from_char_ssize_t().
decode() ==
"$%"
282 assert m.bytearray_from_char_size_t().
decode() ==
"@$!"
283 assert m.bytearray_from_string().
decode() ==
"foo"
284 assert m.bytearray_size() ==
len(
"foo")
290 a = m.return_capsule_with_destructor()
302 a = m.return_renamed_capsule_with_destructor()
315 a = m.return_capsule_with_destructor_2()
322 destructing capsule: 1234
327 a = m.return_capsule_with_destructor_3()
334 destructing capsule: 1233
340 a = m.return_renamed_capsule_with_destructor_2()
348 destructing capsule: 1234
353 a = m.return_capsule_with_name_and_destructor()
359 created capsule (1234, 'pointer type description')
360 destructing capsule (1234, 'pointer type description')
365 a = m.return_capsule_with_explicit_nullptr_dtor()
371 creating capsule with explicit nullptr dtor
383 begin_end = [1, 2, 3]
384 d = {
"operator[object]": 1,
"operator[char *]": 2}
385 sub = SubTestObject()
387 def func(self, x, *args):
388 return self.basic_attr + x + sum(args)
390 d = m.accessor_api(TestObject())
391 assert d[
"basic_attr"] == 1
392 assert d[
"begin_end"] == [1, 2, 3]
393 assert d[
"operator[object]"] == 1
394 assert d[
"operator[char *]"] == 2
395 assert d[
"attr(object)"] == 1
396 assert d[
"attr(char *)"] == 2
397 assert d[
"missing_attr_ptr"] ==
"raised"
398 assert d[
"missing_attr_chain"] ==
"raised"
399 assert d[
"is_none"]
is False
400 assert d[
"operator()"] == 2
401 assert d[
"operator*"] == 7
402 assert d[
"implicit_list"] == [1, 2, 3]
403 assert all(x
in TestObject.__dict__
for x
in d[
"implicit_dict"])
405 assert m.tuple_accessor(()) == (0, 1, 2)
407 d = m.accessor_assignment()
409 assert d[
"deferred_get"] == 0
411 assert d[
"deferred_set"] == 1
412 assert d[
"var"] == 99
416 inc_refs = m.accessor_moves()
418 assert inc_refs == [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
420 pytest.skip(
"Not defined: PYBIND11_HANDLE_REF_DEBUG")
424 """C++ default and converting constructors are equivalent to type calls in Python"""
425 types = [bytes, bytearray, str, bool, int, float, tuple, list, dict, set]
426 expected = {t.__name__:
t()
for t
in types}
427 assert m.default_constructors() == expected
438 dict: [(
"two", 2), (
"one", 1), (
"three", 3)],
439 set: [4, 4, 5, 6, 6, 6],
440 frozenset: [4, 4, 5, 6, 6, 6],
443 inputs = {k.__name__: v
for k, v
in data.items()}
444 expected = {k.__name__: k(v)
for k, v
in data.items()}
446 assert m.converting_constructors(inputs) == expected
447 assert m.cast_functions(inputs) == expected
451 noconv1 = m.converting_constructors(expected)
453 assert noconv1[k]
is expected[k]
455 noconv2 = m.cast_functions(expected)
457 assert noconv2[k]
is expected[k]
461 non_converting_test_cases = [
462 (
"bytes",
range(10)),
467 for t, v
in non_converting_test_cases:
468 for move
in [
True,
False]:
469 with pytest.raises(TypeError)
as excinfo:
470 m.nonconverting_constructor(t, v, move)
472 f
"Object of type '{type(v).__name__}' is not an instance of '{t}'"
474 assert str(excinfo.value) == expected_error
479 cvt = m.convert_to_pybind11_str
480 assert cvt(
"Str") ==
"Str"
481 assert cvt(b
"Bytes") ==
"b'Bytes'"
482 assert cvt(
None) ==
"None"
483 assert cvt(
False) ==
"False"
484 assert cvt(
True) ==
"True"
485 assert cvt(42) ==
"42"
486 assert cvt(2**65) ==
"36893488147419103232"
487 assert cvt(-1.50) ==
"-1.5"
488 assert cvt(()) ==
"()"
489 assert cvt((18,)) ==
"(18,)"
490 assert cvt([]) ==
"[]"
491 assert cvt([28]) ==
"[28]"
492 assert cvt({}) ==
"{}"
493 assert cvt({3: 4}) ==
"{3: 4}"
494 assert cvt(
set()) ==
"set()"
495 assert cvt({3}) ==
"{3}"
498 valid_utf8 = valid_orig.encode(
"utf-8")
499 valid_cvt = cvt(valid_utf8)
500 if hasattr(m,
"PYBIND11_STR_LEGACY_PERMISSIVE"):
501 assert valid_cvt
is valid_utf8
503 assert type(valid_cvt)
is str
504 assert valid_cvt ==
"b'\\xc7\\xb1'"
506 malformed_utf8 = b
"\x80"
507 if hasattr(m,
"PYBIND11_STR_LEGACY_PERMISSIVE"):
508 assert cvt(malformed_utf8)
is malformed_utf8
510 malformed_cvt = cvt(malformed_utf8)
511 assert type(malformed_cvt)
is str
512 assert malformed_cvt ==
"b'\\x80'"
516 """Tests implicit casting when assigning or appending to dicts and lists."""
517 z = m.get_implicit_casting()
532 assert z[
"l"] == [3, 6, 9, 12, 15]
542 1 2.0 three True -- multiple args
543 *args-and-a-custom-separator
544 no new line here -- next print
546 py::print + str.format = this
549 assert capture.stderr ==
"this goes to stderr"
551 with pytest.raises(RuntimeError)
as excinfo:
553 assert str(excinfo.value) ==
"Unable to convert call argument " + (
554 "'1' of type 'UnregisteredType' to Python object"
555 if detailed_error_messages_enabled
556 else "'1' to Python object (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)"
571 assert m.hash_function(Hashable(42)) == 42
572 with pytest.raises(TypeError):
573 m.hash_function(Unhashable())
577 for a, b
in [(1, 1), (3, 5)]:
595 assert m.test_number_protocol(a, b) == li
600 assert li[::2] == m.test_list_slicing(li)
605 assert m.issue2361_str_implicit_copy_none() ==
"None"
606 with pytest.raises(TypeError)
as excinfo:
607 assert m.issue2361_dict_implicit_copy_none()
608 assert "NoneType" in str(excinfo.value)
609 assert "iterable" in str(excinfo.value)
612 @pytest.mark.parametrize(
613 (
"method",
"args",
"fmt",
"expected_view"),
615 (m.test_memoryview_object, (b
"red",),
"B", b
"red"),
616 (m.test_memoryview_buffer_info, (b
"green",),
"B", b
"green"),
617 (m.test_memoryview_from_buffer, (
False,),
"h", [3, 1, 4, 1, 5]),
618 (m.test_memoryview_from_buffer, (
True,),
"H", [2, 7, 1, 8]),
619 (m.test_memoryview_from_buffer_nativeformat, (),
"@i", [4, 7, 5]),
625 assert view.format == fmt
626 assert list(view) ==
list(expected_view)
629 @pytest.mark.xfail(
"env.PYPY", reason=
"getrefcount is not available")
630 @pytest.mark.parametrize(
633 m.test_memoryview_object,
634 m.test_memoryview_buffer_info,
639 buf =
"\x0a\x0b\x0c\x0d".
encode(
"ascii")
640 ref_before = sys.getrefcount(buf)
642 ref_after = sys.getrefcount(buf)
643 assert ref_before < ref_after
648 view = m.test_memoryview_from_buffer_empty_shape()
650 assert view.format ==
"B"
651 assert bytes(view) == b
""
655 with pytest.raises(RuntimeError):
656 m.test_memoryview_from_buffer_invalid_strides()
660 with pytest.raises(ValueError):
661 m.test_memoryview_from_buffer_nullptr()
665 view = m.test_memoryview_from_memory()
667 assert view.format ==
"B"
668 assert bytes(view) == b
"\xff\xe1\xab\x37"
673 with pytest.raises(TypeError)
as exc_info:
674 m.get_len(i
for i
in range(42))
675 assert str(exc_info.value)
in [
676 "object of type 'generator' has no len()",
677 "'generator' has no length",
682 assert m.isinstance_pybind11_bytes(b
"")
683 assert not m.isinstance_pybind11_bytes(
"")
685 assert m.isinstance_pybind11_str(
"")
686 if hasattr(m,
"PYBIND11_STR_LEGACY_PERMISSIVE"):
687 assert m.isinstance_pybind11_str(b
"")
689 assert not m.isinstance_pybind11_str(b
"")
693 assert m.pass_to_pybind11_bytes(b
"Bytes") == 5
694 with pytest.raises(TypeError):
695 m.pass_to_pybind11_bytes(
"Str")
697 if hasattr(m,
"PYBIND11_STR_LEGACY_PERMISSIVE"):
698 assert m.pass_to_pybind11_str(b
"Bytes") == 5
700 with pytest.raises(TypeError):
701 m.pass_to_pybind11_str(b
"Bytes")
702 assert m.pass_to_pybind11_str(
"Str") == 3
704 assert m.pass_to_std_string(b
"Bytes") == 5
705 assert m.pass_to_std_string(
"Str") == 3
707 malformed_utf8 = b
"\x80"
708 if hasattr(m,
"PYBIND11_STR_LEGACY_PERMISSIVE"):
709 assert m.pass_to_pybind11_str(malformed_utf8) == 1
711 with pytest.raises(TypeError):
712 m.pass_to_pybind11_str(malformed_utf8)
715 @pytest.mark.parametrize(
716 (
"create_weakref",
"create_weakref_with_callback"),
718 (m.weakref_from_handle, m.weakref_from_handle_and_function),
719 (m.weakref_from_object, m.weakref_from_object_and_function),
723 from weakref
import getweakrefcount
726 class WeaklyReferenced:
729 callback_called =
False
732 nonlocal callback_called
733 callback_called =
True
735 obj = WeaklyReferenced()
736 assert getweakrefcount(obj) == 0
737 wr = create_weakref(obj)
738 assert getweakrefcount(obj) == 1
740 obj = WeaklyReferenced()
741 assert getweakrefcount(obj) == 0
742 wr = create_weakref_with_callback(obj, callback)
743 assert getweakrefcount(obj) == 1
744 assert not callback_called
747 assert callback_called
750 @pytest.mark.parametrize(
751 (
"create_weakref",
"has_callback"),
753 (m.weakref_from_handle,
False),
754 (m.weakref_from_object,
False),
755 (m.weakref_from_handle_and_function,
True),
756 (m.weakref_from_object_and_function,
True),
768 with pytest.raises(TypeError)
if not env.PYPY
else contextlib.nullcontext():
769 _ = create_weakref(ob, callback)
if has_callback
else create_weakref(ob)
773 assert m.tuple_iterator() == 12
774 assert m.dict_iterator() == 305 + 711
775 assert m.passed_iterator(
iter((-7, 3))) == -4
779 lst = [39, 43, 92, 49, 22, 29, 93, 98, 26, 57, 8]
781 assert m.sequence_item_get_ssize_t(lst) == 43
782 assert m.sequence_item_set_ssize_t(lst)
is None
783 assert lst[1] ==
"peppa"
784 assert m.sequence_item_get_size_t(lst) == 92
785 assert m.sequence_item_set_size_t(lst)
is None
786 assert lst[2] ==
"george"
787 assert m.list_item_get_ssize_t(lst) == 49
788 assert m.list_item_set_ssize_t(lst)
is None
789 assert lst[3] ==
"rebecca"
790 assert m.list_item_get_size_t(lst) == 22
791 assert m.list_item_set_size_t(lst)
is None
792 assert lst[4] ==
"richard"
793 assert m.tuple_item_get_ssize_t(tup) == 29
794 assert m.tuple_item_set_ssize_t() == (
"emely",
"edmond")
795 assert m.tuple_item_get_size_t(tup) == 93
796 assert m.tuple_item_set_size_t() == (
"candy",
"cat")
800 r1 = m.square_float_(2.0)
807 m.tuple_rvalue_getter(tup)
813 m.list_rvalue_getter(my_list)
818 my_dict = {i: i
for i
in range(pop)}
819 assert m.populate_dict_rvalue(pop) == my_dict
824 o = types.SimpleNamespace(**{
str(i): i
for i
in range(pop)})
825 new_o = m.populate_obj_str_attrs(o, pop)
826 new_attrs = {k: v
for k, v
in new_o.__dict__.items()
if not k.startswith(
"_")}
828 assert len(new_attrs) == pop
831 @pytest.mark.parametrize(
837 assert m.inplace_append(a, b) == expected
840 @pytest.mark.parametrize(
845 assert m.inplace_subtract(a, b) == expected
848 @pytest.mark.parametrize((
"a",
"b"), [(3, 2), (3.0, 2.0), ([1], 3)])
851 assert m.inplace_multiply(a, b) == expected
854 @pytest.mark.parametrize((
"a",
"b"), [(6, 3), (6.0, 3.0)])
857 assert m.inplace_divide(a, b) == expected
860 @pytest.mark.parametrize(
874 assert m.inplace_or(a, b) == expected
877 @pytest.mark.parametrize(
891 assert m.inplace_and(a, b) == expected
894 @pytest.mark.parametrize((
"a",
"b"), [(8, 1), (-3, 2)])
897 assert m.inplace_lshift(a, b) == expected
900 @pytest.mark.parametrize((
"a",
"b"), [(8, 1), (-2, 2)])
903 assert m.inplace_rshift(a, b) == expected
908 doc(m.annotate_tuple_float_str)
909 ==
"annotate_tuple_float_str(arg0: tuple[float, str]) -> None"
915 doc(m.annotate_tuple_empty) ==
"annotate_tuple_empty(arg0: tuple[()]) -> None"
921 doc(m.annotate_tuple_variable_length)
922 ==
"annotate_tuple_variable_length(arg0: tuple[float, ...]) -> None"
928 doc(m.annotate_dict_str_int)
929 ==
"annotate_dict_str_int(arg0: dict[str, int]) -> None"
934 assert doc(m.annotate_list_int) ==
"annotate_list_int(arg0: list[int]) -> None"
938 assert doc(m.annotate_set_str) ==
"annotate_set_str(arg0: set[str]) -> None"
943 doc(m.annotate_iterable_str)
944 ==
"annotate_iterable_str(arg0: Iterable[str]) -> None"
950 doc(m.annotate_iterator_int)
951 ==
"annotate_iterator_int(arg0: Iterator[int]) -> None"
958 ==
"annotate_fn(arg0: Callable[[list[str], str], int]) -> None"
964 doc(m.annotate_fn_only_return)
965 ==
"annotate_fn_only_return(arg0: Callable[..., int]) -> None"
970 assert doc(m.annotate_type) ==
"annotate_type(arg0: type[int]) -> type"
975 doc(m.annotate_union)
976 ==
"annotate_union(arg0: list[Union[str, int, object]], arg1: str, arg2: int, arg3: object) -> list[Union[str, int, object]]"
982 doc(m.union_typing_only)
983 ==
"union_typing_only(arg0: list[Union[str]]) -> list[Union[int]]"
989 doc(m.annotate_union_to_object)
990 ==
"annotate_union_to_object(arg0: Union[int, str]) -> object"
996 doc(m.annotate_optional)
997 ==
"annotate_optional(arg0: list) -> list[Optional[str]]"
1003 doc(m.annotate_type_guard)
1004 ==
"annotate_type_guard(arg0: object) -> TypeGuard[str]"
1009 assert doc(m.annotate_type_is) ==
"annotate_type_is(arg0: object) -> TypeIs[str]"
1013 assert doc(m.annotate_no_return) ==
"annotate_no_return() -> NoReturn"
1017 assert doc(m.annotate_never) ==
"annotate_never() -> Never"
1022 doc(m.annotate_optional_to_object)
1023 ==
"annotate_optional_to_object(arg0: Optional[int]) -> object"
1027 @pytest.mark.skipif(
1028 not m.if_defined__cpp_nontype_template_parameter_class,
1029 reason=
"C++20 feature not available.",
1033 doc(m.annotate_literal)
1034 ==
'annotate_literal(arg0: Literal[26, 0x1A, "hello world", b"hello world", u"hello world", True, Color.RED, None]) -> object'
1038 @pytest.mark.skipif(
1039 not m.if_defined__cpp_nontype_template_parameter_class,
1040 reason=
"C++20 feature not available.",
1044 doc(m.annotate_generic_containers)
1045 ==
"annotate_generic_containers(arg0: list[T]) -> list[V]"
1048 assert doc(m.annotate_listT_to_T) ==
"annotate_listT_to_T(arg0: list[T]) -> T"
1050 assert doc(m.annotate_object_to_T) ==
"annotate_object_to_T(arg0: object) -> T"