Unverified Commit c50f90ec authored by Henry Schreiner's avatar Henry Schreiner Committed by GitHub
Browse files

style: use Black everywhere (#2594)

* style: use Black everywhere

* style: minor touchup from review
parent 2e31e466
...@@ -15,11 +15,17 @@ def test_function_signatures(doc): ...@@ -15,11 +15,17 @@ def test_function_signatures(doc):
assert doc(m.kw_func_udl) == "kw_func_udl(x: int, y: int = 300) -> str" assert doc(m.kw_func_udl) == "kw_func_udl(x: int, y: int = 300) -> str"
assert doc(m.kw_func_udl_z) == "kw_func_udl_z(x: int, y: int = 0) -> str" assert doc(m.kw_func_udl_z) == "kw_func_udl_z(x: int, y: int = 0) -> str"
assert doc(m.args_function) == "args_function(*args) -> tuple" assert doc(m.args_function) == "args_function(*args) -> tuple"
assert doc(m.args_kwargs_function) == "args_kwargs_function(*args, **kwargs) -> tuple" assert (
assert doc(m.KWClass.foo0) == \ doc(m.args_kwargs_function) == "args_kwargs_function(*args, **kwargs) -> tuple"
"foo0(self: m.kwargs_and_defaults.KWClass, arg0: int, arg1: float) -> None" )
assert doc(m.KWClass.foo1) == \ assert (
"foo1(self: m.kwargs_and_defaults.KWClass, x: int, y: float) -> None" doc(m.KWClass.foo0)
== "foo0(self: m.kwargs_and_defaults.KWClass, arg0: int, arg1: float) -> None"
)
assert (
doc(m.KWClass.foo1)
== "foo1(self: m.kwargs_and_defaults.KWClass, x: int, y: float) -> None"
)
def test_named_arguments(msg): def test_named_arguments(msg):
...@@ -40,7 +46,9 @@ def test_named_arguments(msg): ...@@ -40,7 +46,9 @@ def test_named_arguments(msg):
# noinspection PyArgumentList # noinspection PyArgumentList
m.kw_func2(x=5, y=10, z=12) m.kw_func2(x=5, y=10, z=12)
assert excinfo.match( assert excinfo.match(
r'(?s)^kw_func2\(\): incompatible.*Invoked with: kwargs: ((x=5|y=10|z=12)(, |$))' + '{3}$') r"(?s)^kw_func2\(\): incompatible.*Invoked with: kwargs: ((x=5|y=10|z=12)(, |$))"
+ "{3}$"
)
assert m.kw_func4() == "{13 17}" assert m.kw_func4() == "{13 17}"
assert m.kw_func4(myList=[1, 2, 3]) == "{1 2 3}" assert m.kw_func4(myList=[1, 2, 3]) == "{1 2 3}"
...@@ -50,11 +58,11 @@ def test_named_arguments(msg): ...@@ -50,11 +58,11 @@ def test_named_arguments(msg):
def test_arg_and_kwargs(): def test_arg_and_kwargs():
args = 'arg1_value', 'arg2_value', 3 args = "arg1_value", "arg2_value", 3
assert m.args_function(*args) == args assert m.args_function(*args) == args
args = 'a1', 'a2' args = "a1", "a2"
kwargs = dict(arg3='a3', arg4=4) kwargs = dict(arg3="a3", arg4=4)
assert m.args_kwargs_function(*args, **kwargs) == (args, kwargs) assert m.args_kwargs_function(*args, **kwargs) == (args, kwargs)
...@@ -68,47 +76,71 @@ def test_mixed_args_and_kwargs(msg): ...@@ -68,47 +76,71 @@ def test_mixed_args_and_kwargs(msg):
assert mpa(1, 2.5) == (1, 2.5, ()) assert mpa(1, 2.5) == (1, 2.5, ())
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
assert mpa(1) assert mpa(1)
assert msg(excinfo.value) == """ assert (
msg(excinfo.value)
== """
mixed_plus_args(): incompatible function arguments. The following argument types are supported: mixed_plus_args(): incompatible function arguments. The following argument types are supported:
1. (arg0: int, arg1: float, *args) -> tuple 1. (arg0: int, arg1: float, *args) -> tuple
Invoked with: 1 Invoked with: 1
""" # noqa: E501 line too long """ # noqa: E501 line too long
)
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
assert mpa() assert mpa()
assert msg(excinfo.value) == """ assert (
msg(excinfo.value)
== """
mixed_plus_args(): incompatible function arguments. The following argument types are supported: mixed_plus_args(): incompatible function arguments. The following argument types are supported:
1. (arg0: int, arg1: float, *args) -> tuple 1. (arg0: int, arg1: float, *args) -> tuple
Invoked with: Invoked with:
""" # noqa: E501 line too long """ # noqa: E501 line too long
)
assert mpk(-2, 3.5, pi=3.14159, e=2.71828) == (-2, 3.5, {'e': 2.71828, 'pi': 3.14159}) assert mpk(-2, 3.5, pi=3.14159, e=2.71828) == (
-2,
3.5,
{"e": 2.71828, "pi": 3.14159},
)
assert mpak(7, 7.7, 7.77, 7.777, 7.7777, minusseven=-7) == ( assert mpak(7, 7.7, 7.77, 7.777, 7.7777, minusseven=-7) == (
7, 7.7, (7.77, 7.777, 7.7777), {'minusseven': -7}) 7,
7.7,
(7.77, 7.777, 7.7777),
{"minusseven": -7},
)
assert mpakd() == (1, 3.14159, (), {}) assert mpakd() == (1, 3.14159, (), {})
assert mpakd(3) == (3, 3.14159, (), {}) assert mpakd(3) == (3, 3.14159, (), {})
assert mpakd(j=2.71828) == (1, 2.71828, (), {}) assert mpakd(j=2.71828) == (1, 2.71828, (), {})
assert mpakd(k=42) == (1, 3.14159, (), {'k': 42}) assert mpakd(k=42) == (1, 3.14159, (), {"k": 42})
assert mpakd(1, 1, 2, 3, 5, 8, then=13, followedby=21) == ( assert mpakd(1, 1, 2, 3, 5, 8, then=13, followedby=21) == (
1, 1, (2, 3, 5, 8), {'then': 13, 'followedby': 21}) 1,
1,
(2, 3, 5, 8),
{"then": 13, "followedby": 21},
)
# Arguments specified both positionally and via kwargs should fail: # Arguments specified both positionally and via kwargs should fail:
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
assert mpakd(1, i=1) assert mpakd(1, i=1)
assert msg(excinfo.value) == """ assert (
msg(excinfo.value)
== """
mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported: mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:
1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple 1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple
Invoked with: 1; kwargs: i=1 Invoked with: 1; kwargs: i=1
""" # noqa: E501 line too long """ # noqa: E501 line too long
)
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
assert mpakd(1, 2, j=1) assert mpakd(1, 2, j=1)
assert msg(excinfo.value) == """ assert (
msg(excinfo.value)
== """
mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported: mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:
1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple 1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple
Invoked with: 1, 2; kwargs: j=1 Invoked with: 1, 2; kwargs: j=1
""" # noqa: E501 line too long """ # noqa: E501 line too long
)
def test_keyword_only_args(msg): def test_keyword_only_args(msg):
...@@ -134,9 +166,9 @@ def test_keyword_only_args(msg): ...@@ -134,9 +166,9 @@ def test_keyword_only_args(msg):
assert m.kw_only_mixed(j=2, i=3) == (3, 2) assert m.kw_only_mixed(j=2, i=3) == (3, 2)
assert m.kw_only_mixed(i=2, j=3) == (2, 3) assert m.kw_only_mixed(i=2, j=3) == (2, 3)
assert m.kw_only_plus_more(4, 5, k=6, extra=7) == (4, 5, 6, {'extra': 7}) assert m.kw_only_plus_more(4, 5, k=6, extra=7) == (4, 5, 6, {"extra": 7})
assert m.kw_only_plus_more(3, k=5, j=4, extra=6) == (3, 4, 5, {'extra': 6}) assert m.kw_only_plus_more(3, k=5, j=4, extra=6) == (3, 4, 5, {"extra": 6})
assert m.kw_only_plus_more(2, k=3, extra=4) == (2, -1, 3, {'extra': 4}) assert m.kw_only_plus_more(2, k=3, extra=4) == (2, -1, 3, {"extra": 4})
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
assert m.kw_only_mixed(i=1) == (1,) assert m.kw_only_mixed(i=1) == (1,)
...@@ -144,9 +176,12 @@ def test_keyword_only_args(msg): ...@@ -144,9 +176,12 @@ def test_keyword_only_args(msg):
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
m.register_invalid_kw_only(m) m.register_invalid_kw_only(m)
assert msg(excinfo.value) == """ assert (
msg(excinfo.value)
== """
arg(): cannot specify an unnamed argument after an kw_only() annotation arg(): cannot specify an unnamed argument after an kw_only() annotation
""" """
)
def test_positional_only_args(msg): def test_positional_only_args(msg):
...@@ -194,7 +229,10 @@ def test_signatures(): ...@@ -194,7 +229,10 @@ def test_signatures():
assert "kw_only_mixed(i: int, *, j: int) -> tuple\n" == m.kw_only_mixed.__doc__ assert "kw_only_mixed(i: int, *, j: int) -> tuple\n" == m.kw_only_mixed.__doc__
assert "pos_only_all(i: int, j: int, /) -> tuple\n" == m.pos_only_all.__doc__ assert "pos_only_all(i: int, j: int, /) -> tuple\n" == m.pos_only_all.__doc__
assert "pos_only_mix(i: int, /, j: int) -> tuple\n" == m.pos_only_mix.__doc__ assert "pos_only_mix(i: int, /, j: int) -> tuple\n" == m.pos_only_mix.__doc__
assert "pos_kw_only_mix(i: int, /, j: int, *, k: int) -> tuple\n" == m.pos_kw_only_mix.__doc__ assert (
"pos_kw_only_mix(i: int, /, j: int, *, k: int) -> tuple\n"
== m.pos_kw_only_mix.__doc__
)
@pytest.mark.xfail("env.PYPY and env.PY2", reason="PyPy2 doesn't double count") @pytest.mark.xfail("env.PYPY and env.PY2", reason="PyPy2 doesn't double count")
...@@ -219,11 +257,18 @@ def test_args_refcount(): ...@@ -219,11 +257,18 @@ def test_args_refcount():
assert m.args_function(-1, myval) == (-1, myval) assert m.args_function(-1, myval) == (-1, myval)
assert refcount(myval) == expected assert refcount(myval) == expected
assert m.mixed_plus_args_kwargs(5, 6.0, myval, a=myval) == (5, 6.0, (myval,), {"a": myval}) assert m.mixed_plus_args_kwargs(5, 6.0, myval, a=myval) == (
5,
6.0,
(myval,),
{"a": myval},
)
assert refcount(myval) == expected assert refcount(myval) == expected
assert m.args_kwargs_function(7, 8, myval, a=1, b=myval) == \ assert m.args_kwargs_function(7, 8, myval, a=1, b=myval) == (
((7, 8, myval), {"a": 1, "b": myval}) (7, 8, myval),
{"a": 1, "b": myval},
)
assert refcount(myval) == expected assert refcount(myval) == expected
exp3 = refcount(myval, myval, myval) exp3 = refcount(myval, myval, myval)
......
...@@ -36,8 +36,8 @@ def test_local_bindings(): ...@@ -36,8 +36,8 @@ def test_local_bindings():
assert i2.get() == 11 assert i2.get() == 11
assert i2.get2() == 12 assert i2.get2() == 12
assert not hasattr(i1, 'get2') assert not hasattr(i1, "get2")
assert not hasattr(i2, 'get3') assert not hasattr(i2, "get3")
# Loading within the local module # Loading within the local module
assert m.local_value(i1) == 5 assert m.local_value(i1) == 5
...@@ -55,7 +55,9 @@ def test_nonlocal_failure(): ...@@ -55,7 +55,9 @@ def test_nonlocal_failure():
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
cm.register_nonlocal() cm.register_nonlocal()
assert str(excinfo.value) == 'generic_type: type "NonLocalType" is already registered!' assert (
str(excinfo.value) == 'generic_type: type "NonLocalType" is already registered!'
)
def test_duplicate_local(): def test_duplicate_local():
...@@ -63,9 +65,12 @@ def test_duplicate_local(): ...@@ -63,9 +65,12 @@ def test_duplicate_local():
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
m.register_local_external() m.register_local_external()
import pybind11_tests import pybind11_tests
assert str(excinfo.value) == ( assert str(excinfo.value) == (
'generic_type: type "LocalExternal" is already registered!' 'generic_type: type "LocalExternal" is already registered!'
if hasattr(pybind11_tests, 'class_') else 'test_class not enabled') if hasattr(pybind11_tests, "class_")
else "test_class not enabled"
)
def test_stl_bind_local(): def test_stl_bind_local():
...@@ -98,8 +103,8 @@ def test_stl_bind_local(): ...@@ -98,8 +103,8 @@ def test_stl_bind_local():
d1["b"] = v1[1] d1["b"] = v1[1]
d2["c"] = v2[0] d2["c"] = v2[0]
d2["d"] = v2[1] d2["d"] = v2[1]
assert {i: d1[i].get() for i in d1} == {'a': 0, 'b': 1} assert {i: d1[i].get() for i in d1} == {"a": 0, "b": 1}
assert {i: d2[i].get() for i in d2} == {'c': 2, 'd': 3} assert {i: d2[i].get() for i in d2} == {"c": 2, "d": 3}
def test_stl_bind_global(): def test_stl_bind_global():
...@@ -107,15 +112,21 @@ def test_stl_bind_global(): ...@@ -107,15 +112,21 @@ def test_stl_bind_global():
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
cm.register_nonlocal_map() cm.register_nonlocal_map()
assert str(excinfo.value) == 'generic_type: type "NonLocalMap" is already registered!' assert (
str(excinfo.value) == 'generic_type: type "NonLocalMap" is already registered!'
)
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
cm.register_nonlocal_vec() cm.register_nonlocal_vec()
assert str(excinfo.value) == 'generic_type: type "NonLocalVec" is already registered!' assert (
str(excinfo.value) == 'generic_type: type "NonLocalVec" is already registered!'
)
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
cm.register_nonlocal_map2() cm.register_nonlocal_map2()
assert str(excinfo.value) == 'generic_type: type "NonLocalMap2" is already registered!' assert (
str(excinfo.value) == 'generic_type: type "NonLocalMap2" is already registered!'
)
def test_mixed_local_global(): def test_mixed_local_global():
...@@ -123,6 +134,7 @@ def test_mixed_local_global(): ...@@ -123,6 +134,7 @@ def test_mixed_local_global():
type can be registered even if the type is already registered globally. With the module, type can be registered even if the type is already registered globally. With the module,
casting will go to the local type; outside the module casting goes to the global type.""" casting will go to the local type; outside the module casting goes to the global type."""
import pybind11_cross_module_tests as cm import pybind11_cross_module_tests as cm
m.register_mixed_global() m.register_mixed_global()
m.register_mixed_local() m.register_mixed_local()
...@@ -145,13 +157,26 @@ def test_mixed_local_global(): ...@@ -145,13 +157,26 @@ def test_mixed_local_global():
a.append(cm.get_mixed_gl(11)) a.append(cm.get_mixed_gl(11))
a.append(cm.get_mixed_lg(12)) a.append(cm.get_mixed_lg(12))
assert [x.get() for x in a] == \ assert [x.get() for x in a] == [
[101, 1002, 103, 1004, 105, 1006, 207, 2008, 109, 1010, 211, 2012] 101,
1002,
103,
1004,
105,
1006,
207,
2008,
109,
1010,
211,
2012,
]
def test_internal_locals_differ(): def test_internal_locals_differ():
"""Makes sure the internal local type map differs across the two modules""" """Makes sure the internal local type map differs across the two modules"""
import pybind11_cross_module_tests as cm import pybind11_cross_module_tests as cm
assert m.local_cpp_types_addr() != cm.local_cpp_types_addr() assert m.local_cpp_types_addr() != cm.local_cpp_types_addr()
...@@ -169,12 +194,15 @@ def test_stl_caster_vs_stl_bind(msg): ...@@ -169,12 +194,15 @@ def test_stl_caster_vs_stl_bind(msg):
assert m.load_vector_via_caster(v2) == 6 assert m.load_vector_via_caster(v2) == 6
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
cm.load_vector_via_binding(v2) == 6 cm.load_vector_via_binding(v2) == 6
assert msg(excinfo.value) == """ assert (
msg(excinfo.value)
== """
load_vector_via_binding(): incompatible function arguments. The following argument types are supported: load_vector_via_binding(): incompatible function arguments. The following argument types are supported:
1. (arg0: pybind11_cross_module_tests.VectorInt) -> int 1. (arg0: pybind11_cross_module_tests.VectorInt) -> int
Invoked with: [1, 2, 3] Invoked with: [1, 2, 3]
""" # noqa: E501 line too long """ # noqa: E501 line too long
)
def test_cross_module_calls(): def test_cross_module_calls():
......
...@@ -40,17 +40,17 @@ def test_methods_and_attributes(): ...@@ -40,17 +40,17 @@ def test_methods_and_attributes():
assert instance1.overloaded(0) == "(int)" assert instance1.overloaded(0) == "(int)"
assert instance1.overloaded(1, 1.0) == "(int, float)" assert instance1.overloaded(1, 1.0) == "(int, float)"
assert instance1.overloaded(2.0, 2) == "(float, int)" assert instance1.overloaded(2.0, 2) == "(float, int)"
assert instance1.overloaded(3, 3) == "(int, int)" assert instance1.overloaded(3, 3) == "(int, int)"
assert instance1.overloaded(4., 4.) == "(float, float)" assert instance1.overloaded(4.0, 4.0) == "(float, float)"
assert instance1.overloaded_const(-3) == "(int) const" assert instance1.overloaded_const(-3) == "(int) const"
assert instance1.overloaded_const(5, 5.0) == "(int, float) const" assert instance1.overloaded_const(5, 5.0) == "(int, float) const"
assert instance1.overloaded_const(6.0, 6) == "(float, int) const" assert instance1.overloaded_const(6.0, 6) == "(float, int) const"
assert instance1.overloaded_const(7, 7) == "(int, int) const" assert instance1.overloaded_const(7, 7) == "(int, int) const"
assert instance1.overloaded_const(8., 8.) == "(float, float) const" assert instance1.overloaded_const(8.0, 8.0) == "(float, float) const"
assert instance1.overloaded_float(1, 1) == "(float, float)" assert instance1.overloaded_float(1, 1) == "(float, float)"
assert instance1.overloaded_float(1, 1.) == "(float, float)" assert instance1.overloaded_float(1, 1.0) == "(float, float)"
assert instance1.overloaded_float(1., 1) == "(float, float)" assert instance1.overloaded_float(1.0, 1) == "(float, float)"
assert instance1.overloaded_float(1., 1.) == "(float, float)" assert instance1.overloaded_float(1.0, 1.0) == "(float, float)"
assert instance1.value == 320 assert instance1.value == 320
instance1.value = 100 instance1.value = 100
...@@ -193,7 +193,10 @@ def test_metaclass_override(): ...@@ -193,7 +193,10 @@ def test_metaclass_override():
assert type(m.MetaclassOverride).__name__ == "type" assert type(m.MetaclassOverride).__name__ == "type"
assert m.MetaclassOverride.readonly == 1 assert m.MetaclassOverride.readonly == 1
assert type(m.MetaclassOverride.__dict__["readonly"]).__name__ == "pybind11_static_property" assert (
type(m.MetaclassOverride.__dict__["readonly"]).__name__
== "pybind11_static_property"
)
# Regular `type` replaces the property instead of calling `__set__()` # Regular `type` replaces the property instead of calling `__set__()`
m.MetaclassOverride.readonly = 2 m.MetaclassOverride.readonly = 2
...@@ -206,22 +209,26 @@ def test_no_mixed_overloads(): ...@@ -206,22 +209,26 @@ def test_no_mixed_overloads():
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
m.ExampleMandA.add_mixed_overloads1() m.ExampleMandA.add_mixed_overloads1()
assert (str(excinfo.value) == assert str(
"overloading a method with both static and instance methods is not supported; " + excinfo.value
("compile in debug mode for more details" if not debug_enabled else ) == "overloading a method with both static and instance methods is not supported; " + (
"error while attempting to bind static method ExampleMandA.overload_mixed1" "compile in debug mode for more details"
"(arg0: float) -> str") if not debug_enabled
) else "error while attempting to bind static method ExampleMandA.overload_mixed1"
"(arg0: float) -> str"
)
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
m.ExampleMandA.add_mixed_overloads2() m.ExampleMandA.add_mixed_overloads2()
assert (str(excinfo.value) == assert str(
"overloading a method with both static and instance methods is not supported; " + excinfo.value
("compile in debug mode for more details" if not debug_enabled else ) == "overloading a method with both static and instance methods is not supported; " + (
"error while attempting to bind instance method ExampleMandA.overload_mixed2" "compile in debug mode for more details"
"(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: int, arg1: int)" if not debug_enabled
" -> str") else "error while attempting to bind instance method ExampleMandA.overload_mixed2"
) "(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: int, arg1: int)"
" -> str"
)
@pytest.mark.parametrize("access", ["ro", "rw", "static_ro", "static_rw"]) @pytest.mark.parametrize("access", ["ro", "rw", "static_ro", "static_rw"])
...@@ -333,8 +340,8 @@ def test_bad_arg_default(msg): ...@@ -333,8 +340,8 @@ def test_bad_arg_default(msg):
assert msg(excinfo.value) == ( assert msg(excinfo.value) == (
"arg(): could not convert default argument 'a: UnregisteredType' in function " "arg(): could not convert default argument 'a: UnregisteredType' in function "
"'should_fail' into a Python object (type not registered yet?)" "'should_fail' into a Python object (type not registered yet?)"
if debug_enabled else if debug_enabled
"arg(): could not convert default argument into a Python object (type not registered " else "arg(): could not convert default argument into a Python object (type not registered "
"yet?). Compile in debug mode for more information." "yet?). Compile in debug mode for more information."
) )
...@@ -343,8 +350,8 @@ def test_bad_arg_default(msg): ...@@ -343,8 +350,8 @@ def test_bad_arg_default(msg):
assert msg(excinfo.value) == ( assert msg(excinfo.value) == (
"arg(): could not convert default argument 'UnregisteredType' in function " "arg(): could not convert default argument 'UnregisteredType' in function "
"'should_fail' into a Python object (type not registered yet?)" "'should_fail' into a Python object (type not registered yet?)"
if debug_enabled else if debug_enabled
"arg(): could not convert default argument into a Python object (type not registered " else "arg(): could not convert default argument into a Python object (type not registered "
"yet?). Compile in debug mode for more information." "yet?). Compile in debug mode for more information."
) )
...@@ -381,12 +388,15 @@ def test_accepts_none(msg): ...@@ -381,12 +388,15 @@ def test_accepts_none(msg):
# The first one still raises because you can't pass None as a lvalue reference arg: # The first one still raises because you can't pass None as a lvalue reference arg:
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
assert m.ok_none1(None) == -1 assert m.ok_none1(None) == -1
assert msg(excinfo.value) == """ assert (
msg(excinfo.value)
== """
ok_none1(): incompatible function arguments. The following argument types are supported: ok_none1(): incompatible function arguments. The following argument types are supported:
1. (arg0: m.methods_and_attributes.NoneTester) -> int 1. (arg0: m.methods_and_attributes.NoneTester) -> int
Invoked with: None Invoked with: None
""" """
)
# The rest take the argument as pointer or holder, and accept None: # The rest take the argument as pointer or holder, and accept None:
assert m.ok_none2(None) == -1 assert m.ok_none2(None) == -1
...@@ -402,13 +412,16 @@ def test_str_issue(msg): ...@@ -402,13 +412,16 @@ def test_str_issue(msg):
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
str(m.StrIssue("no", "such", "constructor")) str(m.StrIssue("no", "such", "constructor"))
assert msg(excinfo.value) == """ assert (
msg(excinfo.value)
== """
__init__(): incompatible constructor arguments. The following argument types are supported: __init__(): incompatible constructor arguments. The following argument types are supported:
1. m.methods_and_attributes.StrIssue(arg0: int) 1. m.methods_and_attributes.StrIssue(arg0: int)
2. m.methods_and_attributes.StrIssue() 2. m.methods_and_attributes.StrIssue()
Invoked with: 'no', 'such', 'constructor' Invoked with: 'no', 'such', 'constructor'
""" """
)
def test_unregistered_base_implementations(): def test_unregistered_base_implementations():
...@@ -441,7 +454,7 @@ def test_ref_qualified(): ...@@ -441,7 +454,7 @@ def test_ref_qualified():
def test_overload_ordering(): def test_overload_ordering():
'Check to see if the normal overload order (first defined) and prepend overload order works' "Check to see if the normal overload order (first defined) and prepend overload order works"
assert m.overload_order("string") == 1 assert m.overload_order("string") == 1
assert m.overload_order(0) == 4 assert m.overload_order(0) == 4
...@@ -449,8 +462,14 @@ def test_overload_ordering(): ...@@ -449,8 +462,14 @@ def test_overload_ordering():
uni_name = type(u"").__name__ uni_name = type(u"").__name__
assert "1. overload_order(arg0: int) -> int" in m.overload_order.__doc__ assert "1. overload_order(arg0: int) -> int" in m.overload_order.__doc__
assert "2. overload_order(arg0: {}) -> int".format(uni_name) in m.overload_order.__doc__ assert (
assert "3. overload_order(arg0: {}) -> int".format(uni_name) in m.overload_order.__doc__ "2. overload_order(arg0: {}) -> int".format(uni_name)
in m.overload_order.__doc__
)
assert (
"3. overload_order(arg0: {}) -> int".format(uni_name)
in m.overload_order.__doc__
)
assert "4. overload_order(arg0: int) -> int" in m.overload_order.__doc__ assert "4. overload_order(arg0: int) -> int" in m.overload_order.__doc__
with pytest.raises(TypeError) as err: with pytest.raises(TypeError) as err:
......
...@@ -6,9 +6,13 @@ from pybind11_tests import ConstructorStats ...@@ -6,9 +6,13 @@ from pybind11_tests import ConstructorStats
def test_nested_modules(): def test_nested_modules():
import pybind11_tests import pybind11_tests
assert pybind11_tests.__name__ == "pybind11_tests" assert pybind11_tests.__name__ == "pybind11_tests"
assert pybind11_tests.modules.__name__ == "pybind11_tests.modules" assert pybind11_tests.modules.__name__ == "pybind11_tests.modules"
assert pybind11_tests.modules.subsubmodule.__name__ == "pybind11_tests.modules.subsubmodule" assert (
pybind11_tests.modules.subsubmodule.__name__
== "pybind11_tests.modules.subsubmodule"
)
assert m.__name__ == "pybind11_tests.modules" assert m.__name__ == "pybind11_tests.modules"
assert ms.__name__ == "pybind11_tests.modules.subsubmodule" assert ms.__name__ == "pybind11_tests.modules.subsubmodule"
...@@ -35,7 +39,7 @@ def test_reference_internal(): ...@@ -35,7 +39,7 @@ def test_reference_internal():
del b del b
assert astats.alive() == 0 assert astats.alive() == 0
assert bstats.alive() == 0 assert bstats.alive() == 0
assert astats.values() == ['1', '2', '42', '43'] assert astats.values() == ["1", "2", "42", "43"]
assert bstats.values() == [] assert bstats.values() == []
assert astats.default_constructions == 0 assert astats.default_constructions == 0
assert bstats.default_constructions == 1 assert bstats.default_constructions == 1
...@@ -54,7 +58,7 @@ def test_importing(): ...@@ -54,7 +58,7 @@ def test_importing():
from collections import OrderedDict from collections import OrderedDict
assert OD is OrderedDict assert OD is OrderedDict
assert str(OD([(1, 'a'), (2, 'b')])) == "OrderedDict([(1, 'a'), (2, 'b')])" assert str(OD([(1, "a"), (2, "b")])) == "OrderedDict([(1, 'a'), (2, 'b')])"
def test_pydoc(): def test_pydoc():
......
...@@ -57,7 +57,6 @@ def test_multiple_inheritance_mix2(): ...@@ -57,7 +57,6 @@ def test_multiple_inheritance_mix2():
@pytest.mark.skipif("env.PYPY and env.PY2") @pytest.mark.skipif("env.PYPY and env.PY2")
@pytest.mark.xfail("env.PYPY and not env.PY2") @pytest.mark.xfail("env.PYPY and not env.PY2")
def test_multiple_inheritance_python(): def test_multiple_inheritance_python():
class MI1(m.Base1, m.Base2): class MI1(m.Base1, m.Base2):
def __init__(self, i, j): def __init__(self, i, j):
m.Base1.__init__(self, i) m.Base1.__init__(self, i)
...@@ -163,7 +162,6 @@ def test_multiple_inheritance_python(): ...@@ -163,7 +162,6 @@ def test_multiple_inheritance_python():
def test_multiple_inheritance_python_many_bases(): def test_multiple_inheritance_python_many_bases():
class MIMany14(m.BaseN1, m.BaseN2, m.BaseN3, m.BaseN4): class MIMany14(m.BaseN1, m.BaseN2, m.BaseN3, m.BaseN4):
def __init__(self): def __init__(self):
m.BaseN1.__init__(self, 1) m.BaseN1.__init__(self, 1)
...@@ -178,8 +176,16 @@ def test_multiple_inheritance_python_many_bases(): ...@@ -178,8 +176,16 @@ def test_multiple_inheritance_python_many_bases():
m.BaseN7.__init__(self, 7) m.BaseN7.__init__(self, 7)
m.BaseN8.__init__(self, 8) m.BaseN8.__init__(self, 8)
class MIMany916(m.BaseN9, m.BaseN10, m.BaseN11, m.BaseN12, m.BaseN13, m.BaseN14, m.BaseN15, class MIMany916(
m.BaseN16): m.BaseN9,
m.BaseN10,
m.BaseN11,
m.BaseN12,
m.BaseN13,
m.BaseN14,
m.BaseN15,
m.BaseN16,
):
def __init__(self): def __init__(self):
m.BaseN9.__init__(self, 9) m.BaseN9.__init__(self, 9)
m.BaseN10.__init__(self, 10) m.BaseN10.__init__(self, 10)
...@@ -225,7 +231,6 @@ def test_multiple_inheritance_python_many_bases(): ...@@ -225,7 +231,6 @@ def test_multiple_inheritance_python_many_bases():
def test_multiple_inheritance_virtbase(): def test_multiple_inheritance_virtbase():
class MITypePy(m.Base12a): class MITypePy(m.Base12a):
def __init__(self, i, j): def __init__(self, i, j):
m.Base12a.__init__(self, i, j) m.Base12a.__init__(self, i, j)
...@@ -238,7 +243,7 @@ def test_multiple_inheritance_virtbase(): ...@@ -238,7 +243,7 @@ def test_multiple_inheritance_virtbase():
def test_mi_static_properties(): def test_mi_static_properties():
"""Mixing bases with and without static properties should be possible """Mixing bases with and without static properties should be possible
and the result should be independent of base definition order""" and the result should be independent of base definition order"""
for d in (m.VanillaStaticMix1(), m.VanillaStaticMix2()): for d in (m.VanillaStaticMix1(), m.VanillaStaticMix2()):
assert d.vanilla() == "Vanilla" assert d.vanilla() == "Vanilla"
......
This diff is collapsed.
...@@ -10,57 +10,71 @@ from pybind11_tests import numpy_dtypes as m ...@@ -10,57 +10,71 @@ from pybind11_tests import numpy_dtypes as m
np = pytest.importorskip("numpy") np = pytest.importorskip("numpy")
@pytest.fixture(scope='module') @pytest.fixture(scope="module")
def simple_dtype(): def simple_dtype():
ld = np.dtype('longdouble') ld = np.dtype("longdouble")
return np.dtype({'names': ['bool_', 'uint_', 'float_', 'ldbl_'], return np.dtype(
'formats': ['?', 'u4', 'f4', 'f{}'.format(ld.itemsize)], {
'offsets': [0, 4, 8, (16 if ld.alignment > 4 else 12)]}) "names": ["bool_", "uint_", "float_", "ldbl_"],
"formats": ["?", "u4", "f4", "f{}".format(ld.itemsize)],
"offsets": [0, 4, 8, (16 if ld.alignment > 4 else 12)],
}
)
@pytest.fixture(scope='module') @pytest.fixture(scope="module")
def packed_dtype(): def packed_dtype():
return np.dtype([('bool_', '?'), ('uint_', 'u4'), ('float_', 'f4'), ('ldbl_', 'g')]) return np.dtype([("bool_", "?"), ("uint_", "u4"), ("float_", "f4"), ("ldbl_", "g")])
def dt_fmt(): def dt_fmt():
from sys import byteorder from sys import byteorder
e = '<' if byteorder == 'little' else '>'
return ("{{'names':['bool_','uint_','float_','ldbl_']," e = "<" if byteorder == "little" else ">"
" 'formats':['?','" + e + "u4','" + e + "f4','" + e + "f{}']," return (
" 'offsets':[0,4,8,{}], 'itemsize':{}}}") "{{'names':['bool_','uint_','float_','ldbl_'],"
" 'formats':['?','" + e + "u4','" + e + "f4','" + e + "f{}'],"
" 'offsets':[0,4,8,{}], 'itemsize':{}}}"
)
def simple_dtype_fmt(): def simple_dtype_fmt():
ld = np.dtype('longdouble') ld = np.dtype("longdouble")
simple_ld_off = 12 + 4 * (ld.alignment > 4) simple_ld_off = 12 + 4 * (ld.alignment > 4)
return dt_fmt().format(ld.itemsize, simple_ld_off, simple_ld_off + ld.itemsize) return dt_fmt().format(ld.itemsize, simple_ld_off, simple_ld_off + ld.itemsize)
def packed_dtype_fmt(): def packed_dtype_fmt():
from sys import byteorder from sys import byteorder
return "[('bool_', '?'), ('uint_', '{e}u4'), ('float_', '{e}f4'), ('ldbl_', '{e}f{}')]".format( return "[('bool_', '?'), ('uint_', '{e}u4'), ('float_', '{e}f4'), ('ldbl_', '{e}f{}')]".format(
np.dtype('longdouble').itemsize, e='<' if byteorder == 'little' else '>') np.dtype("longdouble").itemsize, e="<" if byteorder == "little" else ">"
)
def partial_ld_offset(): def partial_ld_offset():
return 12 + 4 * (np.dtype('uint64').alignment > 4) + 8 + 8 * ( return (
np.dtype('longdouble').alignment > 8) 12
+ 4 * (np.dtype("uint64").alignment > 4)
+ 8
+ 8 * (np.dtype("longdouble").alignment > 8)
)
def partial_dtype_fmt(): def partial_dtype_fmt():
ld = np.dtype('longdouble') ld = np.dtype("longdouble")
partial_ld_off = partial_ld_offset() partial_ld_off = partial_ld_offset()
return dt_fmt().format(ld.itemsize, partial_ld_off, partial_ld_off + ld.itemsize) return dt_fmt().format(ld.itemsize, partial_ld_off, partial_ld_off + ld.itemsize)
def partial_nested_fmt(): def partial_nested_fmt():
ld = np.dtype('longdouble') ld = np.dtype("longdouble")
partial_nested_off = 8 + 8 * (ld.alignment > 8) partial_nested_off = 8 + 8 * (ld.alignment > 8)
partial_ld_off = partial_ld_offset() partial_ld_off = partial_ld_offset()
partial_nested_size = partial_nested_off * 2 + partial_ld_off + ld.itemsize partial_nested_size = partial_nested_off * 2 + partial_ld_off + ld.itemsize
return "{{'names':['a'], 'formats':[{}], 'offsets':[{}], 'itemsize':{}}}".format( return "{{'names':['a'], 'formats':[{}], 'offsets':[{}], 'itemsize':{}}}".format(
partial_dtype_fmt(), partial_nested_off, partial_nested_size) partial_dtype_fmt(), partial_nested_off, partial_nested_size
)
def assert_equal(actual, expected_data, expected_dtype): def assert_equal(actual, expected_data, expected_dtype):
...@@ -70,15 +84,19 @@ def assert_equal(actual, expected_data, expected_dtype): ...@@ -70,15 +84,19 @@ def assert_equal(actual, expected_data, expected_dtype):
def test_format_descriptors(): def test_format_descriptors():
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
m.get_format_unbound() m.get_format_unbound()
assert re.match('^NumPy type info missing for .*UnboundStruct.*$', str(excinfo.value)) assert re.match(
"^NumPy type info missing for .*UnboundStruct.*$", str(excinfo.value)
)
ld = np.dtype('longdouble') ld = np.dtype("longdouble")
ldbl_fmt = ('4x' if ld.alignment > 4 else '') + ld.char ldbl_fmt = ("4x" if ld.alignment > 4 else "") + ld.char
ss_fmt = "^T{?:bool_:3xI:uint_:f:float_:" + ldbl_fmt + ":ldbl_:}" ss_fmt = "^T{?:bool_:3xI:uint_:f:float_:" + ldbl_fmt + ":ldbl_:}"
dbl = np.dtype('double') dbl = np.dtype("double")
partial_fmt = ("^T{?:bool_:3xI:uint_:f:float_:" + partial_fmt = (
str(4 * (dbl.alignment > 4) + dbl.itemsize + 8 * (ld.alignment > 8)) + "^T{?:bool_:3xI:uint_:f:float_:"
"xg:ldbl_:}") + str(4 * (dbl.alignment > 4) + dbl.itemsize + 8 * (ld.alignment > 8))
+ "xg:ldbl_:}"
)
nested_extra = str(max(8, ld.alignment)) nested_extra = str(max(8, ld.alignment))
assert m.print_format_descriptors() == [ assert m.print_format_descriptors() == [
ss_fmt, ss_fmt,
...@@ -88,14 +106,15 @@ def test_format_descriptors(): ...@@ -88,14 +106,15 @@ def test_format_descriptors():
"^T{" + nested_extra + "x" + partial_fmt + ":a:" + nested_extra + "x}", "^T{" + nested_extra + "x" + partial_fmt + ":a:" + nested_extra + "x}",
"^T{3s:a:3s:b:}", "^T{3s:a:3s:b:}",
"^T{(3)4s:a:(2)i:b:(3)B:c:1x(4, 2)f:d:}", "^T{(3)4s:a:(2)i:b:(3)B:c:1x(4, 2)f:d:}",
'^T{q:e1:B:e2:}', "^T{q:e1:B:e2:}",
'^T{Zf:cflt:Zd:cdbl:}' "^T{Zf:cflt:Zd:cdbl:}",
] ]
def test_dtype(simple_dtype): def test_dtype(simple_dtype):
from sys import byteorder from sys import byteorder
e = '<' if byteorder == 'little' else '>'
e = "<" if byteorder == "little" else ">"
assert m.print_dtypes() == [ assert m.print_dtypes() == [
simple_dtype_fmt(), simple_dtype_fmt(),
...@@ -104,30 +123,60 @@ def test_dtype(simple_dtype): ...@@ -104,30 +123,60 @@ def test_dtype(simple_dtype):
partial_dtype_fmt(), partial_dtype_fmt(),
partial_nested_fmt(), partial_nested_fmt(),
"[('a', 'S3'), ('b', 'S3')]", "[('a', 'S3'), ('b', 'S3')]",
("{{'names':['a','b','c','d'], " + (
"'formats':[('S4', (3,)),('" + e + "i4', (2,)),('u1', (3,)),('" + e + "f4', (4, 2))], " + "{{'names':['a','b','c','d'], "
"'offsets':[0,12,20,24], 'itemsize':56}}").format(e=e), + "'formats':[('S4', (3,)),('"
+ e
+ "i4', (2,)),('u1', (3,)),('"
+ e
+ "f4', (4, 2))], "
+ "'offsets':[0,12,20,24], 'itemsize':56}}"
).format(e=e),
"[('e1', '" + e + "i8'), ('e2', 'u1')]", "[('e1', '" + e + "i8'), ('e2', 'u1')]",
"[('x', 'i1'), ('y', '" + e + "u8')]", "[('x', 'i1'), ('y', '" + e + "u8')]",
"[('cflt', '" + e + "c8'), ('cdbl', '" + e + "c16')]" "[('cflt', '" + e + "c8'), ('cdbl', '" + e + "c16')]",
] ]
d1 = np.dtype({'names': ['a', 'b'], 'formats': ['int32', 'float64'], d1 = np.dtype(
'offsets': [1, 10], 'itemsize': 20}) {
d2 = np.dtype([('a', 'i4'), ('b', 'f4')]) "names": ["a", "b"],
assert m.test_dtype_ctors() == [np.dtype('int32'), np.dtype('float64'), "formats": ["int32", "float64"],
np.dtype('bool'), d1, d1, np.dtype('uint32'), d2] "offsets": [1, 10],
"itemsize": 20,
}
)
d2 = np.dtype([("a", "i4"), ("b", "f4")])
assert m.test_dtype_ctors() == [
np.dtype("int32"),
np.dtype("float64"),
np.dtype("bool"),
d1,
d1,
np.dtype("uint32"),
d2,
]
assert m.test_dtype_methods() == [np.dtype('int32'), simple_dtype, False, True, assert m.test_dtype_methods() == [
np.dtype('int32').itemsize, simple_dtype.itemsize] np.dtype("int32"),
simple_dtype,
False,
True,
np.dtype("int32").itemsize,
simple_dtype.itemsize,
]
assert m.trailing_padding_dtype() == m.buffer_to_dtype(np.zeros(1, m.trailing_padding_dtype())) assert m.trailing_padding_dtype() == m.buffer_to_dtype(
np.zeros(1, m.trailing_padding_dtype())
)
def test_recarray(simple_dtype, packed_dtype): def test_recarray(simple_dtype, packed_dtype):
elements = [(False, 0, 0.0, -0.0), (True, 1, 1.5, -2.5), (False, 2, 3.0, -5.0)] elements = [(False, 0, 0.0, -0.0), (True, 1, 1.5, -2.5), (False, 2, 3.0, -5.0)]
for func, dtype in [(m.create_rec_simple, simple_dtype), (m.create_rec_packed, packed_dtype)]: for func, dtype in [
(m.create_rec_simple, simple_dtype),
(m.create_rec_packed, packed_dtype),
]:
arr = func(0) arr = func(0)
assert arr.dtype == dtype assert arr.dtype == dtype
assert_equal(arr, [], simple_dtype) assert_equal(arr, [], simple_dtype)
...@@ -146,16 +195,16 @@ def test_recarray(simple_dtype, packed_dtype): ...@@ -146,16 +195,16 @@ def test_recarray(simple_dtype, packed_dtype):
assert m.print_rec_simple(arr) == [ assert m.print_rec_simple(arr) == [
"s:0,0,0,-0", "s:0,0,0,-0",
"s:1,1,1.5,-2.5", "s:1,1,1.5,-2.5",
"s:0,2,3,-5" "s:0,2,3,-5",
] ]
else: else:
assert m.print_rec_packed(arr) == [ assert m.print_rec_packed(arr) == [
"p:0,0,0,-0", "p:0,0,0,-0",
"p:1,1,1.5,-2.5", "p:1,1,1.5,-2.5",
"p:0,2,3,-5" "p:0,2,3,-5",
] ]
nested_dtype = np.dtype([('a', simple_dtype), ('b', packed_dtype)]) nested_dtype = np.dtype([("a", simple_dtype), ("b", packed_dtype)])
arr = m.create_rec_nested(0) arr = m.create_rec_nested(0)
assert arr.dtype == nested_dtype assert arr.dtype == nested_dtype
...@@ -163,33 +212,39 @@ def test_recarray(simple_dtype, packed_dtype): ...@@ -163,33 +212,39 @@ def test_recarray(simple_dtype, packed_dtype):
arr = m.create_rec_nested(3) arr = m.create_rec_nested(3)
assert arr.dtype == nested_dtype assert arr.dtype == nested_dtype
assert_equal(arr, [((False, 0, 0.0, -0.0), (True, 1, 1.5, -2.5)), assert_equal(
((True, 1, 1.5, -2.5), (False, 2, 3.0, -5.0)), arr,
((False, 2, 3.0, -5.0), (True, 3, 4.5, -7.5))], nested_dtype) [
((False, 0, 0.0, -0.0), (True, 1, 1.5, -2.5)),
((True, 1, 1.5, -2.5), (False, 2, 3.0, -5.0)),
((False, 2, 3.0, -5.0), (True, 3, 4.5, -7.5)),
],
nested_dtype,
)
assert m.print_rec_nested(arr) == [ assert m.print_rec_nested(arr) == [
"n:a=s:0,0,0,-0;b=p:1,1,1.5,-2.5", "n:a=s:0,0,0,-0;b=p:1,1,1.5,-2.5",
"n:a=s:1,1,1.5,-2.5;b=p:0,2,3,-5", "n:a=s:1,1,1.5,-2.5;b=p:0,2,3,-5",
"n:a=s:0,2,3,-5;b=p:1,3,4.5,-7.5" "n:a=s:0,2,3,-5;b=p:1,3,4.5,-7.5",
] ]
arr = m.create_rec_partial(3) arr = m.create_rec_partial(3)
assert str(arr.dtype) == partial_dtype_fmt() assert str(arr.dtype) == partial_dtype_fmt()
partial_dtype = arr.dtype partial_dtype = arr.dtype
assert '' not in arr.dtype.fields assert "" not in arr.dtype.fields
assert partial_dtype.itemsize > simple_dtype.itemsize assert partial_dtype.itemsize > simple_dtype.itemsize
assert_equal(arr, elements, simple_dtype) assert_equal(arr, elements, simple_dtype)
assert_equal(arr, elements, packed_dtype) assert_equal(arr, elements, packed_dtype)
arr = m.create_rec_partial_nested(3) arr = m.create_rec_partial_nested(3)
assert str(arr.dtype) == partial_nested_fmt() assert str(arr.dtype) == partial_nested_fmt()
assert '' not in arr.dtype.fields assert "" not in arr.dtype.fields
assert '' not in arr.dtype.fields['a'][0].fields assert "" not in arr.dtype.fields["a"][0].fields
assert arr.dtype.itemsize > partial_dtype.itemsize assert arr.dtype.itemsize > partial_dtype.itemsize
np.testing.assert_equal(arr['a'], m.create_rec_partial(3)) np.testing.assert_equal(arr["a"], m.create_rec_partial(3))
def test_array_constructors(): def test_array_constructors():
data = np.arange(1, 7, dtype='int32') data = np.arange(1, 7, dtype="int32")
for i in range(8): for i in range(8):
np.testing.assert_array_equal(m.test_array_ctors(10 + i), data.reshape((3, 2))) np.testing.assert_array_equal(m.test_array_ctors(10 + i), data.reshape((3, 2)))
np.testing.assert_array_equal(m.test_array_ctors(20 + i), data.reshape((3, 2))) np.testing.assert_array_equal(m.test_array_ctors(20 + i), data.reshape((3, 2)))
...@@ -205,82 +260,92 @@ def test_string_array(): ...@@ -205,82 +260,92 @@ def test_string_array():
"a='',b=''", "a='',b=''",
"a='a',b='a'", "a='a',b='a'",
"a='ab',b='ab'", "a='ab',b='ab'",
"a='abc',b='abc'" "a='abc',b='abc'",
] ]
dtype = arr.dtype dtype = arr.dtype
assert arr['a'].tolist() == [b'', b'a', b'ab', b'abc'] assert arr["a"].tolist() == [b"", b"a", b"ab", b"abc"]
assert arr['b'].tolist() == [b'', b'a', b'ab', b'abc'] assert arr["b"].tolist() == [b"", b"a", b"ab", b"abc"]
arr = m.create_string_array(False) arr = m.create_string_array(False)
assert dtype == arr.dtype assert dtype == arr.dtype
def test_array_array(): def test_array_array():
from sys import byteorder from sys import byteorder
e = '<' if byteorder == 'little' else '>'
e = "<" if byteorder == "little" else ">"
arr = m.create_array_array(3) arr = m.create_array_array(3)
assert str(arr.dtype) == ( assert str(arr.dtype) == (
"{{'names':['a','b','c','d'], " + "{{'names':['a','b','c','d'], "
"'formats':[('S4', (3,)),('" + e + "i4', (2,)),('u1', (3,)),('{e}f4', (4, 2))], " + + "'formats':[('S4', (3,)),('"
"'offsets':[0,12,20,24], 'itemsize':56}}").format(e=e) + e
+ "i4', (2,)),('u1', (3,)),('{e}f4', (4, 2))], "
+ "'offsets':[0,12,20,24], 'itemsize':56}}"
).format(e=e)
assert m.print_array_array(arr) == [ assert m.print_array_array(arr) == [
"a={{A,B,C,D},{K,L,M,N},{U,V,W,X}},b={0,1}," + "a={{A,B,C,D},{K,L,M,N},{U,V,W,X}},b={0,1},"
"c={0,1,2},d={{0,1},{10,11},{20,21},{30,31}}", + "c={0,1,2},d={{0,1},{10,11},{20,21},{30,31}}",
"a={{W,X,Y,Z},{G,H,I,J},{Q,R,S,T}},b={1000,1001}," + "a={{W,X,Y,Z},{G,H,I,J},{Q,R,S,T}},b={1000,1001},"
"c={10,11,12},d={{100,101},{110,111},{120,121},{130,131}}", + "c={10,11,12},d={{100,101},{110,111},{120,121},{130,131}}",
"a={{S,T,U,V},{C,D,E,F},{M,N,O,P}},b={2000,2001}," + "a={{S,T,U,V},{C,D,E,F},{M,N,O,P}},b={2000,2001},"
"c={20,21,22},d={{200,201},{210,211},{220,221},{230,231}}", + "c={20,21,22},d={{200,201},{210,211},{220,221},{230,231}}",
] ]
assert arr['a'].tolist() == [[b'ABCD', b'KLMN', b'UVWX'], assert arr["a"].tolist() == [
[b'WXYZ', b'GHIJ', b'QRST'], [b"ABCD", b"KLMN", b"UVWX"],
[b'STUV', b'CDEF', b'MNOP']] [b"WXYZ", b"GHIJ", b"QRST"],
assert arr['b'].tolist() == [[0, 1], [1000, 1001], [2000, 2001]] [b"STUV", b"CDEF", b"MNOP"],
]
assert arr["b"].tolist() == [[0, 1], [1000, 1001], [2000, 2001]]
assert m.create_array_array(0).dtype == arr.dtype assert m.create_array_array(0).dtype == arr.dtype
def test_enum_array(): def test_enum_array():
from sys import byteorder from sys import byteorder
e = '<' if byteorder == 'little' else '>'
e = "<" if byteorder == "little" else ">"
arr = m.create_enum_array(3) arr = m.create_enum_array(3)
dtype = arr.dtype dtype = arr.dtype
assert dtype == np.dtype([('e1', e + 'i8'), ('e2', 'u1')]) assert dtype == np.dtype([("e1", e + "i8"), ("e2", "u1")])
assert m.print_enum_array(arr) == [ assert m.print_enum_array(arr) == ["e1=A,e2=X", "e1=B,e2=Y", "e1=A,e2=X"]
"e1=A,e2=X", assert arr["e1"].tolist() == [-1, 1, -1]
"e1=B,e2=Y", assert arr["e2"].tolist() == [1, 2, 1]
"e1=A,e2=X"
]
assert arr['e1'].tolist() == [-1, 1, -1]
assert arr['e2'].tolist() == [1, 2, 1]
assert m.create_enum_array(0).dtype == dtype assert m.create_enum_array(0).dtype == dtype
def test_complex_array(): def test_complex_array():
from sys import byteorder from sys import byteorder
e = '<' if byteorder == 'little' else '>'
e = "<" if byteorder == "little" else ">"
arr = m.create_complex_array(3) arr = m.create_complex_array(3)
dtype = arr.dtype dtype = arr.dtype
assert dtype == np.dtype([('cflt', e + 'c8'), ('cdbl', e + 'c16')]) assert dtype == np.dtype([("cflt", e + "c8"), ("cdbl", e + "c16")])
assert m.print_complex_array(arr) == [ assert m.print_complex_array(arr) == [
"c:(0,0.25),(0.5,0.75)", "c:(0,0.25),(0.5,0.75)",
"c:(1,1.25),(1.5,1.75)", "c:(1,1.25),(1.5,1.75)",
"c:(2,2.25),(2.5,2.75)" "c:(2,2.25),(2.5,2.75)",
] ]
assert arr['cflt'].tolist() == [0.0 + 0.25j, 1.0 + 1.25j, 2.0 + 2.25j] assert arr["cflt"].tolist() == [0.0 + 0.25j, 1.0 + 1.25j, 2.0 + 2.25j]
assert arr['cdbl'].tolist() == [0.5 + 0.75j, 1.5 + 1.75j, 2.5 + 2.75j] assert arr["cdbl"].tolist() == [0.5 + 0.75j, 1.5 + 1.75j, 2.5 + 2.75j]
assert m.create_complex_array(0).dtype == dtype assert m.create_complex_array(0).dtype == dtype
def test_signature(doc): def test_signature(doc):
assert doc(m.create_rec_nested) == \ assert (
"create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]" doc(m.create_rec_nested)
== "create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]"
)
def test_scalar_conversion(): def test_scalar_conversion():
n = 3 n = 3
arrays = [m.create_rec_simple(n), m.create_rec_packed(n), arrays = [
m.create_rec_nested(n), m.create_enum_array(n)] m.create_rec_simple(n),
m.create_rec_packed(n),
m.create_rec_nested(n),
m.create_enum_array(n),
]
funcs = [m.f_simple, m.f_packed, m.f_nested] funcs = [m.f_simple, m.f_packed, m.f_nested]
for i, func in enumerate(funcs): for i, func in enumerate(funcs):
...@@ -290,7 +355,7 @@ def test_scalar_conversion(): ...@@ -290,7 +355,7 @@ def test_scalar_conversion():
else: else:
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
func(arr[0]) func(arr[0])
assert 'incompatible function arguments' in str(excinfo.value) assert "incompatible function arguments" in str(excinfo.value)
def test_vectorize(): def test_vectorize():
...@@ -304,14 +369,14 @@ def test_vectorize(): ...@@ -304,14 +369,14 @@ def test_vectorize():
def test_cls_and_dtype_conversion(simple_dtype): def test_cls_and_dtype_conversion(simple_dtype):
s = m.SimpleStruct() s = m.SimpleStruct()
assert s.astuple() == (False, 0, 0., 0.) assert s.astuple() == (False, 0, 0.0, 0.0)
assert m.SimpleStruct.fromtuple(s.astuple()).astuple() == s.astuple() assert m.SimpleStruct.fromtuple(s.astuple()).astuple() == s.astuple()
s.uint_ = 2 s.uint_ = 2
assert m.f_simple(s) == 20 assert m.f_simple(s) == 20
# Try as recarray of shape==(1,). # Try as recarray of shape==(1,).
s_recarray = np.array([(False, 2, 0., 0.)], dtype=simple_dtype) s_recarray = np.array([(False, 2, 0.0, 0.0)], dtype=simple_dtype)
# Show that this will work for vectorized case. # Show that this will work for vectorized case.
np.testing.assert_array_equal(m.f_simple_vectorized(s_recarray), [20]) np.testing.assert_array_equal(m.f_simple_vectorized(s_recarray), [20])
...@@ -327,17 +392,16 @@ def test_cls_and_dtype_conversion(simple_dtype): ...@@ -327,17 +392,16 @@ def test_cls_and_dtype_conversion(simple_dtype):
assert s_recarray_scalar.dtype == simple_dtype assert s_recarray_scalar.dtype == simple_dtype
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
m.f_simple(s_recarray_scalar) m.f_simple(s_recarray_scalar)
assert 'incompatible function arguments' in str(excinfo.value) assert "incompatible function arguments" in str(excinfo.value)
# Explicitly convert to m.SimpleStruct. # Explicitly convert to m.SimpleStruct.
assert m.f_simple( assert m.f_simple(m.SimpleStruct.fromtuple(s_recarray_scalar.item())) == 20
m.SimpleStruct.fromtuple(s_recarray_scalar.item())) == 20
# Show that an array of dtype=object does *not* convert. # Show that an array of dtype=object does *not* convert.
s_array_object = np.array([s]) s_array_object = np.array([s])
assert s_array_object.dtype == object assert s_array_object.dtype == object
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
m.f_simple_vectorized(s_array_object) m.f_simple_vectorized(s_array_object)
assert 'incompatible function arguments' in str(excinfo.value) assert "incompatible function arguments" in str(excinfo.value)
# Explicitly convert to `np.array(..., dtype=simple_dtype)` # Explicitly convert to `np.array(..., dtype=simple_dtype)`
s_array = np.array([s.astuple()], dtype=simple_dtype) s_array = np.array([s.astuple()], dtype=simple_dtype)
np.testing.assert_array_equal(m.f_simple_vectorized(s_array), [20]) np.testing.assert_array_equal(m.f_simple_vectorized(s_array), [20])
...@@ -346,12 +410,13 @@ def test_cls_and_dtype_conversion(simple_dtype): ...@@ -346,12 +410,13 @@ def test_cls_and_dtype_conversion(simple_dtype):
def test_register_dtype(): def test_register_dtype():
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
m.register_dtype() m.register_dtype()
assert 'dtype is already registered' in str(excinfo.value) assert "dtype is already registered" in str(excinfo.value)
@pytest.mark.xfail("env.PYPY") @pytest.mark.xfail("env.PYPY")
def test_str_leak(): def test_str_leak():
from sys import getrefcount from sys import getrefcount
fmt = "f4" fmt = "f4"
pytest.gc_collect() pytest.gc_collect()
start = getrefcount(fmt) start = getrefcount(fmt)
......
...@@ -17,28 +17,40 @@ def test_vectorize(capture): ...@@ -17,28 +17,40 @@ def test_vectorize(capture):
assert capture == "my_func(x:int=1, y:float=2, z:float=3)" assert capture == "my_func(x:int=1, y:float=2, z:float=3)"
with capture: with capture:
assert np.allclose(f(np.array([1, 3]), np.array([2, 4]), 3), [6, 36]) assert np.allclose(f(np.array([1, 3]), np.array([2, 4]), 3), [6, 36])
assert capture == """ assert (
capture
== """
my_func(x:int=1, y:float=2, z:float=3) my_func(x:int=1, y:float=2, z:float=3)
my_func(x:int=3, y:float=4, z:float=3) my_func(x:int=3, y:float=4, z:float=3)
""" """
)
with capture: with capture:
a = np.array([[1, 2], [3, 4]], order='F') a = np.array([[1, 2], [3, 4]], order="F")
b = np.array([[10, 20], [30, 40]], order='F') b = np.array([[10, 20], [30, 40]], order="F")
c = 3 c = 3
result = f(a, b, c) result = f(a, b, c)
assert np.allclose(result, a * b * c) assert np.allclose(result, a * b * c)
assert result.flags.f_contiguous assert result.flags.f_contiguous
# All inputs are F order and full or singletons, so we the result is in col-major order: # All inputs are F order and full or singletons, so we the result is in col-major order:
assert capture == """ assert (
capture
== """
my_func(x:int=1, y:float=10, z:float=3) my_func(x:int=1, y:float=10, z:float=3)
my_func(x:int=3, y:float=30, z:float=3) my_func(x:int=3, y:float=30, z:float=3)
my_func(x:int=2, y:float=20, z:float=3) my_func(x:int=2, y:float=20, z:float=3)
my_func(x:int=4, y:float=40, z:float=3) my_func(x:int=4, y:float=40, z:float=3)
""" """
)
with capture: with capture:
a, b, c = np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3 a, b, c = (
np.array([[1, 3, 5], [7, 9, 11]]),
np.array([[2, 4, 6], [8, 10, 12]]),
3,
)
assert np.allclose(f(a, b, c), a * b * c) assert np.allclose(f(a, b, c), a * b * c)
assert capture == """ assert (
capture
== """
my_func(x:int=1, y:float=2, z:float=3) my_func(x:int=1, y:float=2, z:float=3)
my_func(x:int=3, y:float=4, z:float=3) my_func(x:int=3, y:float=4, z:float=3)
my_func(x:int=5, y:float=6, z:float=3) my_func(x:int=5, y:float=6, z:float=3)
...@@ -46,10 +58,13 @@ def test_vectorize(capture): ...@@ -46,10 +58,13 @@ def test_vectorize(capture):
my_func(x:int=9, y:float=10, z:float=3) my_func(x:int=9, y:float=10, z:float=3)
my_func(x:int=11, y:float=12, z:float=3) my_func(x:int=11, y:float=12, z:float=3)
""" """
)
with capture: with capture:
a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2 a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2
assert np.allclose(f(a, b, c), a * b * c) assert np.allclose(f(a, b, c), a * b * c)
assert capture == """ assert (
capture
== """
my_func(x:int=1, y:float=2, z:float=2) my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=2, y:float=3, z:float=2) my_func(x:int=2, y:float=3, z:float=2)
my_func(x:int=3, y:float=4, z:float=2) my_func(x:int=3, y:float=4, z:float=2)
...@@ -57,10 +72,13 @@ def test_vectorize(capture): ...@@ -57,10 +72,13 @@ def test_vectorize(capture):
my_func(x:int=5, y:float=3, z:float=2) my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=6, y:float=4, z:float=2) my_func(x:int=6, y:float=4, z:float=2)
""" """
)
with capture: with capture:
a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2 a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2
assert np.allclose(f(a, b, c), a * b * c) assert np.allclose(f(a, b, c), a * b * c)
assert capture == """ assert (
capture
== """
my_func(x:int=1, y:float=2, z:float=2) my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=2, y:float=2, z:float=2) my_func(x:int=2, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2) my_func(x:int=3, y:float=2, z:float=2)
...@@ -68,10 +86,17 @@ def test_vectorize(capture): ...@@ -68,10 +86,17 @@ def test_vectorize(capture):
my_func(x:int=5, y:float=3, z:float=2) my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2) my_func(x:int=6, y:float=3, z:float=2)
""" """
)
with capture: with capture:
a, b, c = np.array([[1, 2, 3], [4, 5, 6]], order='F'), np.array([[2], [3]]), 2 a, b, c = (
np.array([[1, 2, 3], [4, 5, 6]], order="F"),
np.array([[2], [3]]),
2,
)
assert np.allclose(f(a, b, c), a * b * c) assert np.allclose(f(a, b, c), a * b * c)
assert capture == """ assert (
capture
== """
my_func(x:int=1, y:float=2, z:float=2) my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=2, y:float=2, z:float=2) my_func(x:int=2, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2) my_func(x:int=3, y:float=2, z:float=2)
...@@ -79,36 +104,53 @@ def test_vectorize(capture): ...@@ -79,36 +104,53 @@ def test_vectorize(capture):
my_func(x:int=5, y:float=3, z:float=2) my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2) my_func(x:int=6, y:float=3, z:float=2)
""" """
)
with capture: with capture:
a, b, c = np.array([[1, 2, 3], [4, 5, 6]])[::, ::2], np.array([[2], [3]]), 2 a, b, c = np.array([[1, 2, 3], [4, 5, 6]])[::, ::2], np.array([[2], [3]]), 2
assert np.allclose(f(a, b, c), a * b * c) assert np.allclose(f(a, b, c), a * b * c)
assert capture == """ assert (
capture
== """
my_func(x:int=1, y:float=2, z:float=2) my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2) my_func(x:int=3, y:float=2, z:float=2)
my_func(x:int=4, y:float=3, z:float=2) my_func(x:int=4, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2) my_func(x:int=6, y:float=3, z:float=2)
""" """
)
with capture: with capture:
a, b, c = np.array([[1, 2, 3], [4, 5, 6]], order='F')[::, ::2], np.array([[2], [3]]), 2 a, b, c = (
np.array([[1, 2, 3], [4, 5, 6]], order="F")[::, ::2],
np.array([[2], [3]]),
2,
)
assert np.allclose(f(a, b, c), a * b * c) assert np.allclose(f(a, b, c), a * b * c)
assert capture == """ assert (
capture
== """
my_func(x:int=1, y:float=2, z:float=2) my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2) my_func(x:int=3, y:float=2, z:float=2)
my_func(x:int=4, y:float=3, z:float=2) my_func(x:int=4, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2) my_func(x:int=6, y:float=3, z:float=2)
""" """
)
def test_type_selection(): def test_type_selection():
assert m.selective_func(np.array([1], dtype=np.int32)) == "Int branch taken." assert m.selective_func(np.array([1], dtype=np.int32)) == "Int branch taken."
assert m.selective_func(np.array([1.0], dtype=np.float32)) == "Float branch taken." assert m.selective_func(np.array([1.0], dtype=np.float32)) == "Float branch taken."
assert m.selective_func(np.array([1.0j], dtype=np.complex64)) == "Complex float branch taken." assert (
m.selective_func(np.array([1.0j], dtype=np.complex64))
== "Complex float branch taken."
)
def test_docs(doc): def test_docs(doc):
assert doc(m.vectorized_func) == """ assert (
doc(m.vectorized_func)
== """
vectorized_func(arg0: numpy.ndarray[numpy.int32], arg1: numpy.ndarray[numpy.float32], arg2: numpy.ndarray[numpy.float64]) -> object vectorized_func(arg0: numpy.ndarray[numpy.int32], arg1: numpy.ndarray[numpy.float32], arg2: numpy.ndarray[numpy.float64]) -> object
""" # noqa: E501 line too long """ # noqa: E501 line too long
)
def test_trivial_broadcasting(): def test_trivial_broadcasting():
...@@ -116,16 +158,24 @@ def test_trivial_broadcasting(): ...@@ -116,16 +158,24 @@ def test_trivial_broadcasting():
assert vectorized_is_trivial(1, 2, 3) == trivial.c_trivial assert vectorized_is_trivial(1, 2, 3) == trivial.c_trivial
assert vectorized_is_trivial(np.array(1), np.array(2), 3) == trivial.c_trivial assert vectorized_is_trivial(np.array(1), np.array(2), 3) == trivial.c_trivial
assert vectorized_is_trivial(np.array([1, 3]), np.array([2, 4]), 3) == trivial.c_trivial assert (
vectorized_is_trivial(np.array([1, 3]), np.array([2, 4]), 3)
== trivial.c_trivial
)
assert trivial.c_trivial == vectorized_is_trivial( assert trivial.c_trivial == vectorized_is_trivial(
np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3) np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3
assert vectorized_is_trivial( )
np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2) == trivial.non_trivial assert (
assert vectorized_is_trivial( vectorized_is_trivial(np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2)
np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2) == trivial.non_trivial == trivial.non_trivial
z1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]], dtype='int32') )
z2 = np.array(z1, dtype='float32') assert (
z3 = np.array(z1, dtype='float64') vectorized_is_trivial(np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2)
== trivial.non_trivial
)
z1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]], dtype="int32")
z2 = np.array(z1, dtype="float32")
z3 = np.array(z1, dtype="float64")
assert vectorized_is_trivial(z1, z2, z3) == trivial.c_trivial assert vectorized_is_trivial(z1, z2, z3) == trivial.c_trivial
assert vectorized_is_trivial(1, z2, z3) == trivial.c_trivial assert vectorized_is_trivial(1, z2, z3) == trivial.c_trivial
assert vectorized_is_trivial(z1, 1, z3) == trivial.c_trivial assert vectorized_is_trivial(z1, 1, z3) == trivial.c_trivial
...@@ -135,7 +185,7 @@ def test_trivial_broadcasting(): ...@@ -135,7 +185,7 @@ def test_trivial_broadcasting():
assert vectorized_is_trivial(1, 1, z3[::2, ::2]) == trivial.non_trivial assert vectorized_is_trivial(1, 1, z3[::2, ::2]) == trivial.non_trivial
assert vectorized_is_trivial(z1, 1, z3[1::4, 1::4]) == trivial.c_trivial assert vectorized_is_trivial(z1, 1, z3[1::4, 1::4]) == trivial.c_trivial
y1 = np.array(z1, order='F') y1 = np.array(z1, order="F")
y2 = np.array(y1) y2 = np.array(y1)
y3 = np.array(y1) y3 = np.array(y1)
assert vectorized_is_trivial(y1, y2, y3) == trivial.f_trivial assert vectorized_is_trivial(y1, y2, y3) == trivial.f_trivial
...@@ -156,30 +206,41 @@ def test_trivial_broadcasting(): ...@@ -156,30 +206,41 @@ def test_trivial_broadcasting():
def test_passthrough_arguments(doc): def test_passthrough_arguments(doc):
assert doc(m.vec_passthrough) == ( assert doc(m.vec_passthrough) == (
"vec_passthrough(" + ", ".join([ "vec_passthrough("
"arg0: float", + ", ".join(
"arg1: numpy.ndarray[numpy.float64]", [
"arg2: numpy.ndarray[numpy.float64]", "arg0: float",
"arg3: numpy.ndarray[numpy.int32]", "arg1: numpy.ndarray[numpy.float64]",
"arg4: int", "arg2: numpy.ndarray[numpy.float64]",
"arg5: m.numpy_vectorize.NonPODClass", "arg3: numpy.ndarray[numpy.int32]",
"arg6: numpy.ndarray[numpy.float64]"]) + ") -> object") "arg4: int",
"arg5: m.numpy_vectorize.NonPODClass",
b = np.array([[10, 20, 30]], dtype='float64') "arg6: numpy.ndarray[numpy.float64]",
]
)
+ ") -> object"
)
b = np.array([[10, 20, 30]], dtype="float64")
c = np.array([100, 200]) # NOT a vectorized argument c = np.array([100, 200]) # NOT a vectorized argument
d = np.array([[1000], [2000], [3000]], dtype='int') d = np.array([[1000], [2000], [3000]], dtype="int")
g = np.array([[1000000, 2000000, 3000000]], dtype='int') # requires casting g = np.array([[1000000, 2000000, 3000000]], dtype="int") # requires casting
assert np.all( assert np.all(
m.vec_passthrough(1, b, c, d, 10000, m.NonPODClass(100000), g) == m.vec_passthrough(1, b, c, d, 10000, m.NonPODClass(100000), g)
np.array([[1111111, 2111121, 3111131], == np.array(
[1112111, 2112121, 3112131], [
[1113111, 2113121, 3113131]])) [1111111, 2111121, 3111131],
[1112111, 2112121, 3112131],
[1113111, 2113121, 3113131],
]
)
)
def test_method_vectorization(): def test_method_vectorization():
o = m.VectorizeTestClass(3) o = m.VectorizeTestClass(3)
x = np.array([1, 2], dtype='int') x = np.array([1, 2], dtype="int")
y = np.array([[10], [20]], dtype='float32') y = np.array([[10], [20]], dtype="float32")
assert np.all(o.method(x, y) == [[14, 15], [24, 25]]) assert np.all(o.method(x, y) == [[14, 15], [24, 25]])
...@@ -188,7 +249,7 @@ def test_array_collapse(): ...@@ -188,7 +249,7 @@ def test_array_collapse():
assert not isinstance(m.vectorized_func(np.array(1), 2, 3), np.ndarray) assert not isinstance(m.vectorized_func(np.array(1), 2, 3), np.ndarray)
z = m.vectorized_func([1], 2, 3) z = m.vectorized_func([1], 2, 3)
assert isinstance(z, np.ndarray) assert isinstance(z, np.ndarray)
assert z.shape == (1, ) assert z.shape == (1,)
z = m.vectorized_func(1, [[[2]]], 3) z = m.vectorized_func(1, [[[2]]], 3)
assert isinstance(z, np.ndarray) assert isinstance(z, np.ndarray)
assert z.shape == (1, 1, 1) assert z.shape == (1, 1, 1)
......
...@@ -32,12 +32,15 @@ def test_pointers(msg): ...@@ -32,12 +32,15 @@ def test_pointers(msg):
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
m.get_void_ptr_value([1, 2, 3]) # This should not work m.get_void_ptr_value([1, 2, 3]) # This should not work
assert msg(excinfo.value) == """ assert (
msg(excinfo.value)
== """
get_void_ptr_value(): incompatible function arguments. The following argument types are supported: get_void_ptr_value(): incompatible function arguments. The following argument types are supported:
1. (arg0: capsule) -> int 1. (arg0: capsule) -> int
Invoked with: [1, 2, 3] Invoked with: [1, 2, 3]
""" # noqa: E501 line too long """ # noqa: E501 line too long
)
assert m.return_null_str() is None assert m.return_null_str() is None
assert m.get_null_str_value(m.return_null_str()) is not None assert m.get_null_str_value(m.return_null_str()) is not None
......
...@@ -56,23 +56,23 @@ def test_operator_overloading(): ...@@ -56,23 +56,23 @@ def test_operator_overloading():
del v3 del v3
assert cstats.alive() == 0 assert cstats.alive() == 0
assert cstats.values() == [ assert cstats.values() == [
'[1.000000, 2.000000]', "[1.000000, 2.000000]",
'[3.000000, -1.000000]', "[3.000000, -1.000000]",
'[1.000000, 2.000000]', "[1.000000, 2.000000]",
'[-3.000000, 1.000000]', "[-3.000000, 1.000000]",
'[4.000000, 1.000000]', "[4.000000, 1.000000]",
'[-2.000000, 3.000000]', "[-2.000000, 3.000000]",
'[-7.000000, -6.000000]', "[-7.000000, -6.000000]",
'[9.000000, 10.000000]', "[9.000000, 10.000000]",
'[8.000000, 16.000000]', "[8.000000, 16.000000]",
'[0.125000, 0.250000]', "[0.125000, 0.250000]",
'[7.000000, 6.000000]', "[7.000000, 6.000000]",
'[9.000000, 10.000000]', "[9.000000, 10.000000]",
'[8.000000, 16.000000]', "[8.000000, 16.000000]",
'[8.000000, 4.000000]', "[8.000000, 4.000000]",
'[3.000000, -2.000000]', "[3.000000, -2.000000]",
'[3.000000, -0.500000]', "[3.000000, -0.500000]",
'[6.000000, -2.000000]', "[6.000000, -2.000000]",
] ]
assert cstats.default_constructions == 0 assert cstats.default_constructions == 0
assert cstats.copy_constructions == 0 assert cstats.copy_constructions == 0
......
...@@ -42,5 +42,6 @@ def test_roundtrip_with_dict(cls_name): ...@@ -42,5 +42,6 @@ def test_roundtrip_with_dict(cls_name):
def test_enum_pickle(): def test_enum_pickle():
from pybind11_tests import enums as e from pybind11_tests import enums as e
data = pickle.dumps(e.EOne, 2) data = pickle.dumps(e.EOne, 2)
assert e.EOne == pickle.loads(data) assert e.EOne == pickle.loads(data)
...@@ -28,13 +28,16 @@ def test_list(capture, doc): ...@@ -28,13 +28,16 @@ def test_list(capture, doc):
lst.append("value2") lst.append("value2")
m.print_list(lst) m.print_list(lst)
assert capture.unordered == """ assert (
capture.unordered
== """
Entry at position 0: value Entry at position 0: value
list item 0: inserted-0 list item 0: inserted-0
list item 1: overwritten list item 1: overwritten
list item 2: inserted-2 list item 2: inserted-2
list item 3: value2 list item 3: value2
""" """
)
assert doc(m.get_list) == "get_list() -> list" assert doc(m.get_list) == "get_list() -> list"
assert doc(m.print_list) == "print_list(arg0: list) -> None" assert doc(m.print_list) == "print_list(arg0: list) -> None"
...@@ -52,12 +55,15 @@ def test_set(capture, doc): ...@@ -52,12 +55,15 @@ def test_set(capture, doc):
with capture: with capture:
s.add("key4") s.add("key4")
m.print_set(s) m.print_set(s)
assert capture.unordered == """ assert (
capture.unordered
== """
key: key1 key: key1
key: key2 key: key2
key: key3 key: key3
key: key4 key: key4
""" """
)
assert not m.set_contains(set([]), 42) assert not m.set_contains(set([]), 42)
assert m.set_contains({42}, 42) assert m.set_contains({42}, 42)
...@@ -74,10 +80,13 @@ def test_dict(capture, doc): ...@@ -74,10 +80,13 @@ def test_dict(capture, doc):
with capture: with capture:
d["key2"] = "value2" d["key2"] = "value2"
m.print_dict(d) m.print_dict(d)
assert capture.unordered == """ assert (
capture.unordered
== """
key: key, value=value key: key, value=value
key: key2, value=value2 key: key2, value=value2
""" """
)
assert not m.dict_contains({}, 42) assert not m.dict_contains({}, 42)
assert m.dict_contains({42: None}, 42) assert m.dict_contains({42: None}, 42)
...@@ -137,28 +146,37 @@ def test_capsule(capture): ...@@ -137,28 +146,37 @@ def test_capsule(capture):
a = m.return_capsule_with_destructor() a = m.return_capsule_with_destructor()
del a del a
pytest.gc_collect() pytest.gc_collect()
assert capture.unordered == """ assert (
capture.unordered
== """
creating capsule creating capsule
destructing capsule destructing capsule
""" """
)
with capture: with capture:
a = m.return_capsule_with_destructor_2() a = m.return_capsule_with_destructor_2()
del a del a
pytest.gc_collect() pytest.gc_collect()
assert capture.unordered == """ assert (
capture.unordered
== """
creating capsule creating capsule
destructing capsule: 1234 destructing capsule: 1234
""" """
)
with capture: with capture:
a = m.return_capsule_with_name_and_destructor() a = m.return_capsule_with_name_and_destructor()
del a del a
pytest.gc_collect() pytest.gc_collect()
assert capture.unordered == """ assert (
capture.unordered
== """
created capsule (1234, 'pointer type description') created capsule (1234, 'pointer type description')
destructing capsule (1234, 'pointer type description') destructing capsule (1234, 'pointer type description')
""" """
)
def test_accessors(): def test_accessors():
...@@ -212,7 +230,7 @@ def test_constructors(): ...@@ -212,7 +230,7 @@ def test_constructors():
assert m.default_constructors() == expected assert m.default_constructors() == expected
data = { data = {
bytes: b'41', # Currently no supported or working conversions. bytes: b"41", # Currently no supported or working conversions.
str: 42, str: 42,
bool: "Not empty", bool: "Not empty",
int: "42", int: "42",
...@@ -221,14 +239,14 @@ def test_constructors(): ...@@ -221,14 +239,14 @@ def test_constructors():
list: range(3), list: range(3),
dict: [("two", 2), ("one", 1), ("three", 3)], dict: [("two", 2), ("one", 1), ("three", 3)],
set: [4, 4, 5, 6, 6, 6], set: [4, 4, 5, 6, 6, 6],
memoryview: b'abc' memoryview: b"abc",
} }
inputs = {k.__name__: v for k, v in data.items()} inputs = {k.__name__: v for k, v in data.items()}
expected = {k.__name__: k(v) for k, v in data.items()} expected = {k.__name__: k(v) for k, v in data.items()}
if env.PY2: # Similar to the above. See comments above. if env.PY2: # Similar to the above. See comments above.
inputs["bytes"] = b'41' inputs["bytes"] = b"41"
inputs["str"] = 42 inputs["str"] = 42
expected["bytes"] = b'41' expected["bytes"] = b"41"
expected["str"] = u"42" expected["str"] = u"42"
assert m.converting_constructors(inputs) == expected assert m.converting_constructors(inputs) == expected
...@@ -255,7 +273,8 @@ def test_non_converting_constructors(): ...@@ -255,7 +273,8 @@ def test_non_converting_constructors():
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
m.nonconverting_constructor(t, v) m.nonconverting_constructor(t, v)
expected_error = "Object of type '{}' is not an instance of '{}'".format( expected_error = "Object of type '{}' is not an instance of '{}'".format(
type(v).__name__, t) type(v).__name__, t
)
assert str(excinfo.value) == expected_error assert str(excinfo.value) == expected_error
...@@ -263,12 +282,12 @@ def test_pybind11_str_raw_str(): ...@@ -263,12 +282,12 @@ def test_pybind11_str_raw_str():
# specifically to exercise pybind11::str::raw_str # specifically to exercise pybind11::str::raw_str
cvt = m.convert_to_pybind11_str cvt = m.convert_to_pybind11_str
assert cvt(u"Str") == u"Str" assert cvt(u"Str") == u"Str"
assert cvt(b'Bytes') == u"Bytes" if env.PY2 else "b'Bytes'" assert cvt(b"Bytes") == u"Bytes" if env.PY2 else "b'Bytes'"
assert cvt(None) == u"None" assert cvt(None) == u"None"
assert cvt(False) == u"False" assert cvt(False) == u"False"
assert cvt(True) == u"True" assert cvt(True) == u"True"
assert cvt(42) == u"42" assert cvt(42) == u"42"
assert cvt(2**65) == u"36893488147419103232" assert cvt(2 ** 65) == u"36893488147419103232"
assert cvt(-1.50) == u"-1.5" assert cvt(-1.50) == u"-1.5"
assert cvt(()) == u"()" assert cvt(()) == u"()"
assert cvt((18,)) == u"(18,)" assert cvt((18,)) == u"(18,)"
...@@ -283,29 +302,40 @@ def test_pybind11_str_raw_str(): ...@@ -283,29 +302,40 @@ def test_pybind11_str_raw_str():
valid_utf8 = valid_orig.encode("utf-8") valid_utf8 = valid_orig.encode("utf-8")
valid_cvt = cvt(valid_utf8) valid_cvt = cvt(valid_utf8)
assert type(valid_cvt) == bytes # Probably surprising. assert type(valid_cvt) == bytes # Probably surprising.
assert valid_cvt == b'\xc7\xb1' assert valid_cvt == b"\xc7\xb1"
malformed_utf8 = b'\x80' malformed_utf8 = b"\x80"
malformed_cvt = cvt(malformed_utf8) malformed_cvt = cvt(malformed_utf8)
assert type(malformed_cvt) == bytes # Probably surprising. assert type(malformed_cvt) == bytes # Probably surprising.
assert malformed_cvt == b'\x80' assert malformed_cvt == b"\x80"
def test_implicit_casting(): def test_implicit_casting():
"""Tests implicit casting when assigning or appending to dicts and lists.""" """Tests implicit casting when assigning or appending to dicts and lists."""
z = m.get_implicit_casting() z = m.get_implicit_casting()
assert z['d'] == { assert z["d"] == {
'char*_i1': 'abc', 'char*_i2': 'abc', 'char*_e': 'abc', 'char*_p': 'abc', "char*_i1": "abc",
'str_i1': 'str', 'str_i2': 'str1', 'str_e': 'str2', 'str_p': 'str3', "char*_i2": "abc",
'int_i1': 42, 'int_i2': 42, 'int_e': 43, 'int_p': 44 "char*_e": "abc",
"char*_p": "abc",
"str_i1": "str",
"str_i2": "str1",
"str_e": "str2",
"str_p": "str3",
"int_i1": 42,
"int_i2": 42,
"int_e": 43,
"int_p": 44,
} }
assert z['l'] == [3, 6, 9, 12, 15] assert z["l"] == [3, 6, 9, 12, 15]
def test_print(capture): def test_print(capture):
with capture: with capture:
m.print_function() m.print_function()
assert capture == """ assert (
capture
== """
Hello, World! Hello, World!
1 2.0 three True -- multiple args 1 2.0 three True -- multiple args
*args-and-a-custom-separator *args-and-a-custom-separator
...@@ -313,14 +343,15 @@ def test_print(capture): ...@@ -313,14 +343,15 @@ def test_print(capture):
flush flush
py::print + str.format = this py::print + str.format = this
""" """
)
assert capture.stderr == "this goes to stderr" assert capture.stderr == "this goes to stderr"
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
m.print_failure() m.print_failure()
assert str(excinfo.value) == "make_tuple(): unable to convert " + ( assert str(excinfo.value) == "make_tuple(): unable to convert " + (
"argument of type 'UnregisteredType' to Python object" "argument of type 'UnregisteredType' to Python object"
if debug_enabled else if debug_enabled
"arguments to Python object (compile in debug mode for details)" else "arguments to Python object (compile in debug mode for details)"
) )
...@@ -342,8 +373,23 @@ def test_hash(): ...@@ -342,8 +373,23 @@ def test_hash():
def test_number_protocol(): def test_number_protocol():
for a, b in [(1, 1), (3, 5)]: for a, b in [(1, 1), (3, 5)]:
li = [a == b, a != b, a < b, a <= b, a > b, a >= b, a + b, li = [
a - b, a * b, a / b, a | b, a & b, a ^ b, a >> b, a << b] a == b,
a != b,
a < b,
a <= b,
a > b,
a >= b,
a + b,
a - b,
a * b,
a / b,
a | b,
a & b,
a ^ b,
a >> b,
a << b,
]
assert m.test_number_protocol(a, b) == li assert m.test_number_protocol(a, b) == li
...@@ -360,13 +406,16 @@ def test_issue2361(): ...@@ -360,13 +406,16 @@ def test_issue2361():
assert "'NoneType' object is not iterable" in str(excinfo.value) assert "'NoneType' object is not iterable" in str(excinfo.value)
@pytest.mark.parametrize('method, args, fmt, expected_view', [ @pytest.mark.parametrize(
(m.test_memoryview_object, (b'red',), 'B', b'red'), "method, args, fmt, expected_view",
(m.test_memoryview_buffer_info, (b'green',), 'B', b'green'), [
(m.test_memoryview_from_buffer, (False,), 'h', [3, 1, 4, 1, 5]), (m.test_memoryview_object, (b"red",), "B", b"red"),
(m.test_memoryview_from_buffer, (True,), 'H', [2, 7, 1, 8]), (m.test_memoryview_buffer_info, (b"green",), "B", b"green"),
(m.test_memoryview_from_buffer_nativeformat, (), '@i', [4, 7, 5]), (m.test_memoryview_from_buffer, (False,), "h", [3, 1, 4, 1, 5]),
]) (m.test_memoryview_from_buffer, (True,), "H", [2, 7, 1, 8]),
(m.test_memoryview_from_buffer_nativeformat, (), "@i", [4, 7, 5]),
],
)
def test_memoryview(method, args, fmt, expected_view): def test_memoryview(method, args, fmt, expected_view):
view = method(*args) view = method(*args)
assert isinstance(view, memoryview) assert isinstance(view, memoryview)
...@@ -380,12 +429,15 @@ def test_memoryview(method, args, fmt, expected_view): ...@@ -380,12 +429,15 @@ def test_memoryview(method, args, fmt, expected_view):
@pytest.mark.xfail("env.PYPY", reason="getrefcount is not available") @pytest.mark.xfail("env.PYPY", reason="getrefcount is not available")
@pytest.mark.parametrize('method', [ @pytest.mark.parametrize(
m.test_memoryview_object, "method",
m.test_memoryview_buffer_info, [
]) m.test_memoryview_object,
m.test_memoryview_buffer_info,
],
)
def test_memoryview_refcount(method): def test_memoryview_refcount(method):
buf = b'\x0a\x0b\x0c\x0d' buf = b"\x0a\x0b\x0c\x0d"
ref_before = sys.getrefcount(buf) ref_before = sys.getrefcount(buf)
view = method(buf) view = method(buf)
ref_after = sys.getrefcount(buf) ref_after = sys.getrefcount(buf)
...@@ -396,13 +448,13 @@ def test_memoryview_refcount(method): ...@@ -396,13 +448,13 @@ def test_memoryview_refcount(method):
def test_memoryview_from_buffer_empty_shape(): def test_memoryview_from_buffer_empty_shape():
view = m.test_memoryview_from_buffer_empty_shape() view = m.test_memoryview_from_buffer_empty_shape()
assert isinstance(view, memoryview) assert isinstance(view, memoryview)
assert view.format == 'B' assert view.format == "B"
if env.PY2: if env.PY2:
# Python 2 behavior is weird, but Python 3 (the future) is fine. # Python 2 behavior is weird, but Python 3 (the future) is fine.
# PyPy3 has <memoryview, while CPython 2 has <memory # PyPy3 has <memoryview, while CPython 2 has <memory
assert bytes(view).startswith(b'<memory') assert bytes(view).startswith(b"<memory")
else: else:
assert bytes(view) == b'' assert bytes(view) == b""
def test_test_memoryview_from_buffer_invalid_strides(): def test_test_memoryview_from_buffer_invalid_strides():
...@@ -422,13 +474,15 @@ def test_test_memoryview_from_buffer_nullptr(): ...@@ -422,13 +474,15 @@ def test_test_memoryview_from_buffer_nullptr():
def test_memoryview_from_memory(): def test_memoryview_from_memory():
view = m.test_memoryview_from_memory() view = m.test_memoryview_from_memory()
assert isinstance(view, memoryview) assert isinstance(view, memoryview)
assert view.format == 'B' assert view.format == "B"
assert bytes(view) == b'\xff\xe1\xab\x37' assert bytes(view) == b"\xff\xe1\xab\x37"
def test_builtin_functions(): def test_builtin_functions():
assert m.get_len([i for i in range(42)]) == 42 assert m.get_len([i for i in range(42)]) == 42
with pytest.raises(TypeError) as exc_info: with pytest.raises(TypeError) as exc_info:
m.get_len(i for i in range(42)) m.get_len(i for i in range(42))
assert str(exc_info.value) in ["object of type 'generator' has no len()", assert str(exc_info.value) in [
"'generator' has no length"] # PyPy "object of type 'generator' has no len()",
"'generator' has no length",
] # PyPy
...@@ -10,7 +10,9 @@ def isclose(a, b, rel_tol=1e-05, abs_tol=0.0): ...@@ -10,7 +10,9 @@ def isclose(a, b, rel_tol=1e-05, abs_tol=0.0):
def allclose(a_list, b_list, rel_tol=1e-05, abs_tol=0.0): def allclose(a_list, b_list, rel_tol=1e-05, abs_tol=0.0):
return all(isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol) for a, b in zip(a_list, b_list)) return all(
isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol) for a, b in zip(a_list, b_list)
)
def test_generalized_iterators(): def test_generalized_iterators():
...@@ -51,7 +53,7 @@ def test_sequence(): ...@@ -51,7 +53,7 @@ def test_sequence():
cstats = ConstructorStats.get(m.Sequence) cstats = ConstructorStats.get(m.Sequence)
s = m.Sequence(5) s = m.Sequence(5)
assert cstats.values() == ['of size', '5'] assert cstats.values() == ["of size", "5"]
assert "Sequence" in repr(s) assert "Sequence" in repr(s)
assert len(s) == 5 assert len(s) == 5
...@@ -62,16 +64,16 @@ def test_sequence(): ...@@ -62,16 +64,16 @@ def test_sequence():
assert isclose(s[0], 12.34) and isclose(s[3], 56.78) assert isclose(s[0], 12.34) and isclose(s[3], 56.78)
rev = reversed(s) rev = reversed(s)
assert cstats.values() == ['of size', '5'] assert cstats.values() == ["of size", "5"]
rev2 = s[::-1] rev2 = s[::-1]
assert cstats.values() == ['of size', '5'] assert cstats.values() == ["of size", "5"]
it = iter(m.Sequence(0)) it = iter(m.Sequence(0))
for _ in range(3): # __next__ must continue to raise StopIteration for _ in range(3): # __next__ must continue to raise StopIteration
with pytest.raises(StopIteration): with pytest.raises(StopIteration):
next(it) next(it)
assert cstats.values() == ['of size', '0'] assert cstats.values() == ["of size", "0"]
expected = [0, 56.78, 0, 0, 12.34] expected = [0, 56.78, 0, 0, 12.34]
assert allclose(rev, expected) assert allclose(rev, expected)
...@@ -79,7 +81,7 @@ def test_sequence(): ...@@ -79,7 +81,7 @@ def test_sequence():
assert rev == rev2 assert rev == rev2
rev[0::2] = m.Sequence([2.0, 2.0, 2.0]) rev[0::2] = m.Sequence([2.0, 2.0, 2.0])
assert cstats.values() == ['of size', '3', 'from std::vector'] assert cstats.values() == ["of size", "3", "from std::vector"]
assert allclose(rev, [2, 56.78, 2, 0, 2]) assert allclose(rev, [2, 56.78, 2, 0, 2])
...@@ -103,10 +105,11 @@ def test_sequence(): ...@@ -103,10 +105,11 @@ def test_sequence():
def test_sequence_length(): def test_sequence_length():
"""#2076: Exception raised by len(arg) should be propagated """ """#2076: Exception raised by len(arg) should be propagated """
class BadLen(RuntimeError): class BadLen(RuntimeError):
pass pass
class SequenceLike(): class SequenceLike:
def __getitem__(self, i): def __getitem__(self, i):
return None return None
...@@ -121,17 +124,17 @@ def test_sequence_length(): ...@@ -121,17 +124,17 @@ def test_sequence_length():
def test_map_iterator(): def test_map_iterator():
sm = m.StringMap({'hi': 'bye', 'black': 'white'}) sm = m.StringMap({"hi": "bye", "black": "white"})
assert sm['hi'] == 'bye' assert sm["hi"] == "bye"
assert len(sm) == 2 assert len(sm) == 2
assert sm['black'] == 'white' assert sm["black"] == "white"
with pytest.raises(KeyError): with pytest.raises(KeyError):
assert sm['orange'] assert sm["orange"]
sm['orange'] = 'banana' sm["orange"] = "banana"
assert sm['orange'] == 'banana' assert sm["orange"] == "banana"
expected = {'hi': 'bye', 'black': 'white', 'orange': 'banana'} expected = {"hi": "bye", "black": "white", "orange": "banana"}
for k in sm: for k in sm:
assert sm[k] == expected[k] assert sm[k] == expected[k]
for k, v in sm.items(): for k, v in sm.items():
...@@ -179,7 +182,8 @@ def test_iterator_passthrough(): ...@@ -179,7 +182,8 @@ def test_iterator_passthrough():
"""#181: iterator passthrough did not compile""" """#181: iterator passthrough did not compile"""
from pybind11_tests.sequences_and_iterators import iterator_passthrough from pybind11_tests.sequences_and_iterators import iterator_passthrough
assert list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15]))) == [3, 5, 7, 9, 11, 13, 15] values = [3, 5, 7, 9, 11, 13, 15]
assert list(iterator_passthrough(iter(values))) == values
def test_iterator_rvp(): def test_iterator_rvp():
......
...@@ -7,7 +7,9 @@ from pybind11_tests import ConstructorStats # noqa: E402 ...@@ -7,7 +7,9 @@ from pybind11_tests import ConstructorStats # noqa: E402
def test_smart_ptr(capture): def test_smart_ptr(capture):
# Object1 # Object1
for i, o in enumerate([m.make_object_1(), m.make_object_2(), m.MyObject1(3)], start=1): for i, o in enumerate(
[m.make_object_1(), m.make_object_2(), m.MyObject1(3)], start=1
):
assert o.getRefCount() == 1 assert o.getRefCount() == 1
with capture: with capture:
m.print_object_1(o) m.print_object_1(o)
...@@ -16,8 +18,9 @@ def test_smart_ptr(capture): ...@@ -16,8 +18,9 @@ def test_smart_ptr(capture):
m.print_object_4(o) m.print_object_4(o)
assert capture == "MyObject1[{i}]\n".format(i=i) * 4 assert capture == "MyObject1[{i}]\n".format(i=i) * 4
for i, o in enumerate([m.make_myobject1_1(), m.make_myobject1_2(), m.MyObject1(6), 7], for i, o in enumerate(
start=4): [m.make_myobject1_1(), m.make_myobject1_2(), m.MyObject1(6), 7], start=4
):
print(o) print(o)
with capture: with capture:
if not isinstance(o, int): if not isinstance(o, int):
...@@ -29,11 +32,15 @@ def test_smart_ptr(capture): ...@@ -29,11 +32,15 @@ def test_smart_ptr(capture):
m.print_myobject1_2(o) m.print_myobject1_2(o)
m.print_myobject1_3(o) m.print_myobject1_3(o)
m.print_myobject1_4(o) m.print_myobject1_4(o)
assert capture == "MyObject1[{i}]\n".format(i=i) * (4 if isinstance(o, int) else 8)
times = 4 if isinstance(o, int) else 8
assert capture == "MyObject1[{i}]\n".format(i=i) * times
cstats = ConstructorStats.get(m.MyObject1) cstats = ConstructorStats.get(m.MyObject1)
assert cstats.alive() == 0 assert cstats.alive() == 0
expected_values = ['MyObject1[{}]'.format(i) for i in range(1, 7)] + ['MyObject1[7]'] * 4 expected_values = ["MyObject1[{}]".format(i) for i in range(1, 7)] + [
"MyObject1[7]"
] * 4
assert cstats.values() == expected_values assert cstats.values() == expected_values
assert cstats.default_constructions == 0 assert cstats.default_constructions == 0
assert cstats.copy_constructions == 0 assert cstats.copy_constructions == 0
...@@ -42,7 +49,9 @@ def test_smart_ptr(capture): ...@@ -42,7 +49,9 @@ def test_smart_ptr(capture):
assert cstats.move_assignments == 0 assert cstats.move_assignments == 0
# Object2 # Object2
for i, o in zip([8, 6, 7], [m.MyObject2(8), m.make_myobject2_1(), m.make_myobject2_2()]): for i, o in zip(
[8, 6, 7], [m.MyObject2(8), m.make_myobject2_1(), m.make_myobject2_2()]
):
print(o) print(o)
with capture: with capture:
m.print_myobject2_1(o) m.print_myobject2_1(o)
...@@ -55,7 +64,7 @@ def test_smart_ptr(capture): ...@@ -55,7 +64,7 @@ def test_smart_ptr(capture):
assert cstats.alive() == 1 assert cstats.alive() == 1
o = None o = None
assert cstats.alive() == 0 assert cstats.alive() == 0
assert cstats.values() == ['MyObject2[8]', 'MyObject2[6]', 'MyObject2[7]'] assert cstats.values() == ["MyObject2[8]", "MyObject2[6]", "MyObject2[7]"]
assert cstats.default_constructions == 0 assert cstats.default_constructions == 0
assert cstats.copy_constructions == 0 assert cstats.copy_constructions == 0
# assert cstats.move_constructions >= 0 # Doesn't invoke any # assert cstats.move_constructions >= 0 # Doesn't invoke any
...@@ -63,7 +72,9 @@ def test_smart_ptr(capture): ...@@ -63,7 +72,9 @@ def test_smart_ptr(capture):
assert cstats.move_assignments == 0 assert cstats.move_assignments == 0
# Object3 # Object3
for i, o in zip([9, 8, 9], [m.MyObject3(9), m.make_myobject3_1(), m.make_myobject3_2()]): for i, o in zip(
[9, 8, 9], [m.MyObject3(9), m.make_myobject3_1(), m.make_myobject3_2()]
):
print(o) print(o)
with capture: with capture:
m.print_myobject3_1(o) m.print_myobject3_1(o)
...@@ -76,7 +87,7 @@ def test_smart_ptr(capture): ...@@ -76,7 +87,7 @@ def test_smart_ptr(capture):
assert cstats.alive() == 1 assert cstats.alive() == 1
o = None o = None
assert cstats.alive() == 0 assert cstats.alive() == 0
assert cstats.values() == ['MyObject3[9]', 'MyObject3[8]', 'MyObject3[9]'] assert cstats.values() == ["MyObject3[9]", "MyObject3[8]", "MyObject3[9]"]
assert cstats.default_constructions == 0 assert cstats.default_constructions == 0
assert cstats.copy_constructions == 0 assert cstats.copy_constructions == 0
# assert cstats.move_constructions >= 0 # Doesn't invoke any # assert cstats.move_constructions >= 0 # Doesn't invoke any
...@@ -96,7 +107,7 @@ def test_smart_ptr(capture): ...@@ -96,7 +107,7 @@ def test_smart_ptr(capture):
# ref<> # ref<>
cstats = m.cstats_ref() cstats = m.cstats_ref()
assert cstats.alive() == 0 assert cstats.alive() == 0
assert cstats.values() == ['from pointer'] * 10 assert cstats.values() == ["from pointer"] * 10
assert cstats.default_constructions == 30 assert cstats.default_constructions == 30
assert cstats.copy_constructions == 12 assert cstats.copy_constructions == 12
# assert cstats.move_constructions >= 0 # Doesn't invoke any # assert cstats.move_constructions >= 0 # Doesn't invoke any
...@@ -186,7 +197,9 @@ def test_shared_ptr_from_this_and_references(): ...@@ -186,7 +197,9 @@ def test_shared_ptr_from_this_and_references():
ref = s.ref # init_holder_helper(holder_ptr=false, owned=false, bad_wp=false) ref = s.ref # init_holder_helper(holder_ptr=false, owned=false, bad_wp=false)
assert stats.alive() == 2 assert stats.alive() == 2
assert s.set_ref(ref) assert s.set_ref(ref)
assert s.set_holder(ref) # std::enable_shared_from_this can create a holder from a reference assert s.set_holder(
ref
) # std::enable_shared_from_this can create a holder from a reference
bad_wp = s.bad_wp # init_holder_helper(holder_ptr=false, owned=false, bad_wp=true) bad_wp = s.bad_wp # init_holder_helper(holder_ptr=false, owned=false, bad_wp=true)
assert stats.alive() == 2 assert stats.alive() == 2
...@@ -200,12 +213,16 @@ def test_shared_ptr_from_this_and_references(): ...@@ -200,12 +213,16 @@ def test_shared_ptr_from_this_and_references():
assert s.set_ref(copy) assert s.set_ref(copy)
assert s.set_holder(copy) assert s.set_holder(copy)
holder_ref = s.holder_ref # init_holder_helper(holder_ptr=true, owned=false, bad_wp=false) holder_ref = (
s.holder_ref
) # init_holder_helper(holder_ptr=true, owned=false, bad_wp=false)
assert stats.alive() == 3 assert stats.alive() == 3
assert s.set_ref(holder_ref) assert s.set_ref(holder_ref)
assert s.set_holder(holder_ref) assert s.set_holder(holder_ref)
holder_copy = s.holder_copy # init_holder_helper(holder_ptr=true, owned=true, bad_wp=false) holder_copy = (
s.holder_copy
) # init_holder_helper(holder_ptr=true, owned=true, bad_wp=false)
assert stats.alive() == 3 assert stats.alive() == 3
assert s.set_ref(holder_copy) assert s.set_ref(holder_copy)
assert s.set_holder(holder_copy) assert s.set_holder(holder_copy)
...@@ -277,8 +294,10 @@ def test_smart_ptr_from_default(): ...@@ -277,8 +294,10 @@ def test_smart_ptr_from_default():
instance = m.HeldByDefaultHolder() instance = m.HeldByDefaultHolder()
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
m.HeldByDefaultHolder.load_shared_ptr(instance) m.HeldByDefaultHolder.load_shared_ptr(instance)
assert "Unable to load a custom holder type from a " \ assert (
"default-holder instance" in str(excinfo.value) "Unable to load a custom holder type from a "
"default-holder instance" in str(excinfo.value)
)
def test_shared_ptr_gc(): def test_shared_ptr_gc():
......
This diff is collapsed.
This diff is collapsed.
...@@ -5,16 +5,24 @@ from pybind11_tests import tagbased_polymorphic as m ...@@ -5,16 +5,24 @@ from pybind11_tests import tagbased_polymorphic as m
def test_downcast(): def test_downcast():
zoo = m.create_zoo() zoo = m.create_zoo()
assert [type(animal) for animal in zoo] == [ assert [type(animal) for animal in zoo] == [
m.Labrador, m.Dog, m.Chihuahua, m.Cat, m.Panther m.Labrador,
m.Dog,
m.Chihuahua,
m.Cat,
m.Panther,
] ]
assert [animal.name for animal in zoo] == [ assert [animal.name for animal in zoo] == [
"Fido", "Ginger", "Hertzl", "Tiger", "Leo" "Fido",
"Ginger",
"Hertzl",
"Tiger",
"Leo",
] ]
zoo[1].sound = "woooooo" zoo[1].sound = "woooooo"
assert [dog.bark() for dog in zoo[:3]] == [ assert [dog.bark() for dog in zoo[:3]] == [
"Labrador Fido goes WOOF!", "Labrador Fido goes WOOF!",
"Dog Ginger goes woooooo", "Dog Ginger goes woooooo",
"Chihuahua Hertzl goes iyiyiyiyiyi and runs in circles" "Chihuahua Hertzl goes iyiyiyiyiyi and runs in circles",
] ]
assert [cat.purr() for cat in zoo[3:]] == ["mrowr", "mrrrRRRRRR"] assert [cat.purr() for cat in zoo[3:]] == ["mrowr", "mrrrRRRRRR"]
zoo[0].excitement -= 1000 zoo[0].excitement -= 1000
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment