perf: Add object rvalue overload for accessors. Enables reference stealing (#3970)

* Add object rvalue overload for accessors. Enables reference stealing

* Fix comments

* Fix more comment typos

* Fix bug

* reorder declarations for clarity

* fix another perf bug

* should be static

* future proof operator overloads

* Fix perfect forwarding

* Add a couple of tests

* Remove errant include

* Improve test documentation

* Add dict test

* add object attr tests

* Optimize STL map caster and cleanup enum

* Reorder to match declarations

* adjust increfs

* Remove comment

* revert value change

* add missing move
This commit is contained in:
Aaron Gokaslan
2022-06-01 15:19:13 -04:00
committed by GitHub
parent 9f7b3f735a
commit 58802de41b
5 changed files with 97 additions and 12 deletions

View File

@@ -1,5 +1,6 @@
import contextlib
import sys
import types
import pytest
@@ -320,8 +321,7 @@ def test_accessors():
def test_accessor_moves():
inc_refs = m.accessor_moves()
if inc_refs:
# To be changed in PR #3970: [1, 0, 1, 0, ...]
assert inc_refs == [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
assert inc_refs == [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
else:
pytest.skip("Not defined: PYBIND11_HANDLE_REF_DEBUG")
@@ -707,3 +707,30 @@ def test_implementation_details():
def test_external_float_():
r1 = m.square_float_(2.0)
assert r1 == 4.0
def test_tuple_rvalue_getter():
pop = 1000
tup = tuple(range(pop))
m.tuple_rvalue_getter(tup)
def test_list_rvalue_getter():
pop = 1000
my_list = list(range(pop))
m.list_rvalue_getter(my_list)
def test_populate_dict_rvalue():
pop = 1000
my_dict = {i: i for i in range(pop)}
assert m.populate_dict_rvalue(pop) == my_dict
def test_populate_obj_str_attrs():
pop = 1000
o = types.SimpleNamespace(**{str(i): i for i in range(pop)})
new_o = m.populate_obj_str_attrs(o, pop)
new_attrs = {k: v for k, v in new_o.__dict__.items() if not k.startswith("_")}
assert all(isinstance(v, str) for v in new_attrs.values())
assert len(new_attrs) == pop