Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:37:05

0001 import pickle
0002 import re
0003 
0004 import pytest
0005 
0006 import env
0007 from pybind11_tests import pickling as m
0008 
0009 
0010 def test_pickle_simple_callable():
0011     assert m.simple_callable() == 20220426
0012     if env.PYPY:
0013         serialized = pickle.dumps(m.simple_callable)
0014         deserialized = pickle.loads(serialized)
0015         assert deserialized() == 20220426
0016     else:
0017         # To document broken behavior: currently it fails universally with
0018         # all C Python versions.
0019         with pytest.raises(TypeError) as excinfo:
0020             pickle.dumps(m.simple_callable)
0021         assert re.search("can.*t pickle .*PyCapsule.* object", str(excinfo.value))
0022 
0023 
0024 @pytest.mark.parametrize("cls_name", ["Pickleable", "PickleableNew"])
0025 def test_roundtrip(cls_name):
0026     cls = getattr(m, cls_name)
0027     p = cls("test_value")
0028     p.setExtra1(15)
0029     p.setExtra2(48)
0030 
0031     data = pickle.dumps(p, 2)  # Must use pickle protocol >= 2
0032     p2 = pickle.loads(data)
0033     assert p2.value() == p.value()
0034     assert p2.extra1() == p.extra1()
0035     assert p2.extra2() == p.extra2()
0036 
0037 
0038 @pytest.mark.xfail("env.PYPY")
0039 @pytest.mark.parametrize("cls_name", ["PickleableWithDict", "PickleableWithDictNew"])
0040 def test_roundtrip_with_dict(cls_name):
0041     cls = getattr(m, cls_name)
0042     p = cls("test_value")
0043     p.extra = 15
0044     p.dynamic = "Attribute"
0045 
0046     data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL)
0047     p2 = pickle.loads(data)
0048     assert p2.value == p.value
0049     assert p2.extra == p.extra
0050     assert p2.dynamic == p.dynamic
0051 
0052 
0053 def test_enum_pickle():
0054     from pybind11_tests import enums as e
0055 
0056     data = pickle.dumps(e.EOne, 2)
0057     assert e.EOne == pickle.loads(data)
0058 
0059 
0060 #
0061 # exercise_trampoline
0062 #
0063 class SimplePyDerived(m.SimpleBase):
0064     pass
0065 
0066 
0067 def test_roundtrip_simple_py_derived():
0068     p = SimplePyDerived()
0069     p.num = 202
0070     p.stored_in_dict = 303
0071     data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL)
0072     p2 = pickle.loads(data)
0073     assert isinstance(p2, SimplePyDerived)
0074     assert p2.num == 202
0075     assert p2.stored_in_dict == 303
0076 
0077 
0078 def test_roundtrip_simple_cpp_derived():
0079     p = m.make_SimpleCppDerivedAsBase()
0080     assert m.check_dynamic_cast_SimpleCppDerived(p)
0081     p.num = 404
0082     if not env.PYPY:
0083         # To ensure that this unit test is not accidentally invalidated.
0084         with pytest.raises(AttributeError):
0085             # Mimics the `setstate` C++ implementation.
0086             setattr(p, "__dict__", {})  # noqa: B010
0087     data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL)
0088     p2 = pickle.loads(data)
0089     assert isinstance(p2, m.SimpleBase)
0090     assert p2.num == 404
0091     # Issue #3062: pickleable base C++ classes can incur object slicing
0092     #              if derived typeid is not registered with pybind11
0093     assert not m.check_dynamic_cast_SimpleCppDerived(p2)