Avatar for the PyO3 user
PyO3
pyo3
BlogDocsChangelog

Turn calls of __traverse__ into no-ops for unsendable pyclass if on the wrong thread

#3689Merged
Comparing
unsendable-threadsafe-traverse
(
4dc6c16
) with
main
(
65f25d4
)
CodSpeed Performance Gauge
0%
Improvements
0
Regressions
0
Untouched
62
New
0
Dropped
0
Ignored
16

Benchmarks

Passed

test_empty_class_init
pytests/tests/test_pyclasses.py::test_empty_class_init
CodSpeed Performance Gauge
+1%
22.4 µs
22.1 µs
getattr_intern
pyo3-benches/benches/bench_intern.rs::benches::criterion_benchmark::getattr_intern
CodSpeed Performance Gauge
+1%
3.1 µs
3.1 µs
dirty_acquire_gil
pyo3-benches/benches/bench_gil.rs::benches::criterion_benchmark::dirty_acquire_gil
CodSpeed Performance Gauge
+1%
4.4 µs
4.4 µs
test_simple_kwargs_py
pytests/tests/test_pyfunctions.py::test_simple_kwargs_py
CodSpeed Performance Gauge
+1%
22.5 µs
22.4 µs
decimal_via_extract
pyo3-benches/benches/bench_decimal.rs::benches::criterion_benchmark::decimal_via_extract
CodSpeed Performance Gauge
+1%
14.9 µs
14.8 µs
test_empty_class_init_py
pytests/tests/test_pyclasses.py::test_empty_class_init_py
CodSpeed Performance Gauge
+1%
16.1 µs
16.1 µs
test_none_rs
pytests/tests/test_pyfunctions.py::test_none_rs
CodSpeed Performance Gauge
0%
12 µs
12 µs
test_simple_py
pytests/tests/test_pyfunctions.py::test_simple_py
CodSpeed Performance Gauge
0%
18.2 µs
18.2 µs
first_time_init
pyo3-benches/benches/bench_pyclass.rs::benches::criterion_benchmark::first_time_init
CodSpeed Performance Gauge
0%
39.2 µs
39.1 µs
extract_bigint_huge_positive
pyo3-benches/benches/bench_bigint.rs::benches::criterion_benchmark::extract_bigint_huge_positive
CodSpeed Performance Gauge
0%
12.2 µs
12.2 µs
extract_btreemap
pyo3-benches/benches/bench_dict.rs::benches::criterion_benchmark::extract_btreemap
CodSpeed Performance Gauge
0%
44.3 ms
44.2 ms
list_get_item_unchecked
pyo3-benches/benches/bench_list.rs::benches::criterion_benchmark::list_get_item_unchecked
CodSpeed Performance Gauge
0%
4.5 ms
4.5 ms
extract_btreeset
pyo3-benches/benches/bench_set.rs::benches::criterion_benchmark::extract_btreeset
CodSpeed Performance Gauge
0%
21.2 ms
21.2 ms
list_get_item
pyo3-benches/benches/bench_list.rs::benches::criterion_benchmark::list_get_item
CodSpeed Performance Gauge
0%
5 ms
5 ms
iter_list
pyo3-benches/benches/bench_list.rs::benches::criterion_benchmark::iter_list
CodSpeed Performance Gauge
0%
9 ms
9 ms
tuple_new
pyo3-benches/benches/bench_tuple.rs::benches::criterion_benchmark::tuple_new
CodSpeed Performance Gauge
0%
6.7 ms
6.7 ms
dict_new
pyo3-benches/benches/bench_dict.rs::benches::criterion_benchmark::dict_new
CodSpeed Performance Gauge
0%
24.8 ms
24.8 ms
iter_set
pyo3-benches/benches/bench_set.rs::benches::criterion_benchmark::iter_set
CodSpeed Performance Gauge
0%
16.7 ms
16.7 ms
set_new
pyo3-benches/benches/bench_set.rs::benches::criterion_benchmark::set_new
CodSpeed Performance Gauge
0%
18.8 ms
18.8 ms
dict_get_item
pyo3-benches/benches/bench_dict.rs::benches::criterion_benchmark::dict_get_item
CodSpeed Performance Gauge
0%
17.3 ms
17.3 ms
extract_hashmap
pyo3-benches/benches/bench_dict.rs::benches::criterion_benchmark::extract_hashmap
CodSpeed Performance Gauge
0%
25.1 ms
25.1 ms
extract_bigint_big_positive
pyo3-benches/benches/bench_bigint.rs::benches::criterion_benchmark::extract_bigint_big_positive
CodSpeed Performance Gauge
0%
3.7 µs
3.7 µs
call_0
pyo3-benches/benches/bench_call.rs::benches::criterion_benchmark::call_0
CodSpeed Performance Gauge
0%
213.9 µs
213.9 µs
err_new_restore_and_fetch
pyo3-benches/benches/bench_err.rs::benches::criterion_benchmark::err_new_restore_and_fetch
CodSpeed Performance Gauge
0%
7.5 µs
7.5 µs
err_new_without_gil
pyo3-benches/benches/bench_err.rs::benches::criterion_benchmark::err_new_without_gil
CodSpeed Performance Gauge
0%
1.3 µs
1.3 µs
f64_from_pyobject
pyo3-benches/benches/bench_frompyobject.rs::benches::criterion_benchmark::f64_from_pyobject
CodSpeed Performance Gauge
0%
241.7 ns
241.7 ns
not_a_list_via_extract
pyo3-benches/benches/bench_frompyobject.rs::benches::criterion_benchmark::not_a_list_via_extract
CodSpeed Performance Gauge
0%
1.7 µs
1.7 µs
clean_acquire_gil
pyo3-benches/benches/bench_gil.rs::benches::criterion_benchmark::clean_acquire_gil
CodSpeed Performance Gauge
0%
3.6 µs
3.6 µs
clean_gilpool_new
pyo3-benches/benches/bench_gil.rs::benches::criterion_benchmark::clean_gilpool_new
CodSpeed Performance Gauge
0%
559.2 ns
559.2 ns
drop_many_objects
pyo3-benches/benches/bench_pyobject.rs::benches::criterion_benchmark::drop_many_objects
CodSpeed Performance Gauge
0%
9.4 µs
9.4 µs
tuple_into_py
pyo3-benches/benches/bench_tuple.rs::benches::criterion_benchmark::tuple_into_py
CodSpeed Performance Gauge
0%
2.9 µs
2.9 µs
test_args_kwargs_rs
pytests/tests/test_pyfunctions.py::test_args_kwargs_rs
CodSpeed Performance Gauge
0%
15.8 µs
15.8 µs
test_none_py
pytests/tests/test_pyfunctions.py::test_none_py
CodSpeed Performance Gauge
0%
12 µs
12 µs
collect_generic_iterator
pyo3-benches/benches/bench_any.rs::benches::criterion_benchmark::collect_generic_iterator
CodSpeed Performance Gauge
0%
90 ms
90 ms
list_new
pyo3-benches/benches/bench_list.rs::benches::criterion_benchmark::list_new
CodSpeed Performance Gauge
0%
6.7 ms
6.7 ms
tuple_to_list
pyo3-benches/benches/bench_tuple.rs::benches::criterion_benchmark::tuple_to_list
CodSpeed Performance Gauge
0%
1.9 ms
1.9 ms
iter_dict
pyo3-benches/benches/bench_dict.rs::benches::criterion_benchmark::iter_dict
CodSpeed Performance Gauge
0%
15.4 ms
15.4 ms
iter_tuple
pyo3-benches/benches/bench_tuple.rs::benches::criterion_benchmark::iter_tuple
CodSpeed Performance Gauge
0%
6.8 ms
6.8 ms
tuple_get_item_unchecked
pyo3-benches/benches/bench_tuple.rs::benches::criterion_benchmark::tuple_get_item_unchecked
CodSpeed Performance Gauge
0%
3.7 ms
3.7 ms
tuple_new_list
pyo3-benches/benches/bench_tuple.rs::benches::criterion_benchmark::tuple_new_list
CodSpeed Performance Gauge
0%
2.5 ms
2.5 ms
tuple_get_item
pyo3-benches/benches/bench_tuple.rs::benches::criterion_benchmark::tuple_get_item
CodSpeed Performance Gauge
0%
4.2 ms
4.2 ms
extract_int_extract_fail
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_int_extract_fail
CodSpeed Performance Gauge
0%
11.4 µs
11.4 µs
extract_hashset
pyo3-benches/benches/bench_set.rs::benches::criterion_benchmark::extract_hashset
CodSpeed Performance Gauge
0%
23 ms
23 ms
test_simple_args_kwargs_py
pytests/tests/test_pyfunctions.py::test_simple_args_kwargs_py
CodSpeed Performance Gauge
0%
21.4 µs
21.4 µs
enum_from_pyobject
pyo3-benches/benches/bench_frompyobject.rs::benches::criterion_benchmark::enum_from_pyobject
CodSpeed Performance Gauge
0%
19.4 µs
19.5 µs
test_simple_rs
pytests/tests/test_pyfunctions.py::test_simple_rs
CodSpeed Performance Gauge
0%
18.9 µs
18.9 µs
identify_object_type
pyo3-benches/benches/bench_any.rs::benches::criterion_benchmark::identify_object_type
CodSpeed Performance Gauge
0%
15.5 µs
15.5 µs
extract_bigint_extract_fail
pyo3-benches/benches/bench_bigint.rs::benches::criterion_benchmark::extract_bigint_extract_fail
CodSpeed Performance Gauge
0%
11.5 µs
11.5 µs
extract_bigint_huge_negative
pyo3-benches/benches/bench_bigint.rs::benches::criterion_benchmark::extract_bigint_huge_negative
CodSpeed Performance Gauge
0%
13.5 µs
13.5 µs
not_a_list_via_extract_enum
pyo3-benches/benches/bench_frompyobject.rs::benches::criterion_benchmark::not_a_list_via_extract_enum
CodSpeed Performance Gauge
0%
13.8 µs
13.9 µs
test_simple_args_kwargs_rs
pytests/tests/test_pyfunctions.py::test_simple_args_kwargs_rs
CodSpeed Performance Gauge
0%
23.9 µs
24 µs
test_args_kwargs_py
pytests/tests/test_pyfunctions.py::test_args_kwargs_py
CodSpeed Performance Gauge
0%
21.1 µs
21.2 µs
test_simple_kwargs_rs
pytests/tests/test_pyfunctions.py::test_simple_kwargs_rs
CodSpeed Performance Gauge
-1%
22.9 µs
23 µs
extract_bigint_big_negative
pyo3-benches/benches/bench_bigint.rs::benches::criterion_benchmark::extract_bigint_big_negative
CodSpeed Performance Gauge
-1%
4 µs
4.1 µs
extract_float_extract_fail
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_float_extract_fail
CodSpeed Performance Gauge
-1%
11.4 µs
11.5 µs
test_simple_args_py
pytests/tests/test_pyfunctions.py::test_simple_args_py
CodSpeed Performance Gauge
-1%
18 µs
18.2 µs
ordered_richcmp
pyo3-benches/benches/bench_comparisons.rs::benches::criterion_benchmark::ordered_richcmp
CodSpeed Performance Gauge
-1%
3.1 µs
3.2 µs
call_method_0
pyo3-benches/benches/bench_call.rs::benches::criterion_benchmark::call_method_0
CodSpeed Performance Gauge
-1%
684.3 µs
691.3 µs
test_simple_args_rs
pytests/tests/test_pyfunctions.py::test_simple_args_rs
CodSpeed Performance Gauge
-1%
21.6 µs
21.9 µs
ordered_dunder_methods
pyo3-benches/benches/bench_comparisons.rs::benches::criterion_benchmark::ordered_dunder_methods
CodSpeed Performance Gauge
-2%
3.1 µs
3.2 µs
extract_bigint_small
pyo3-benches/benches/bench_bigint.rs::benches::criterion_benchmark::extract_bigint_small
CodSpeed Performance Gauge
-2%
2.9 µs
3 µs
extract_str_extract_fail
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_str_extract_fail
CodSpeed Performance Gauge
-3%
1.8 µs
1.9 µs

Ignored

mapping_from_dictIgnored
pyo3-benches/benches/bench_dict.rs::benches::criterion_benchmark::mapping_from_dict
CodSpeed Performance Gauge
0%
330 ns
330 ns
extract_float_downcast_failIgnored
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_float_downcast_fail
CodSpeed Performance Gauge
+7%
428.6 ns
399.4 ns
extract_float_downcast_successIgnored
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_float_downcast_success
CodSpeed Performance Gauge
0%
425 ns
425 ns
extract_float_extract_successIgnored
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_float_extract_success
CodSpeed Performance Gauge
0%
271.7 ns
271.7 ns
extract_int_downcast_failIgnored
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_int_downcast_fail
CodSpeed Performance Gauge
0%
216.1 ns
216.1 ns
extract_int_downcast_successIgnored
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_int_downcast_success
CodSpeed Performance Gauge
0%
741.7 ns
741.7 ns
extract_int_extract_successIgnored
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_int_extract_success
CodSpeed Performance Gauge
0%
646.9 ns
646.9 ns
extract_str_downcast_failIgnored
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_str_downcast_fail
CodSpeed Performance Gauge
0%
216.1 ns
216.1 ns
extract_str_downcast_successIgnored
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_str_downcast_success
CodSpeed Performance Gauge
0%
551.9 ns
551.9 ns
extract_str_extract_successIgnored
pyo3-benches/benches/bench_extract.rs::benches::criterion_benchmark::extract_str_extract_success
CodSpeed Performance Gauge
+7%
458.3 ns
429.2 ns
list_via_downcastIgnored
pyo3-benches/benches/bench_frompyobject.rs::benches::criterion_benchmark::list_via_downcast
CodSpeed Performance Gauge
0%
119.2 ns
119.2 ns
list_via_extractIgnored
pyo3-benches/benches/bench_frompyobject.rs::benches::criterion_benchmark::list_via_extract
CodSpeed Performance Gauge
0%
148.3 ns
148.3 ns
not_a_list_via_downcastIgnored
pyo3-benches/benches/bench_frompyobject.rs::benches::criterion_benchmark::not_a_list_via_downcast
CodSpeed Performance Gauge
0%
119.2 ns
119.2 ns
getattr_directIgnored
pyo3-benches/benches/bench_intern.rs::benches::criterion_benchmark::getattr_direct
CodSpeed Performance Gauge
+1%
6.8 µs
6.8 µs
sequence_from_listIgnored
pyo3-benches/benches/bench_list.rs::benches::criterion_benchmark::sequence_from_list
CodSpeed Performance Gauge
0%
271.9 ns
271.9 ns
sequence_from_tupleIgnored
pyo3-benches/benches/bench_tuple.rs::benches::criterion_benchmark::sequence_from_tuple
CodSpeed Performance Gauge
0%
242.8 ns
242.8 ns

Commits

Click on a commit to change the comparison range
Base
main
65f25d4
0%
Turn calls of __traverse__ into no-ops for unsendable pyclass if on the wrong thread Adds a "threadsafe" variant of `PyCell::try_borrow` which will fail instead of panicking if called on the wrong thread and use it in `call_traverse` to turn GC traversals of unsendable pyclasses into no-ops if on the wrong thread. This can imply leaking the underlying resource if the originator thread has already exited so that the GC will never run there again, but it does avoid hard aborts as we cannot raise an exception from within `call_traverse`.
4dc6c16
1 year ago
by adamreichold
© 2025 CodSpeed Technology
Home Terms PrivacyDocs