Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:57

0001 import pytest
0002 
0003 from pybind11_tests import ConstructorStats, UserType
0004 from pybind11_tests import stl as m
0005 
0006 
0007 def test_vector(doc):
0008     """std::vector <-> list"""
0009     lst = m.cast_vector()
0010     assert lst == [1]
0011     lst.append(2)
0012     assert m.load_vector(lst)
0013     assert m.load_vector(tuple(lst))
0014 
0015     assert m.cast_bool_vector() == [True, False]
0016     assert m.load_bool_vector([True, False])
0017     assert m.load_bool_vector(tuple([True, False]))
0018 
0019     assert doc(m.cast_vector) == "cast_vector() -> List[int]"
0020     assert doc(m.load_vector) == "load_vector(arg0: List[int]) -> bool"
0021 
0022     # Test regression caused by 936: pointers to stl containers weren't castable
0023     assert m.cast_ptr_vector() == ["lvalue", "lvalue"]
0024 
0025 
0026 def test_deque(doc):
0027     """std::deque <-> list"""
0028     lst = m.cast_deque()
0029     assert lst == [1]
0030     lst.append(2)
0031     assert m.load_deque(lst)
0032     assert m.load_deque(tuple(lst))
0033 
0034 
0035 def test_array(doc):
0036     """std::array <-> list"""
0037     lst = m.cast_array()
0038     assert lst == [1, 2]
0039     assert m.load_array(lst)
0040     assert m.load_array(tuple(lst))
0041 
0042     assert doc(m.cast_array) == "cast_array() -> List[int[2]]"
0043     assert doc(m.load_array) == "load_array(arg0: List[int[2]]) -> bool"
0044 
0045 
0046 def test_valarray(doc):
0047     """std::valarray <-> list"""
0048     lst = m.cast_valarray()
0049     assert lst == [1, 4, 9]
0050     assert m.load_valarray(lst)
0051     assert m.load_valarray(tuple(lst))
0052 
0053     assert doc(m.cast_valarray) == "cast_valarray() -> List[int]"
0054     assert doc(m.load_valarray) == "load_valarray(arg0: List[int]) -> bool"
0055 
0056 
0057 def test_map(doc):
0058     """std::map <-> dict"""
0059     d = m.cast_map()
0060     assert d == {"key": "value"}
0061     assert "key" in d
0062     d["key2"] = "value2"
0063     assert "key2" in d
0064     assert m.load_map(d)
0065 
0066     assert doc(m.cast_map) == "cast_map() -> Dict[str, str]"
0067     assert doc(m.load_map) == "load_map(arg0: Dict[str, str]) -> bool"
0068 
0069 
0070 def test_set(doc):
0071     """std::set <-> set"""
0072     s = m.cast_set()
0073     assert s == {"key1", "key2"}
0074     s.add("key3")
0075     assert m.load_set(s)
0076     assert m.load_set(frozenset(s))
0077 
0078     assert doc(m.cast_set) == "cast_set() -> Set[str]"
0079     assert doc(m.load_set) == "load_set(arg0: Set[str]) -> bool"
0080 
0081 
0082 def test_recursive_casting():
0083     """Tests that stl casters preserve lvalue/rvalue context for container values"""
0084     assert m.cast_rv_vector() == ["rvalue", "rvalue"]
0085     assert m.cast_lv_vector() == ["lvalue", "lvalue"]
0086     assert m.cast_rv_array() == ["rvalue", "rvalue", "rvalue"]
0087     assert m.cast_lv_array() == ["lvalue", "lvalue"]
0088     assert m.cast_rv_map() == {"a": "rvalue"}
0089     assert m.cast_lv_map() == {"a": "lvalue", "b": "lvalue"}
0090     assert m.cast_rv_nested() == [[[{"b": "rvalue", "c": "rvalue"}], [{"a": "rvalue"}]]]
0091     assert m.cast_lv_nested() == {
0092         "a": [[["lvalue", "lvalue"]], [["lvalue", "lvalue"]]],
0093         "b": [[["lvalue", "lvalue"], ["lvalue", "lvalue"]]],
0094     }
0095 
0096     # Issue #853 test case:
0097     z = m.cast_unique_ptr_vector()
0098     assert z[0].value == 7 and z[1].value == 42
0099 
0100 
0101 def test_move_out_container():
0102     """Properties use the `reference_internal` policy by default. If the underlying function
0103     returns an rvalue, the policy is automatically changed to `move` to avoid referencing
0104     a temporary. In case the return value is a container of user-defined types, the policy
0105     also needs to be applied to the elements, not just the container."""
0106     c = m.MoveOutContainer()
0107     moved_out_list = c.move_list
0108     assert [x.value for x in moved_out_list] == [0, 1, 2]
0109 
0110 
0111 @pytest.mark.skipif(not hasattr(m, "has_optional"), reason="no <optional>")
0112 def test_optional():
0113     assert m.double_or_zero(None) == 0
0114     assert m.double_or_zero(42) == 84
0115     pytest.raises(TypeError, m.double_or_zero, "foo")
0116 
0117     assert m.half_or_none(0) is None
0118     assert m.half_or_none(42) == 21
0119     pytest.raises(TypeError, m.half_or_none, "foo")
0120 
0121     assert m.test_nullopt() == 42
0122     assert m.test_nullopt(None) == 42
0123     assert m.test_nullopt(42) == 42
0124     assert m.test_nullopt(43) == 43
0125 
0126     assert m.test_no_assign() == 42
0127     assert m.test_no_assign(None) == 42
0128     assert m.test_no_assign(m.NoAssign(43)) == 43
0129     pytest.raises(TypeError, m.test_no_assign, 43)
0130 
0131     assert m.nodefer_none_optional(None)
0132 
0133     holder = m.OptionalHolder()
0134     mvalue = holder.member
0135     assert mvalue.initialized
0136     assert holder.member_initialized()
0137 
0138     props = m.OptionalProperties()
0139     assert int(props.access_by_ref) == 42
0140     assert int(props.access_by_copy) == 42
0141 
0142 
0143 @pytest.mark.skipif(
0144     not hasattr(m, "has_exp_optional"), reason="no <experimental/optional>"
0145 )
0146 def test_exp_optional():
0147     assert m.double_or_zero_exp(None) == 0
0148     assert m.double_or_zero_exp(42) == 84
0149     pytest.raises(TypeError, m.double_or_zero_exp, "foo")
0150 
0151     assert m.half_or_none_exp(0) is None
0152     assert m.half_or_none_exp(42) == 21
0153     pytest.raises(TypeError, m.half_or_none_exp, "foo")
0154 
0155     assert m.test_nullopt_exp() == 42
0156     assert m.test_nullopt_exp(None) == 42
0157     assert m.test_nullopt_exp(42) == 42
0158     assert m.test_nullopt_exp(43) == 43
0159 
0160     assert m.test_no_assign_exp() == 42
0161     assert m.test_no_assign_exp(None) == 42
0162     assert m.test_no_assign_exp(m.NoAssign(43)) == 43
0163     pytest.raises(TypeError, m.test_no_assign_exp, 43)
0164 
0165     holder = m.OptionalExpHolder()
0166     mvalue = holder.member
0167     assert mvalue.initialized
0168     assert holder.member_initialized()
0169 
0170     props = m.OptionalExpProperties()
0171     assert int(props.access_by_ref) == 42
0172     assert int(props.access_by_copy) == 42
0173 
0174 
0175 @pytest.mark.skipif(not hasattr(m, "has_boost_optional"), reason="no <boost/optional>")
0176 def test_boost_optional():
0177     assert m.double_or_zero_boost(None) == 0
0178     assert m.double_or_zero_boost(42) == 84
0179     pytest.raises(TypeError, m.double_or_zero_boost, "foo")
0180 
0181     assert m.half_or_none_boost(0) is None
0182     assert m.half_or_none_boost(42) == 21
0183     pytest.raises(TypeError, m.half_or_none_boost, "foo")
0184 
0185     assert m.test_nullopt_boost() == 42
0186     assert m.test_nullopt_boost(None) == 42
0187     assert m.test_nullopt_boost(42) == 42
0188     assert m.test_nullopt_boost(43) == 43
0189 
0190     assert m.test_no_assign_boost() == 42
0191     assert m.test_no_assign_boost(None) == 42
0192     assert m.test_no_assign_boost(m.NoAssign(43)) == 43
0193     pytest.raises(TypeError, m.test_no_assign_boost, 43)
0194 
0195     holder = m.OptionalBoostHolder()
0196     mvalue = holder.member
0197     assert mvalue.initialized
0198     assert holder.member_initialized()
0199 
0200     props = m.OptionalBoostProperties()
0201     assert int(props.access_by_ref) == 42
0202     assert int(props.access_by_copy) == 42
0203 
0204 
0205 def test_reference_sensitive_optional():
0206     assert m.double_or_zero_refsensitive(None) == 0
0207     assert m.double_or_zero_refsensitive(42) == 84
0208     pytest.raises(TypeError, m.double_or_zero_refsensitive, "foo")
0209 
0210     assert m.half_or_none_refsensitive(0) is None
0211     assert m.half_or_none_refsensitive(42) == 21
0212     pytest.raises(TypeError, m.half_or_none_refsensitive, "foo")
0213 
0214     assert m.test_nullopt_refsensitive() == 42
0215     assert m.test_nullopt_refsensitive(None) == 42
0216     assert m.test_nullopt_refsensitive(42) == 42
0217     assert m.test_nullopt_refsensitive(43) == 43
0218 
0219     assert m.test_no_assign_refsensitive() == 42
0220     assert m.test_no_assign_refsensitive(None) == 42
0221     assert m.test_no_assign_refsensitive(m.NoAssign(43)) == 43
0222     pytest.raises(TypeError, m.test_no_assign_refsensitive, 43)
0223 
0224     holder = m.OptionalRefSensitiveHolder()
0225     mvalue = holder.member
0226     assert mvalue.initialized
0227     assert holder.member_initialized()
0228 
0229     props = m.OptionalRefSensitiveProperties()
0230     assert int(props.access_by_ref) == 42
0231     assert int(props.access_by_copy) == 42
0232 
0233 
0234 @pytest.mark.skipif(not hasattr(m, "has_filesystem"), reason="no <filesystem>")
0235 def test_fs_path():
0236     from pathlib import Path
0237 
0238     class PseudoStrPath:
0239         def __fspath__(self):
0240             return "foo/bar"
0241 
0242     class PseudoBytesPath:
0243         def __fspath__(self):
0244             return b"foo/bar"
0245 
0246     assert m.parent_path(Path("foo/bar")) == Path("foo")
0247     assert m.parent_path("foo/bar") == Path("foo")
0248     assert m.parent_path(b"foo/bar") == Path("foo")
0249     assert m.parent_path(PseudoStrPath()) == Path("foo")
0250     assert m.parent_path(PseudoBytesPath()) == Path("foo")
0251 
0252 
0253 @pytest.mark.skipif(not hasattr(m, "load_variant"), reason="no <variant>")
0254 def test_variant(doc):
0255     assert m.load_variant(1) == "int"
0256     assert m.load_variant("1") == "std::string"
0257     assert m.load_variant(1.0) == "double"
0258     assert m.load_variant(None) == "std::nullptr_t"
0259 
0260     assert m.load_variant_2pass(1) == "int"
0261     assert m.load_variant_2pass(1.0) == "double"
0262 
0263     assert m.cast_variant() == (5, "Hello")
0264 
0265     assert (
0266         doc(m.load_variant) == "load_variant(arg0: Union[int, str, float, None]) -> str"
0267     )
0268 
0269 
0270 @pytest.mark.skipif(
0271     not hasattr(m, "load_monostate_variant"), reason="no std::monostate"
0272 )
0273 def test_variant_monostate(doc):
0274     assert m.load_monostate_variant(None) == "std::monostate"
0275     assert m.load_monostate_variant(1) == "int"
0276     assert m.load_monostate_variant("1") == "std::string"
0277 
0278     assert m.cast_monostate_variant() == (None, 5, "Hello")
0279 
0280     assert (
0281         doc(m.load_monostate_variant)
0282         == "load_monostate_variant(arg0: Union[None, int, str]) -> str"
0283     )
0284 
0285 
0286 def test_vec_of_reference_wrapper():
0287     """#171: Can't return reference wrappers (or STL structures containing them)"""
0288     assert (
0289         str(m.return_vec_of_reference_wrapper(UserType(4)))
0290         == "[UserType(1), UserType(2), UserType(3), UserType(4)]"
0291     )
0292 
0293 
0294 def test_stl_pass_by_pointer(msg):
0295     """Passing nullptr or None to an STL container pointer is not expected to work"""
0296     with pytest.raises(TypeError) as excinfo:
0297         m.stl_pass_by_pointer()  # default value is `nullptr`
0298     assert (
0299         msg(excinfo.value)
0300         == """
0301         stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
0302             1. (v: List[int] = None) -> List[int]
0303 
0304         Invoked with:
0305     """
0306     )
0307 
0308     with pytest.raises(TypeError) as excinfo:
0309         m.stl_pass_by_pointer(None)
0310     assert (
0311         msg(excinfo.value)
0312         == """
0313         stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
0314             1. (v: List[int] = None) -> List[int]
0315 
0316         Invoked with: None
0317     """
0318     )
0319 
0320     assert m.stl_pass_by_pointer([1, 2, 3]) == [1, 2, 3]
0321 
0322 
0323 def test_missing_header_message():
0324     """Trying convert `list` to a `std::vector`, or vice versa, without including
0325     <pybind11/stl.h> should result in a helpful suggestion in the error message"""
0326     import pybind11_cross_module_tests as cm
0327 
0328     expected_message = (
0329         "Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,\n"
0330         "<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic\n"
0331         "conversions are optional and require extra headers to be included\n"
0332         "when compiling your pybind11 module."
0333     )
0334 
0335     with pytest.raises(TypeError) as excinfo:
0336         cm.missing_header_arg([1.0, 2.0, 3.0])
0337     assert expected_message in str(excinfo.value)
0338 
0339     with pytest.raises(TypeError) as excinfo:
0340         cm.missing_header_return()
0341     assert expected_message in str(excinfo.value)
0342 
0343 
0344 def test_function_with_string_and_vector_string_arg():
0345     """Check if a string is NOT implicitly converted to a list, which was the
0346     behavior before fix of issue #1258"""
0347     assert m.func_with_string_or_vector_string_arg_overload(("A", "B")) == 2
0348     assert m.func_with_string_or_vector_string_arg_overload(["A", "B"]) == 2
0349     assert m.func_with_string_or_vector_string_arg_overload("A") == 3
0350 
0351 
0352 def test_stl_ownership():
0353     cstats = ConstructorStats.get(m.Placeholder)
0354     assert cstats.alive() == 0
0355     r = m.test_stl_ownership()
0356     assert len(r) == 1
0357     del r
0358     assert cstats.alive() == 0
0359 
0360 
0361 def test_array_cast_sequence():
0362     assert m.array_cast_sequence((1, 2, 3)) == [1, 2, 3]
0363 
0364 
0365 def test_issue_1561():
0366     """check fix for issue #1561"""
0367     bar = m.Issue1561Outer()
0368     bar.list = [m.Issue1561Inner("bar")]
0369     bar.list
0370     assert bar.list[0].data == "bar"
0371 
0372 
0373 def test_return_vector_bool_raw_ptr():
0374     # Add `while True:` for manual leak checking.
0375     v = m.return_vector_bool_raw_ptr()
0376     assert isinstance(v, list)
0377     assert len(v) == 4513