Removing uses of env.PY2 and env.PY (no longer available).

smart_holder_type_casters.h tweaks:
    * Removing MSVC 2015 workaround.
    * Manually adding braces to pre-empt clang-tidy issue (involving `#ifdef`).
    * Removing `// clang-format off` & `on`.
    * One manual line break (moving comment above line).

Adding mypy type information for ubench/*.py
This commit is contained in:
Ralf W. Grosse-Kunstleve 2022-02-14 14:44:31 -08:00
parent 5820767a18
commit d5e302ce46
6 changed files with 40 additions and 46 deletions

View File

@ -83,6 +83,7 @@ repos:
hooks: hooks:
- id: python-check-blanket-noqa - id: python-check-blanket-noqa
- id: python-check-blanket-type-ignore - id: python-check-blanket-type-ignore
exclude: ubench/holder_comparison.py
- id: python-no-log-warn - id: python-no-log-warn
- id: python-use-type-annotations - id: python-use-type-annotations
- id: rst-backticks - id: rst-backticks

View File

@ -49,7 +49,6 @@ inline void replace_all(std::string& str, const std::string& from, char to) {
// The modified_type_caster_generic_load_impl could replace type_caster_generic::load_impl but not // The modified_type_caster_generic_load_impl could replace type_caster_generic::load_impl but not
// vice versa. The main difference is that the original code only propagates a reference to the // vice versa. The main difference is that the original code only propagates a reference to the
// held value, while the modified implementation propagates value_and_holder. // held value, while the modified implementation propagates value_and_holder.
// clang-format off
class modified_type_caster_generic_load_impl { class modified_type_caster_generic_load_impl {
public: public:
PYBIND11_NOINLINE explicit modified_type_caster_generic_load_impl(const std::type_info &type_info) PYBIND11_NOINLINE explicit modified_type_caster_generic_load_impl(const std::type_info &type_info)
@ -76,12 +75,15 @@ public:
vptr = type->operator_new(type->type_size); vptr = type->operator_new(type->type_size);
} else { } else {
#if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912) #if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)
if (type->type_align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) if (type->type_align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
vptr = ::operator new(type->type_size, vptr = ::operator new(type->type_size,
std::align_val_t(type->type_align)); std::align_val_t(type->type_align));
else } else {
vptr = ::operator new(type->type_size);
}
#else
vptr = ::operator new(type->type_size);
#endif #endif
vptr = ::operator new(type->type_size);
} }
} }
// type_caster_generic::load_value END // type_caster_generic::load_value END
@ -182,7 +184,8 @@ public:
} }
loaded_v_h = foreign_loader->loaded_v_h; loaded_v_h = foreign_loader->loaded_v_h;
loaded_v_h_cpptype = foreign_loader->loaded_v_h_cpptype; loaded_v_h_cpptype = foreign_loader->loaded_v_h_cpptype;
implicit_casts = foreign_loader->implicit_casts; // SMART_HOLDER_WIP: should this be a copy or move? // SMART_HOLDER_WIP: should this be a copy or move?
implicit_casts = foreign_loader->implicit_casts;
return true; return true;
} }
return false; return false;
@ -297,7 +300,6 @@ public:
// set/reset this value in ctor/dtor, mark volatile. // set/reset this value in ctor/dtor, mark volatile.
std::size_t local_load_safety_guard = 1887406645; // 32-bit compatible value for portability. std::size_t local_load_safety_guard = 1887406645; // 32-bit compatible value for portability.
}; };
// clang-format on
struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag { struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag {
static decltype(&modified_type_caster_generic_load_impl::local_load) static decltype(&modified_type_caster_generic_load_impl::local_load)
@ -595,19 +597,15 @@ struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
static handle cast(T &&src, return_value_policy /*policy*/, handle parent) { static handle cast(T &&src, return_value_policy /*policy*/, handle parent) {
// type_caster_base BEGIN // type_caster_base BEGIN
// clang-format off
return cast(&src, return_value_policy::move, parent); return cast(&src, return_value_policy::move, parent);
// clang-format on
// type_caster_base END // type_caster_base END
} }
static handle cast(T const &src, return_value_policy policy, handle parent) { static handle cast(T const &src, return_value_policy policy, handle parent) {
// type_caster_base BEGIN // type_caster_base BEGIN
// clang-format off
if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference)
policy = return_value_policy::copy; policy = return_value_policy::copy;
return cast(&src, policy, parent); return cast(&src, policy, parent);
// clang-format on
// type_caster_base END // type_caster_base END
} }
@ -630,12 +628,6 @@ struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
return cast(const_cast<T const *>(src), policy, parent); // Mutbl2Const return cast(const_cast<T const *>(src), policy, parent); // Mutbl2Const
} }
#if defined(_MSC_VER) && _MSC_VER < 1910
// Working around MSVC 2015 bug. const-correctness is lost.
// SMART_HOLDER_WIP: IMPROVABLE: make common code work with MSVC 2015.
template <typename T_>
using cast_op_type = detail::cast_op_type<T_>;
#else
template <typename T_> template <typename T_>
using cast_op_type = conditional_t< using cast_op_type = conditional_t<
std::is_same<remove_reference_t<T_>, T const *>::value, std::is_same<remove_reference_t<T_>, T const *>::value,
@ -643,7 +635,6 @@ struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
conditional_t<std::is_same<remove_reference_t<T_>, T *>::value, conditional_t<std::is_same<remove_reference_t<T_>, T *>::value,
T *, T *,
conditional_t<std::is_same<T_, T const &>::value, T const &, T &>>>; conditional_t<std::is_same<T_, T const &>::value, T const &, T &>>>;
#endif
// The const operators here prove that the existing type_caster mechanism already supports // The const operators here prove that the existing type_caster mechanism already supports
// const-correctness. However, fully implementing const-correctness inside this type_caster // const-correctness. However, fully implementing const-correctness inside this type_caster

View File

@ -147,8 +147,7 @@ class MI8b(B3, MI6):
MI6.__init__(self, i) MI6.__init__(self, i)
@pytest.mark.skipif("env.PYPY and env.PY2") @pytest.mark.xfail("env.PYPY")
@pytest.mark.xfail("env.PYPY and not env.PY2")
def test_multiple_inheritance_python(): def test_multiple_inheritance_python():
# Based on test_multiple_inheritance.py:test_multiple_inheritance_python. # Based on test_multiple_inheritance.py:test_multiple_inheritance_python.
# Exercises values_and_holders with 2 value_and_holder instances. # Exercises values_and_holders with 2 value_and_holder instances.
@ -203,8 +202,7 @@ DISOWN_CLS_I_J_V_LIST = [
] ]
@pytest.mark.skipif("env.PYPY and env.PY2") @pytest.mark.xfail("env.PYPY", strict=False)
@pytest.mark.xfail("env.PYPY and not env.PY2", strict=False)
@pytest.mark.parametrize("cls, i, j, v", DISOWN_CLS_I_J_V_LIST) @pytest.mark.parametrize("cls, i, j, v", DISOWN_CLS_I_J_V_LIST)
def test_disown_base1_first(cls, i, j, v): def test_disown_base1_first(cls, i, j, v):
obj = cls(i, j) obj = cls(i, j)
@ -218,8 +216,7 @@ def test_disown_base1_first(cls, i, j, v):
assert obj.v() == v assert obj.v() == v
@pytest.mark.skipif("env.PYPY and env.PY2") @pytest.mark.xfail("env.PYPY", strict=False)
@pytest.mark.xfail("env.PYPY and not env.PY2", strict=False)
@pytest.mark.parametrize("cls, i, j, v", DISOWN_CLS_I_J_V_LIST) @pytest.mark.parametrize("cls, i, j, v", DISOWN_CLS_I_J_V_LIST)
def test_disown_base2_first(cls, i, j, v): def test_disown_base2_first(cls, i, j, v):
obj = cls(i, j) obj = cls(i, j)
@ -233,8 +230,7 @@ def test_disown_base2_first(cls, i, j, v):
assert obj.v() == v assert obj.v() == v
@pytest.mark.skipif("env.PYPY and env.PY2") @pytest.mark.xfail("env.PYPY", strict=False)
@pytest.mark.xfail("env.PYPY and not env.PY2", strict=False)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"cls, j, v", "cls, j, v",
[ [

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys
import weakref import weakref
import pytest import pytest
@ -213,7 +214,7 @@ def test_multiple_registered_instances_for_same_pointee_recursive():
# As of 2021-07-10 the pybind11 GitHub Actions valgrind build uses Python 3.9. # As of 2021-07-10 the pybind11 GitHub Actions valgrind build uses Python 3.9.
WORKAROUND_ENABLING_ROLLBACK_OF_PR3068 = env.LINUX and env.PY[:2] == (3, 9) WORKAROUND_ENABLING_ROLLBACK_OF_PR3068 = env.LINUX and sys.version_info == (3, 9)
def test_std_make_shared_factory(): def test_std_make_shared_factory():

View File

@ -2,25 +2,24 @@
"""Simple comparison of holder performances, relative to unique_ptr holder.""" """Simple comparison of holder performances, relative to unique_ptr holder."""
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
import collections import collections
import sys import sys
import time import time
from typing import Any, Callable, Dict, List
import pybind11_ubench_holder_comparison as m import pybind11_ubench_holder_comparison as m # type: ignore
number_bucket_pc = None number_bucket_pc = None
def pflush(*args, **kwargs): def pflush(*args: Any, **kwargs: Any) -> None:
result = print(*args, **kwargs) print(*args, **kwargs)
# Using "file" here because it is the name of the built-in keyword argument. # Using "file" here because it is the name of the built-in keyword argument.
file = kwargs.get("file", sys.stdout) # pylint: disable=redefined-builtin file = kwargs.get("file", sys.stdout) # pylint: disable=redefined-builtin
file.flush() # file object must have a flush method. file.flush() # file object must have a flush method.
return result
def run(args): def run(args: List[str]) -> None:
if not args: if not args:
size_exponent_min = 0 size_exponent_min = 0
size_exponent_max = 16 size_exponent_max = 16
@ -55,12 +54,12 @@ def run(args):
pflush("sizeof_smart_holder:", m.sizeof_smart_holder()) pflush("sizeof_smart_holder:", m.sizeof_smart_holder())
def find_call_repetitions( def find_call_repetitions(
callable, callable: Callable[[int], float],
time_delta_floor=1.0e-6, time_delta_floor: float = 1.0e-6,
target_elapsed_secs_multiplier=1.05, # Empirical. target_elapsed_secs_multiplier: float = 1.05, # Empirical.
target_elapsed_secs_tolerance=0.05, target_elapsed_secs_tolerance: float = 0.05,
max_iterations=100, max_iterations: int = 100,
): ) -> int:
td_target = ( td_target = (
call_repetitions_target_elapsed_secs * target_elapsed_secs_multiplier call_repetitions_target_elapsed_secs * target_elapsed_secs_multiplier
) )
@ -77,7 +76,7 @@ def run(args):
): ):
data_size = 2 ** size_exponent data_size = 2 ** size_exponent
pflush(data_size, "data_size") pflush(data_size, "data_size")
ratios = collections.defaultdict(list) ratios: Dict[str, List[float]] = collections.defaultdict(list)
call_repetitions = None call_repetitions = None
for _ in range(num_samples): for _ in range(num_samples):
row_0 = None row_0 = None
@ -92,17 +91,17 @@ def run(args):
continue continue
if selected_holder_type != "all" and nb_label != selected_holder_type: if selected_holder_type != "all" and nb_label != selected_holder_type:
continue continue
nb1 = nb_type(data_size) nb1 = nb_type(data_size) # type: ignore
nb2 = nb_type(data_size) nb2 = nb_type(data_size) # type: ignore
def many_sum(call_repetitions): def many_sum(call_repetitions: int) -> float:
assert int(round(nb1.sum())) == data_size assert int(round(nb1.sum())) == data_size
t0 = time.time() t0 = time.time()
for _ in range(call_repetitions): for _ in range(call_repetitions):
nb1.sum() nb1.sum()
return time.time() - t0 return time.time() - t0
def many_add(call_repetitions): def many_add(call_repetitions: int) -> float:
assert nb1.add(nb2) == data_size assert nb1.add(nb2) == data_size
t0 = time.time() t0 = time.time()
for _ in range(call_repetitions): for _ in range(call_repetitions):

View File

@ -4,9 +4,10 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
import sys import sys
from typing import List, Optional
def run(args): def run(args: List[str]) -> None:
assert len(args) == 1, "log_holder_comparison.txt" assert len(args) == 1, "log_holder_comparison.txt"
log_lines = open(args[0]).read().splitlines() log_lines = open(args[0]).read().splitlines()
@ -16,9 +17,9 @@ def run(args):
header = None header = None
header_row = None header_row = None
data_row = None data_row = None
data_row_buffer = [] data_row_buffer: List[List[str]] = []
def show(): def show() -> Optional[List[str]]:
if header_row: if header_row:
if header is None: if header is None:
print(",".join(header_row)) print(",".join(header_row))
@ -39,6 +40,8 @@ def run(args):
elif line.endswith(" call_repetitions"): elif line.endswith(" call_repetitions"):
flds = line.split() flds = line.split()
assert len(flds) == 2 assert len(flds) == 2
assert header_row is not None
assert data_row is not None
header_row.append("calls") header_row.append("calls")
data_row.append(flds[0]) data_row.append(flds[0])
header_row.append("up") header_row.append("up")
@ -46,10 +49,13 @@ def run(args):
elif line[2:].startswith(ratx): elif line[2:].startswith(ratx):
flds = line.split() flds = line.split()
assert len(flds) == 4 assert len(flds) == 4
assert header_row is not None
assert data_row is not None
header_row.append(line[:2]) header_row.append(line[:2])
data_row.append(flds[2]) data_row.append(flds[2])
show() show()
assert header_row is not None
print("Scaled to last column:") print("Scaled to last column:")
print(",".join(header_row)) print(",".join(header_row))
for data_row in data_row_buffer: for data_row in data_row_buffer: