Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
c50f90ec
Unverified
Commit
c50f90ec
authored
Oct 16, 2020
by
Henry Schreiner
Committed by
GitHub
Oct 16, 2020
Browse files
style: use Black everywhere (#2594)
* style: use Black everywhere * style: minor touchup from review
parent
2e31e466
Changes
38
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
888 additions
and
480 deletions
+888
-480
tests/test_kwargs_and_defaults.py
tests/test_kwargs_and_defaults.py
+70
-25
tests/test_local_bindings.py
tests/test_local_bindings.py
+40
-12
tests/test_methods_and_attributes.py
tests/test_methods_and_attributes.py
+49
-30
tests/test_modules.py
tests/test_modules.py
+7
-3
tests/test_multiple_inheritance.py
tests/test_multiple_inheritance.py
+11
-6
tests/test_numpy_array.py
tests/test_numpy_array.py
+140
-94
tests/test_numpy_dtypes.py
tests/test_numpy_dtypes.py
+161
-96
tests/test_numpy_vectorize.py
tests/test_numpy_vectorize.py
+105
-44
tests/test_opaque_types.py
tests/test_opaque_types.py
+4
-1
tests/test_operator_overloading.py
tests/test_operator_overloading.py
+17
-17
tests/test_pickling.py
tests/test_pickling.py
+1
-0
tests/test_pytypes.py
tests/test_pytypes.py
+99
-45
tests/test_sequences_and_iterators.py
tests/test_sequences_and_iterators.py
+19
-15
tests/test_smart_ptr.py
tests/test_smart_ptr.py
+34
-15
tests/test_stl.py
tests/test_stl.py
+36
-22
tests/test_stl_binders.py
tests/test_stl_binders.py
+40
-34
tests/test_tagbased_polymorphic.py
tests/test_tagbased_polymorphic.py
+11
-3
tests/test_virtual_functions.py
tests/test_virtual_functions.py
+44
-18
No files found.
tests/test_kwargs_and_defaults.py
View file @
c50f90ec
...
...
@@ -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_z
)
==
"kw_func_udl_z(x: int, y: int = 0) -> str"
assert
doc
(
m
.
args_function
)
==
"args_function(*args) -> tuple"
assert
doc
(
m
.
args_kwargs_function
)
==
"args_kwargs_function(*args, **kwargs) -> tuple"
assert
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"
assert
(
doc
(
m
.
args_kwargs_function
)
==
"args_kwargs_function(*args, **kwargs) -> tuple"
)
assert
(
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
):
...
...
@@ -40,7 +46,9 @@ def test_named_arguments(msg):
# noinspection PyArgumentList
m
.
kw_func2
(
x
=
5
,
y
=
10
,
z
=
12
)
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
(
myList
=
[
1
,
2
,
3
])
==
"{1 2 3}"
...
...
@@ -50,11 +58,11 @@ def test_named_arguments(msg):
def
test_arg_and_kwargs
():
args
=
'
arg1_value
'
,
'
arg2_value
'
,
3
args
=
"
arg1_value
"
,
"
arg2_value
"
,
3
assert
m
.
args_function
(
*
args
)
==
args
args
=
'
a1
'
,
'
a2
'
kwargs
=
dict
(
arg3
=
'
a3
'
,
arg4
=
4
)
args
=
"
a1
"
,
"
a2
"
kwargs
=
dict
(
arg3
=
"
a3
"
,
arg4
=
4
)
assert
m
.
args_kwargs_function
(
*
args
,
**
kwargs
)
==
(
args
,
kwargs
)
...
...
@@ -68,47 +76,71 @@ def test_mixed_args_and_kwargs(msg):
assert
mpa
(
1
,
2.5
)
==
(
1
,
2.5
,
())
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
mpa
(
1
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
mixed_plus_args(): incompatible function arguments. The following argument types are supported:
1. (arg0: int, arg1: float, *args) -> tuple
Invoked with: 1
"""
# noqa: E501 line too long
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
mpa
()
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
mixed_plus_args(): incompatible function arguments. The following argument types are supported:
1. (arg0: int, arg1: float, *args) -> tuple
Invoked with:
"""
# 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
)
==
(
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
(
3
)
==
(
3
,
3.14159
,
(),
{})
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
)
==
(
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:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
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:
1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple
Invoked with: 1; kwargs: i=1
"""
# noqa: E501 line too long
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
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:
1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple
Invoked with: 1, 2; kwargs: j=1
"""
# noqa: E501 line too long
)
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
(
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
(
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
(
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
(
2
,
k
=
3
,
extra
=
4
)
==
(
2
,
-
1
,
3
,
{
"
extra
"
:
4
})
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
m
.
kw_only_mixed
(
i
=
1
)
==
(
1
,)
...
...
@@ -144,9 +176,12 @@ def test_keyword_only_args(msg):
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
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
"""
)
def
test_positional_only_args
(
msg
):
...
...
@@ -194,7 +229,10 @@ def test_signatures():
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_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"
)
...
...
@@ -219,11 +257,18 @@ def test_args_refcount():
assert
m
.
args_function
(
-
1
,
myval
)
==
(
-
1
,
myval
)
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
m
.
args_kwargs_function
(
7
,
8
,
myval
,
a
=
1
,
b
=
myval
)
==
\
((
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
},
)
assert
refcount
(
myval
)
==
expected
exp3
=
refcount
(
myval
,
myval
,
myval
)
...
...
tests/test_local_bindings.py
View file @
c50f90ec
...
...
@@ -36,8 +36,8 @@ def test_local_bindings():
assert
i2
.
get
()
==
11
assert
i2
.
get2
()
==
12
assert
not
hasattr
(
i1
,
'
get2
'
)
assert
not
hasattr
(
i2
,
'
get3
'
)
assert
not
hasattr
(
i1
,
"
get2
"
)
assert
not
hasattr
(
i2
,
"
get3
"
)
# Loading within the local module
assert
m
.
local_value
(
i1
)
==
5
...
...
@@ -55,7 +55,9 @@ def test_nonlocal_failure():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
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
():
...
...
@@ -63,9 +65,12 @@ def test_duplicate_local():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
register_local_external
()
import
pybind11_tests
assert
str
(
excinfo
.
value
)
==
(
'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
():
...
...
@@ -98,8 +103,8 @@ def test_stl_bind_local():
d1
[
"b"
]
=
v1
[
1
]
d2
[
"c"
]
=
v2
[
0
]
d2
[
"d"
]
=
v2
[
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
:
d1
[
i
].
get
()
for
i
in
d1
}
==
{
"a"
:
0
,
"b"
:
1
}
assert
{
i
:
d2
[
i
].
get
()
for
i
in
d2
}
==
{
"c"
:
2
,
"d"
:
3
}
def
test_stl_bind_global
():
...
...
@@ -107,15 +112,21 @@ def test_stl_bind_global():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
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
:
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
:
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
():
...
...
@@ -123,6 +134,7 @@ def test_mixed_local_global():
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."""
import
pybind11_cross_module_tests
as
cm
m
.
register_mixed_global
()
m
.
register_mixed_local
()
...
...
@@ -145,13 +157,26 @@ def test_mixed_local_global():
a
.
append
(
cm
.
get_mixed_gl
(
11
))
a
.
append
(
cm
.
get_mixed_lg
(
12
))
assert
[
x
.
get
()
for
x
in
a
]
==
\
[
101
,
1002
,
103
,
1004
,
105
,
1006
,
207
,
2008
,
109
,
1010
,
211
,
2012
]
assert
[
x
.
get
()
for
x
in
a
]
==
[
101
,
1002
,
103
,
1004
,
105
,
1006
,
207
,
2008
,
109
,
1010
,
211
,
2012
,
]
def
test_internal_locals_differ
():
"""Makes sure the internal local type map differs across the two modules"""
import
pybind11_cross_module_tests
as
cm
assert
m
.
local_cpp_types_addr
()
!=
cm
.
local_cpp_types_addr
()
...
...
@@ -169,12 +194,15 @@ def test_stl_caster_vs_stl_bind(msg):
assert
m
.
load_vector_via_caster
(
v2
)
==
6
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
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:
1. (arg0: pybind11_cross_module_tests.VectorInt) -> int
Invoked with: [1, 2, 3]
"""
# noqa: E501 line too long
)
def
test_cross_module_calls
():
...
...
tests/test_methods_and_attributes.py
View file @
c50f90ec
...
...
@@ -40,17 +40,17 @@ def test_methods_and_attributes():
assert
instance1
.
overloaded
(
0
)
==
"(int)"
assert
instance1
.
overloaded
(
1
,
1.0
)
==
"(int, float)"
assert
instance1
.
overloaded
(
2.0
,
2
)
==
"(float, int)"
assert
instance1
.
overloaded
(
3
,
3
)
==
"(int, int)"
assert
instance1
.
overloaded
(
4.
,
4.
)
==
"(float, float)"
assert
instance1
.
overloaded
(
3
,
3
)
==
"(int, int)"
assert
instance1
.
overloaded
(
4.
0
,
4.
0
)
==
"(float, float)"
assert
instance1
.
overloaded_const
(
-
3
)
==
"(int) 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
(
7
,
7
)
==
"(int, int) const"
assert
instance1
.
overloaded_const
(
8.
,
8.
)
==
"(float, float) const"
assert
instance1
.
overloaded_const
(
7
,
7
)
==
"(int, int) 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.
)
==
"(float, float)"
assert
instance1
.
overloaded_float
(
1
,
1.
0
)
==
"(float, float)"
assert
instance1
.
overloaded_float
(
1.
0
,
1
)
==
"(float, float)"
assert
instance1
.
overloaded_float
(
1.
0
,
1.
0
)
==
"(float, float)"
assert
instance1
.
value
==
320
instance1
.
value
=
100
...
...
@@ -193,7 +193,10 @@ def test_metaclass_override():
assert
type
(
m
.
MetaclassOverride
).
__name__
==
"type"
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__()`
m
.
MetaclassOverride
.
readonly
=
2
...
...
@@ -206,22 +209,26 @@ def test_no_mixed_overloads():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
ExampleMandA
.
add_mixed_overloads1
()
assert
(
str
(
excinfo
.
value
)
==
"overloading a method with both static and instance methods is not supported; "
+
(
"compile in debug mode for more details"
if
not
debug_enabled
else
"error while attempting to bind static method ExampleMandA.overload_mixed1"
"(arg0: float) -> str"
)
)
assert
str
(
excinfo
.
value
)
==
"overloading a method with both static and instance methods is not supported; "
+
(
"compile in debug mode for more details"
if
not
debug_enabled
else
"error while attempting to bind static method ExampleMandA.overload_mixed1"
"(arg0: float) -> str"
)
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
ExampleMandA
.
add_mixed_overloads2
()
assert
(
str
(
excinfo
.
value
)
==
"overloading a method with both static and instance methods is not supported; "
+
(
"compile in debug mode for more details"
if
not
debug_enabled
else
"error while attempting to bind instance method ExampleMandA.overload_mixed2"
"(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: int, arg1: int)"
" -> str"
)
)
assert
str
(
excinfo
.
value
)
==
"overloading a method with both static and instance methods is not supported; "
+
(
"compile in debug mode for more details"
if
not
debug_enabled
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"
])
...
...
@@ -333,8 +340,8 @@ def test_bad_arg_default(msg):
assert
msg
(
excinfo
.
value
)
==
(
"arg(): could not convert default argument 'a: UnregisteredType' in function "
"'should_fail' into a Python object (type not registered yet?)"
if
debug_enabled
else
"arg(): could not convert default argument into a Python object (type not registered "
if
debug_enabled
else
"arg(): could not convert default argument into a Python object (type not registered "
"yet?). Compile in debug mode for more information."
)
...
...
@@ -343,8 +350,8 @@ def test_bad_arg_default(msg):
assert
msg
(
excinfo
.
value
)
==
(
"arg(): could not convert default argument 'UnregisteredType' in function "
"'should_fail' into a Python object (type not registered yet?)"
if
debug_enabled
else
"arg(): could not convert default argument into a Python object (type not registered "
if
debug_enabled
else
"arg(): could not convert default argument into a Python object (type not registered "
"yet?). Compile in debug mode for more information."
)
...
...
@@ -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:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
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:
1. (arg0: m.methods_and_attributes.NoneTester) -> int
Invoked with: None
"""
)
# The rest take the argument as pointer or holder, and accept None:
assert
m
.
ok_none2
(
None
)
==
-
1
...
...
@@ -402,13 +412,16 @@ def test_str_issue(msg):
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
str
(
m
.
StrIssue
(
"no"
,
"such"
,
"constructor"
))
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
__init__(): incompatible constructor arguments. The following argument types are supported:
1. m.methods_and_attributes.StrIssue(arg0: int)
2. m.methods_and_attributes.StrIssue()
Invoked with: 'no', 'such', 'constructor'
"""
)
def
test_unregistered_base_implementations
():
...
...
@@ -441,7 +454,7 @@ def test_ref_qualified():
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
(
0
)
==
4
...
...
@@ -449,8 +462,14 @@ def test_overload_ordering():
uni_name
=
type
(
u
""
).
__name__
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
"3. overload_order(arg0: {}) -> int"
.
format
(
uni_name
)
in
m
.
overload_order
.
__doc__
assert
(
"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__
with
pytest
.
raises
(
TypeError
)
as
err
:
...
...
tests/test_modules.py
View file @
c50f90ec
...
...
@@ -6,9 +6,13 @@ from pybind11_tests import ConstructorStats
def
test_nested_modules
():
import
pybind11_tests
assert
pybind11_tests
.
__name__
==
"pybind11_tests"
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
ms
.
__name__
==
"pybind11_tests.modules.subsubmodule"
...
...
@@ -35,7 +39,7 @@ def test_reference_internal():
del
b
assert
astats
.
alive
()
==
0
assert
bstats
.
alive
()
==
0
assert
astats
.
values
()
==
[
'1'
,
'2'
,
'
42
'
,
'
43
'
]
assert
astats
.
values
()
==
[
"1"
,
"2"
,
"
42
"
,
"
43
"
]
assert
bstats
.
values
()
==
[]
assert
astats
.
default_constructions
==
0
assert
bstats
.
default_constructions
==
1
...
...
@@ -54,7 +58,7 @@ def test_importing():
from
collections
import
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
():
...
...
tests/test_multiple_inheritance.py
View file @
c50f90ec
...
...
@@ -57,7 +57,6 @@ def test_multiple_inheritance_mix2():
@
pytest
.
mark
.
skipif
(
"env.PYPY and env.PY2"
)
@
pytest
.
mark
.
xfail
(
"env.PYPY and not env.PY2"
)
def
test_multiple_inheritance_python
():
class
MI1
(
m
.
Base1
,
m
.
Base2
):
def
__init__
(
self
,
i
,
j
):
m
.
Base1
.
__init__
(
self
,
i
)
...
...
@@ -163,7 +162,6 @@ def test_multiple_inheritance_python():
def
test_multiple_inheritance_python_many_bases
():
class
MIMany14
(
m
.
BaseN1
,
m
.
BaseN2
,
m
.
BaseN3
,
m
.
BaseN4
):
def
__init__
(
self
):
m
.
BaseN1
.
__init__
(
self
,
1
)
...
...
@@ -178,8 +176,16 @@ def test_multiple_inheritance_python_many_bases():
m
.
BaseN7
.
__init__
(
self
,
7
)
m
.
BaseN8
.
__init__
(
self
,
8
)
class
MIMany916
(
m
.
BaseN9
,
m
.
BaseN10
,
m
.
BaseN11
,
m
.
BaseN12
,
m
.
BaseN13
,
m
.
BaseN14
,
m
.
BaseN15
,
m
.
BaseN16
):
class
MIMany916
(
m
.
BaseN9
,
m
.
BaseN10
,
m
.
BaseN11
,
m
.
BaseN12
,
m
.
BaseN13
,
m
.
BaseN14
,
m
.
BaseN15
,
m
.
BaseN16
,
):
def
__init__
(
self
):
m
.
BaseN9
.
__init__
(
self
,
9
)
m
.
BaseN10
.
__init__
(
self
,
10
)
...
...
@@ -225,7 +231,6 @@ def test_multiple_inheritance_python_many_bases():
def
test_multiple_inheritance_virtbase
():
class
MITypePy
(
m
.
Base12a
):
def
__init__
(
self
,
i
,
j
):
m
.
Base12a
.
__init__
(
self
,
i
,
j
)
...
...
@@ -238,7 +243,7 @@ def test_multiple_inheritance_virtbase():
def
test_mi_static_properties
():
"""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
()):
assert
d
.
vanilla
()
==
"Vanilla"
...
...
tests/test_numpy_array.py
View file @
c50f90ec
...
...
@@ -19,33 +19,36 @@ def test_dtypes():
print
(
check
)
assert
check
.
numpy
==
check
.
pybind11
,
check
if
check
.
numpy
.
num
!=
check
.
pybind11
.
num
:
print
(
"NOTE: typenum mismatch for {}: {} != {}"
.
format
(
check
,
check
.
numpy
.
num
,
check
.
pybind11
.
num
))
print
(
"NOTE: typenum mismatch for {}: {} != {}"
.
format
(
check
,
check
.
numpy
.
num
,
check
.
pybind11
.
num
)
)
@
pytest
.
fixture
(
scope
=
'
function
'
)
@
pytest
.
fixture
(
scope
=
"
function
"
)
def
arr
():
return
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
'
=u2
'
)
return
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
"
=u2
"
)
def
test_array_attributes
():
a
=
np
.
array
(
0
,
'
f8
'
)
a
=
np
.
array
(
0
,
"
f8
"
)
assert
m
.
ndim
(
a
)
==
0
assert
all
(
m
.
shape
(
a
)
==
[])
assert
all
(
m
.
strides
(
a
)
==
[])
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
m
.
shape
(
a
,
0
)
assert
str
(
excinfo
.
value
)
==
'
invalid axis: 0 (ndim = 0)
'
assert
str
(
excinfo
.
value
)
==
"
invalid axis: 0 (ndim = 0)
"
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
m
.
strides
(
a
,
0
)
assert
str
(
excinfo
.
value
)
==
'
invalid axis: 0 (ndim = 0)
'
assert
str
(
excinfo
.
value
)
==
"
invalid axis: 0 (ndim = 0)
"
assert
m
.
writeable
(
a
)
assert
m
.
size
(
a
)
==
1
assert
m
.
itemsize
(
a
)
==
8
assert
m
.
nbytes
(
a
)
==
8
assert
m
.
owndata
(
a
)
a
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
'
u2
'
).
view
()
a
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
"
u2
"
).
view
()
a
.
flags
.
writeable
=
False
assert
m
.
ndim
(
a
)
==
2
assert
all
(
m
.
shape
(
a
)
==
[
2
,
3
])
...
...
@@ -56,10 +59,10 @@ def test_array_attributes():
assert
m
.
strides
(
a
,
1
)
==
2
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
m
.
shape
(
a
,
2
)
assert
str
(
excinfo
.
value
)
==
'
invalid axis: 2 (ndim = 2)
'
assert
str
(
excinfo
.
value
)
==
"
invalid axis: 2 (ndim = 2)
"
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
m
.
strides
(
a
,
2
)
assert
str
(
excinfo
.
value
)
==
'
invalid axis: 2 (ndim = 2)
'
assert
str
(
excinfo
.
value
)
==
"
invalid axis: 2 (ndim = 2)
"
assert
not
m
.
writeable
(
a
)
assert
m
.
size
(
a
)
==
6
assert
m
.
itemsize
(
a
)
==
2
...
...
@@ -67,7 +70,9 @@ def test_array_attributes():
assert
not
m
.
owndata
(
a
)
@
pytest
.
mark
.
parametrize
(
'args, ret'
,
[([],
0
),
([
0
],
0
),
([
1
],
3
),
([
0
,
1
],
1
),
([
1
,
2
],
5
)])
@
pytest
.
mark
.
parametrize
(
"args, ret"
,
[([],
0
),
([
0
],
0
),
([
1
],
3
),
([
0
,
1
],
1
),
([
1
,
2
],
5
)]
)
def
test_index_offset
(
arr
,
args
,
ret
):
assert
m
.
index_at
(
arr
,
*
args
)
==
ret
assert
m
.
index_at_t
(
arr
,
*
args
)
==
ret
...
...
@@ -76,31 +81,46 @@ def test_index_offset(arr, args, ret):
def
test_dim_check_fail
(
arr
):
for
func
in
(
m
.
index_at
,
m
.
index_at_t
,
m
.
offset_at
,
m
.
offset_at_t
,
m
.
data
,
m
.
data_t
,
m
.
mutate_data
,
m
.
mutate_data_t
):
for
func
in
(
m
.
index_at
,
m
.
index_at_t
,
m
.
offset_at
,
m
.
offset_at_t
,
m
.
data
,
m
.
data_t
,
m
.
mutate_data
,
m
.
mutate_data_t
,
):
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
func
(
arr
,
1
,
2
,
3
)
assert
str
(
excinfo
.
value
)
==
'
too many indices for an array: 3 (ndim = 2)
'
assert
str
(
excinfo
.
value
)
==
"
too many indices for an array: 3 (ndim = 2)
"
@
pytest
.
mark
.
parametrize
(
'args, ret'
,
[([],
[
1
,
2
,
3
,
4
,
5
,
6
]),
([
1
],
[
4
,
5
,
6
]),
([
0
,
1
],
[
2
,
3
,
4
,
5
,
6
]),
([
1
,
2
],
[
6
])])
@
pytest
.
mark
.
parametrize
(
"args, ret"
,
[
([],
[
1
,
2
,
3
,
4
,
5
,
6
]),
([
1
],
[
4
,
5
,
6
]),
([
0
,
1
],
[
2
,
3
,
4
,
5
,
6
]),
([
1
,
2
],
[
6
]),
],
)
def
test_data
(
arr
,
args
,
ret
):
from
sys
import
byteorder
assert
all
(
m
.
data_t
(
arr
,
*
args
)
==
ret
)
assert
all
(
m
.
data
(
arr
,
*
args
)[(
0
if
byteorder
==
'
little
'
else
1
)::
2
]
==
ret
)
assert
all
(
m
.
data
(
arr
,
*
args
)[(
1
if
byteorder
==
'
little
'
else
0
)::
2
]
==
0
)
assert
all
(
m
.
data
(
arr
,
*
args
)[(
0
if
byteorder
==
"
little
"
else
1
)
::
2
]
==
ret
)
assert
all
(
m
.
data
(
arr
,
*
args
)[(
1
if
byteorder
==
"
little
"
else
0
)
::
2
]
==
0
)
@
pytest
.
mark
.
parametrize
(
'
dim
'
,
[
0
,
1
,
3
])
@
pytest
.
mark
.
parametrize
(
"
dim
"
,
[
0
,
1
,
3
])
def
test_at_fail
(
arr
,
dim
):
for
func
in
m
.
at_t
,
m
.
mutate_at_t
:
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
func
(
arr
,
*
([
0
]
*
dim
))
assert
str
(
excinfo
.
value
)
==
'index dimension mismatch: {} (ndim = 2)'
.
format
(
dim
)
assert
str
(
excinfo
.
value
)
==
"index dimension mismatch: {} (ndim = 2)"
.
format
(
dim
)
def
test_at
(
arr
):
...
...
@@ -113,10 +133,14 @@ def test_at(arr):
def
test_mutate_readonly
(
arr
):
arr
.
flags
.
writeable
=
False
for
func
,
args
in
(
m
.
mutate_data
,
()),
(
m
.
mutate_data_t
,
()),
(
m
.
mutate_at_t
,
(
0
,
0
)):
for
func
,
args
in
(
(
m
.
mutate_data
,
()),
(
m
.
mutate_data_t
,
()),
(
m
.
mutate_at_t
,
(
0
,
0
)),
):
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
func
(
arr
,
*
args
)
assert
str
(
excinfo
.
value
)
==
'
array is not writeable
'
assert
str
(
excinfo
.
value
)
==
"
array is not writeable
"
def
test_mutate_data
(
arr
):
...
...
@@ -134,14 +158,22 @@ def test_mutate_data(arr):
def
test_bounds_check
(
arr
):
for
func
in
(
m
.
index_at
,
m
.
index_at_t
,
m
.
data
,
m
.
data_t
,
m
.
mutate_data
,
m
.
mutate_data_t
,
m
.
at_t
,
m
.
mutate_at_t
):
for
func
in
(
m
.
index_at
,
m
.
index_at_t
,
m
.
data
,
m
.
data_t
,
m
.
mutate_data
,
m
.
mutate_data_t
,
m
.
at_t
,
m
.
mutate_at_t
,
):
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
func
(
arr
,
2
,
0
)
assert
str
(
excinfo
.
value
)
==
'
index 2 is out of bounds for axis 0 with size 2
'
assert
str
(
excinfo
.
value
)
==
"
index 2 is out of bounds for axis 0 with size 2
"
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
func
(
arr
,
0
,
4
)
assert
str
(
excinfo
.
value
)
==
'
index 4 is out of bounds for axis 1 with size 3
'
assert
str
(
excinfo
.
value
)
==
"
index 4 is out of bounds for axis 1 with size 3
"
def
test_make_c_f_array
():
...
...
@@ -163,10 +195,11 @@ def test_make_empty_shaped_array():
def
test_wrap
():
def
assert_references
(
a
,
b
,
base
=
None
):
from
distutils.version
import
LooseVersion
if
base
is
None
:
base
=
a
assert
a
is
not
b
assert
a
.
__array_interface__
[
'
data
'
][
0
]
==
b
.
__array_interface__
[
'
data
'
][
0
]
assert
a
.
__array_interface__
[
"
data
"
][
0
]
==
b
.
__array_interface__
[
"
data
"
][
0
]
assert
a
.
shape
==
b
.
shape
assert
a
.
strides
==
b
.
strides
assert
a
.
flags
.
c_contiguous
==
b
.
flags
.
c_contiguous
...
...
@@ -189,12 +222,12 @@ def test_wrap():
a2
=
m
.
wrap
(
a1
)
assert_references
(
a1
,
a2
)
a1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
np
.
float32
,
order
=
'F'
)
a1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
np
.
float32
,
order
=
"F"
)
assert
a1
.
flags
.
owndata
and
a1
.
base
is
None
a2
=
m
.
wrap
(
a1
)
assert_references
(
a1
,
a2
)
a1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
np
.
float32
,
order
=
'C'
)
a1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
np
.
float32
,
order
=
"C"
)
a1
.
flags
.
writeable
=
False
a2
=
m
.
wrap
(
a1
)
assert_references
(
a1
,
a2
)
...
...
@@ -224,11 +257,14 @@ def test_numpy_view(capture):
assert
np
.
all
(
ac_view_1
==
np
.
array
([
1
,
2
],
dtype
=
np
.
int32
))
del
ac
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
ArrayClass()
ArrayClass::numpy_view()
ArrayClass::numpy_view()
"""
)
ac_view_1
[
0
]
=
4
ac_view_1
[
1
]
=
3
assert
ac_view_2
[
0
]
==
4
...
...
@@ -238,9 +274,12 @@ def test_numpy_view(capture):
del
ac_view_2
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
~ArrayClass()
"""
)
def
test_cast_numpy_int64_to_uint64
():
...
...
@@ -271,20 +310,22 @@ def test_constructors():
def
test_overload_resolution
(
msg
):
# Exact overload matches:
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'
float64
'
))
==
'
double
'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'
float32
'
))
==
'
float
'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'
ushort
'
))
==
'
unsigned short
'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'
intc
'
))
==
'
int
'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'
longlong
'
))
==
'
long long
'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'
complex
'
))
==
'
double complex
'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'
csingle
'
))
==
'
float complex
'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"
float64
"
))
==
"
double
"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"
float32
"
))
==
"
float
"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"
ushort
"
))
==
"
unsigned short
"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"
intc
"
))
==
"
int
"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"
longlong
"
))
==
"
long long
"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"
complex
"
))
==
"
double complex
"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"
csingle
"
))
==
"
float complex
"
# No exact match, should call first convertible version:
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'
uint8
'
))
==
'
double
'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"
uint8
"
))
==
"
double
"
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
overloaded
(
"not an array"
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
overloaded(): incompatible function arguments. The following argument types are supported:
1. (arg0: numpy.ndarray[numpy.float64]) -> str
2. (arg0: numpy.ndarray[numpy.float32]) -> str
...
...
@@ -296,15 +337,16 @@ def test_overload_resolution(msg):
Invoked with: 'not an array'
"""
)
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
'
float64
'
))
==
'
double
'
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
'
float32
'
))
==
'
float
'
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
'
complex64
'
))
==
'
float complex
'
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
'
complex128
'
))
==
'
double complex
'
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
'
float32
'
))
==
'
float
'
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
"
float64
"
))
==
"
double
"
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
"
float32
"
))
==
"
float
"
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
"
complex64
"
))
==
"
float complex
"
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
"
complex128
"
))
==
"
double complex
"
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
"
float32
"
))
==
"
float
"
assert
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
'
float64
'
))
==
'
double
'
assert
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
'
intc
'
))
==
'
int
'
assert
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
"
float64
"
))
==
"
double
"
assert
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
"
intc
"
))
==
"
int
"
expected_exc
=
"""
overloaded3(): incompatible function arguments. The following argument types are supported:
1. (arg0: numpy.ndarray[numpy.int32]) -> str
...
...
@@ -313,47 +355,49 @@ def test_overload_resolution(msg):
Invoked with: """
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
'
uintc
'
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1
],
dtype
=
'
uint32
'
))
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
"
uintc
"
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1
],
dtype
=
"
uint32
"
))
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
'
float32
'
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1.
],
dtype
=
'
float32
'
))
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
"
float32
"
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1.
0
],
dtype
=
"
float32
"
))
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
'
complex
'
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1.
+
0.j
]))
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
"
complex
"
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1.
0
+
0.
0
j
]))
# Exact matches:
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
'
double
'
))
==
'
double
'
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
'
longlong
'
))
==
'
long long
'
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
"
double
"
))
==
"
double
"
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
"
longlong
"
))
==
"
long long
"
# Non-exact matches requiring conversion. Since float to integer isn't a
# save conversion, it should go to the double overload, but short can go to
# either (and so should end up on the first-registered, the long long).
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
'
float32
'
))
==
'
double
'
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
'
short
'
))
==
'
long long
'
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
"
float32
"
))
==
"
double
"
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
"
short
"
))
==
"
long long
"
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
'
double
'
))
==
'
double
'
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
'
uintc
'
))
==
'
unsigned int
'
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
'
float32
'
))
==
'
unsigned int
'
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
"
double
"
))
==
"
double
"
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
"
uintc
"
))
==
"
unsigned int
"
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
"
float32
"
))
==
"
unsigned int
"
def
test_greedy_string_overload
():
"""Tests fix for #685 - ndarray shouldn't go to std::string overload"""
assert
m
.
issue685
(
"abc"
)
==
"string"
assert
m
.
issue685
(
np
.
array
([
97
,
98
,
99
],
dtype
=
'b'
))
==
"array"
assert
m
.
issue685
(
np
.
array
([
97
,
98
,
99
],
dtype
=
"b"
))
==
"array"
assert
m
.
issue685
(
123
)
==
"other"
def
test_array_unchecked_fixed_dims
(
msg
):
z1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
'
float64
'
)
z1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
"
float64
"
)
m
.
proxy_add2
(
z1
,
10
)
assert
np
.
all
(
z1
==
[[
11
,
12
],
[
13
,
14
]])
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
proxy_add2
(
np
.
array
([
1.
,
2
,
3
]),
5.0
)
assert
msg
(
excinfo
.
value
)
==
"array has incorrect number of dimensions: 1; expected 2"
m
.
proxy_add2
(
np
.
array
([
1.0
,
2
,
3
]),
5.0
)
assert
(
msg
(
excinfo
.
value
)
==
"array has incorrect number of dimensions: 1; expected 2"
)
expect_c
=
np
.
ndarray
(
shape
=
(
3
,
3
,
3
),
buffer
=
np
.
array
(
range
(
3
,
30
)),
dtype
=
'
int
'
)
expect_c
=
np
.
ndarray
(
shape
=
(
3
,
3
,
3
),
buffer
=
np
.
array
(
range
(
3
,
30
)),
dtype
=
"
int
"
)
assert
np
.
all
(
m
.
proxy_init3
(
3.0
)
==
expect_c
)
expect_f
=
np
.
transpose
(
expect_c
)
assert
np
.
all
(
m
.
proxy_init3F
(
3.0
)
==
expect_f
)
...
...
@@ -369,11 +413,11 @@ def test_array_unchecked_fixed_dims(msg):
def
test_array_unchecked_dyn_dims
(
msg
):
z1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
'
float64
'
)
z1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
"
float64
"
)
m
.
proxy_add2_dyn
(
z1
,
10
)
assert
np
.
all
(
z1
==
[[
11
,
12
],
[
13
,
14
]])
expect_c
=
np
.
ndarray
(
shape
=
(
3
,
3
,
3
),
buffer
=
np
.
array
(
range
(
3
,
30
)),
dtype
=
'
int
'
)
expect_c
=
np
.
ndarray
(
shape
=
(
3
,
3
,
3
),
buffer
=
np
.
array
(
range
(
3
,
30
)),
dtype
=
"
int
"
)
assert
np
.
all
(
m
.
proxy_init3_dyn
(
3.0
)
==
expect_c
)
assert
m
.
proxy_auxiliaries2_dyn
(
z1
)
==
[
11
,
11
,
True
,
2
,
8
,
2
,
2
,
4
,
32
]
...
...
@@ -383,15 +427,15 @@ def test_array_unchecked_dyn_dims(msg):
def
test_array_failure
():
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
array_fail_test
()
assert
str
(
excinfo
.
value
)
==
'
cannot create a pybind11::array from a nullptr
'
assert
str
(
excinfo
.
value
)
==
"
cannot create a pybind11::array from a nullptr
"
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
array_t_fail_test
()
assert
str
(
excinfo
.
value
)
==
'
cannot create a pybind11::array_t from a nullptr
'
assert
str
(
excinfo
.
value
)
==
"
cannot create a pybind11::array_t from a nullptr
"
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
array_fail_test_negative_size
()
assert
str
(
excinfo
.
value
)
==
'
negative dimensions are not allowed
'
assert
str
(
excinfo
.
value
)
==
"
negative dimensions are not allowed
"
def
test_initializer_list
():
...
...
@@ -402,35 +446,35 @@ def test_initializer_list():
def
test_array_resize
(
msg
):
a
=
np
.
array
([
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
],
dtype
=
'
float64
'
)
a
=
np
.
array
([
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
],
dtype
=
"
float64
"
)
m
.
array_reshape2
(
a
)
assert
(
a
.
size
==
9
)
assert
(
np
.
all
(
a
==
[[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]])
)
assert
a
.
size
==
9
assert
np
.
all
(
a
==
[[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]])
# total size change should succced with refcheck off
m
.
array_resize3
(
a
,
4
,
False
)
assert
(
a
.
size
==
64
)
assert
a
.
size
==
64
# ... and fail with refcheck on
try
:
m
.
array_resize3
(
a
,
3
,
True
)
except
ValueError
as
e
:
assert
(
str
(
e
).
startswith
(
"cannot resize an array"
)
)
assert
str
(
e
).
startswith
(
"cannot resize an array"
)
# transposed array doesn't own data
b
=
a
.
transpose
()
try
:
m
.
array_resize3
(
b
,
3
,
False
)
except
ValueError
as
e
:
assert
(
str
(
e
).
startswith
(
"cannot resize this array: it does not own its data"
)
)
assert
str
(
e
).
startswith
(
"cannot resize this array: it does not own its data"
)
# ... but reshape should be fine
m
.
array_reshape2
(
b
)
assert
(
b
.
shape
==
(
8
,
8
)
)
assert
b
.
shape
==
(
8
,
8
)
@
pytest
.
mark
.
xfail
(
"env.PYPY"
)
def
test_array_create_and_resize
(
msg
):
a
=
m
.
create_and_resize
(
2
)
assert
(
a
.
size
==
4
)
assert
(
np
.
all
(
a
==
42.
)
)
assert
a
.
size
==
4
assert
np
.
all
(
a
==
42.
0
)
def
test_index_using_ellipsis
():
...
...
@@ -439,16 +483,16 @@ def test_index_using_ellipsis():
@
pytest
.
mark
.
parametrize
(
"forcecast"
,
[
False
,
True
])
@
pytest
.
mark
.
parametrize
(
"contiguity"
,
[
None
,
'C'
,
'F'
])
@
pytest
.
mark
.
parametrize
(
"contiguity"
,
[
None
,
"C"
,
"F"
])
@
pytest
.
mark
.
parametrize
(
"noconvert"
,
[
False
,
True
])
@
pytest
.
mark
.
filterwarnings
(
"ignore:Casting complex values to real discards the imaginary part:numpy.ComplexWarning"
)
def
test_argument_conversions
(
forcecast
,
contiguity
,
noconvert
):
function_name
=
"accept_double"
if
contiguity
==
'C'
:
if
contiguity
==
"C"
:
function_name
+=
"_c_style"
elif
contiguity
==
'F'
:
elif
contiguity
==
"F"
:
function_name
+=
"_f_style"
if
forcecast
:
function_name
+=
"_forcecast"
...
...
@@ -456,37 +500,39 @@ def test_argument_conversions(forcecast, contiguity, noconvert):
function_name
+=
"_noconvert"
function
=
getattr
(
m
,
function_name
)
for
dtype
in
[
np
.
dtype
(
'
float32
'
),
np
.
dtype
(
'
float64
'
),
np
.
dtype
(
'
complex128
'
)]:
for
order
in
[
'C'
,
'F'
]:
for
dtype
in
[
np
.
dtype
(
"
float32
"
),
np
.
dtype
(
"
float64
"
),
np
.
dtype
(
"
complex128
"
)]:
for
order
in
[
"C"
,
"F"
]:
for
shape
in
[(
2
,
2
),
(
1
,
3
,
1
,
1
),
(
1
,
1
,
1
),
(
0
,)]:
if
not
noconvert
:
# If noconvert is not passed, only complex128 needs to be truncated and
# "cannot be safely obtained". So without `forcecast`, the argument shouldn't
# be accepted.
should_raise
=
dtype
.
name
==
'
complex128
'
and
not
forcecast
should_raise
=
dtype
.
name
==
"
complex128
"
and
not
forcecast
else
:
# If noconvert is passed, only float64 and the matching order is accepted.
# If at most one dimension has a size greater than 1, the array is also
# trivially contiguous.
trivially_contiguous
=
sum
(
1
for
d
in
shape
if
d
>
1
)
<=
1
should_raise
=
(
dtype
.
name
!=
'float64'
or
(
contiguity
is
not
None
and
contiguity
!=
order
and
not
trivially_contiguous
)
should_raise
=
dtype
.
name
!=
"float64"
or
(
contiguity
is
not
None
and
contiguity
!=
order
and
not
trivially_contiguous
)
array
=
np
.
zeros
(
shape
,
dtype
=
dtype
,
order
=
order
)
if
not
should_raise
:
function
(
array
)
else
:
with
pytest
.
raises
(
TypeError
,
match
=
"incompatible function arguments"
):
with
pytest
.
raises
(
TypeError
,
match
=
"incompatible function arguments"
):
function
(
array
)
@
pytest
.
mark
.
xfail
(
"env.PYPY"
)
def
test_dtype_refcount_leak
():
from
sys
import
getrefcount
dtype
=
np
.
dtype
(
np
.
float_
)
a
=
np
.
array
([
1
],
dtype
=
dtype
)
before
=
getrefcount
(
dtype
)
...
...
tests/test_numpy_dtypes.py
View file @
c50f90ec
...
...
@@ -10,57 +10,71 @@ from pybind11_tests import numpy_dtypes as m
np
=
pytest
.
importorskip
(
"numpy"
)
@
pytest
.
fixture
(
scope
=
'
module
'
)
@
pytest
.
fixture
(
scope
=
"
module
"
)
def
simple_dtype
():
ld
=
np
.
dtype
(
'longdouble'
)
return
np
.
dtype
({
'names'
:
[
'bool_'
,
'uint_'
,
'float_'
,
'ldbl_'
],
'formats'
:
[
'?'
,
'u4'
,
'f4'
,
'f{}'
.
format
(
ld
.
itemsize
)],
'offsets'
:
[
0
,
4
,
8
,
(
16
if
ld
.
alignment
>
4
else
12
)]})
ld
=
np
.
dtype
(
"longdouble"
)
return
np
.
dtype
(
{
"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
():
return
np
.
dtype
([(
'
bool_
'
,
'?'
),
(
'
uint_
'
,
'
u4
'
),
(
'
float_
'
,
'
f4
'
),
(
'
ldbl_
'
,
'g'
)])
return
np
.
dtype
([(
"
bool_
"
,
"?"
),
(
"
uint_
"
,
"
u4
"
),
(
"
float_
"
,
"
f4
"
),
(
"
ldbl_
"
,
"g"
)])
def
dt_fmt
():
from
sys
import
byteorder
e
=
'<'
if
byteorder
==
'little'
else
'>'
return
(
"{{'names':['bool_','uint_','float_','ldbl_'],"
" 'formats':['?','"
+
e
+
"u4','"
+
e
+
"f4','"
+
e
+
"f{}'],"
" 'offsets':[0,4,8,{}], 'itemsize':{}}}"
)
e
=
"<"
if
byteorder
==
"little"
else
">"
return
(
"{{'names':['bool_','uint_','float_','ldbl_'],"
" 'formats':['?','"
+
e
+
"u4','"
+
e
+
"f4','"
+
e
+
"f{}'],"
" 'offsets':[0,4,8,{}], 'itemsize':{}}}"
)
def
simple_dtype_fmt
():
ld
=
np
.
dtype
(
'
longdouble
'
)
ld
=
np
.
dtype
(
"
longdouble
"
)
simple_ld_off
=
12
+
4
*
(
ld
.
alignment
>
4
)
return
dt_fmt
().
format
(
ld
.
itemsize
,
simple_ld_off
,
simple_ld_off
+
ld
.
itemsize
)
def
packed_dtype_fmt
():
from
sys
import
byteorder
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
():
return
12
+
4
*
(
np
.
dtype
(
'uint64'
).
alignment
>
4
)
+
8
+
8
*
(
np
.
dtype
(
'longdouble'
).
alignment
>
8
)
return
(
12
+
4
*
(
np
.
dtype
(
"uint64"
).
alignment
>
4
)
+
8
+
8
*
(
np
.
dtype
(
"longdouble"
).
alignment
>
8
)
)
def
partial_dtype_fmt
():
ld
=
np
.
dtype
(
'
longdouble
'
)
ld
=
np
.
dtype
(
"
longdouble
"
)
partial_ld_off
=
partial_ld_offset
()
return
dt_fmt
().
format
(
ld
.
itemsize
,
partial_ld_off
,
partial_ld_off
+
ld
.
itemsize
)
def
partial_nested_fmt
():
ld
=
np
.
dtype
(
'
longdouble
'
)
ld
=
np
.
dtype
(
"
longdouble
"
)
partial_nested_off
=
8
+
8
*
(
ld
.
alignment
>
8
)
partial_ld_off
=
partial_ld_offset
()
partial_nested_size
=
partial_nested_off
*
2
+
partial_ld_off
+
ld
.
itemsize
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
):
...
...
@@ -70,15 +84,19 @@ def assert_equal(actual, expected_data, expected_dtype):
def
test_format_descriptors
():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
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
'
)
ldbl_fmt
=
(
'
4x
'
if
ld
.
alignment
>
4
else
''
)
+
ld
.
char
ld
=
np
.
dtype
(
"
longdouble
"
)
ldbl_fmt
=
(
"
4x
"
if
ld
.
alignment
>
4
else
""
)
+
ld
.
char
ss_fmt
=
"^T{?:bool_:3xI:uint_:f:float_:"
+
ldbl_fmt
+
":ldbl_:}"
dbl
=
np
.
dtype
(
'double'
)
partial_fmt
=
(
"^T{?:bool_:3xI:uint_:f:float_:"
+
str
(
4
*
(
dbl
.
alignment
>
4
)
+
dbl
.
itemsize
+
8
*
(
ld
.
alignment
>
8
))
+
"xg:ldbl_:}"
)
dbl
=
np
.
dtype
(
"double"
)
partial_fmt
=
(
"^T{?:bool_:3xI:uint_:f:float_:"
+
str
(
4
*
(
dbl
.
alignment
>
4
)
+
dbl
.
itemsize
+
8
*
(
ld
.
alignment
>
8
))
+
"xg:ldbl_:}"
)
nested_extra
=
str
(
max
(
8
,
ld
.
alignment
))
assert
m
.
print_format_descriptors
()
==
[
ss_fmt
,
...
...
@@ -88,14 +106,15 @@ def test_format_descriptors():
"^T{"
+
nested_extra
+
"x"
+
partial_fmt
+
":a:"
+
nested_extra
+
"x}"
,
"^T{3s:a:3s:b:}"
,
"^T{(3)4s:a:(2)i:b:(3)B:c:1x(4, 2)f:d:}"
,
'
^T{q:e1:B:e2:}
'
,
'
^T{Zf:cflt:Zd:cdbl:}
'
"
^T{q:e1:B:e2:}
"
,
"
^T{Zf:cflt:Zd:cdbl:}
"
,
]
def
test_dtype
(
simple_dtype
):
from
sys
import
byteorder
e
=
'<'
if
byteorder
==
'little'
else
'>'
e
=
"<"
if
byteorder
==
"little"
else
">"
assert
m
.
print_dtypes
()
==
[
simple_dtype_fmt
(),
...
...
@@ -104,30 +123,60 @@ def test_dtype(simple_dtype):
partial_dtype_fmt
(),
partial_nested_fmt
(),
"[('a', 'S3'), ('b', 'S3')]"
,
(
"{{'names':['a','b','c','d'], "
+
"'formats':[('S4', (3,)),('"
+
e
+
"i4', (2,)),('u1', (3,)),('"
+
e
+
"f4', (4, 2))], "
+
"'offsets':[0,12,20,24], 'itemsize':56}}"
).
format
(
e
=
e
),
(
"{{'names':['a','b','c','d'], "
+
"'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')]"
,
"[('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'
],
'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
]
d1
=
np
.
dtype
(
{
"names"
:
[
"a"
,
"b"
],
"formats"
:
[
"int32"
,
"float64"
],
"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
,
np
.
dtype
(
'int32'
).
itemsize
,
simple_dtype
.
itemsize
]
assert
m
.
test_dtype_methods
()
==
[
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
):
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
)
assert
arr
.
dtype
==
dtype
assert_equal
(
arr
,
[],
simple_dtype
)
...
...
@@ -146,16 +195,16 @@ def test_recarray(simple_dtype, packed_dtype):
assert
m
.
print_rec_simple
(
arr
)
==
[
"s:0,0,0,-0"
,
"s:1,1,1.5,-2.5"
,
"s:0,2,3,-5"
"s:0,2,3,-5"
,
]
else
:
assert
m
.
print_rec_packed
(
arr
)
==
[
"p:0,0,0,-0"
,
"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
)
assert
arr
.
dtype
==
nested_dtype
...
...
@@ -163,33 +212,39 @@ def test_recarray(simple_dtype, packed_dtype):
arr
=
m
.
create_rec_nested
(
3
)
assert
arr
.
dtype
==
nested_dtype
assert_equal
(
arr
,
[((
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_equal
(
arr
,
[
((
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
)
==
[
"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: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
)
assert
str
(
arr
.
dtype
)
==
partial_dtype_fmt
()
partial_dtype
=
arr
.
dtype
assert
''
not
in
arr
.
dtype
.
fields
assert
""
not
in
arr
.
dtype
.
fields
assert
partial_dtype
.
itemsize
>
simple_dtype
.
itemsize
assert_equal
(
arr
,
elements
,
simple_dtype
)
assert_equal
(
arr
,
elements
,
packed_dtype
)
arr
=
m
.
create_rec_partial_nested
(
3
)
assert
str
(
arr
.
dtype
)
==
partial_nested_fmt
()
assert
''
not
in
arr
.
dtype
.
fields
assert
''
not
in
arr
.
dtype
.
fields
[
'a'
][
0
].
fields
assert
""
not
in
arr
.
dtype
.
fields
assert
""
not
in
arr
.
dtype
.
fields
[
"a"
][
0
].
fields
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
():
data
=
np
.
arange
(
1
,
7
,
dtype
=
'
int32
'
)
data
=
np
.
arange
(
1
,
7
,
dtype
=
"
int32
"
)
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
(
20
+
i
),
data
.
reshape
((
3
,
2
)))
...
...
@@ -205,82 +260,92 @@ def test_string_array():
"a='',b=''"
,
"a='a',b='a'"
,
"a='ab',b='ab'"
,
"a='abc',b='abc'"
"a='abc',b='abc'"
,
]
dtype
=
arr
.
dtype
assert
arr
[
'a'
].
tolist
()
==
[
b
''
,
b
'a'
,
b
'
ab
'
,
b
'
abc
'
]
assert
arr
[
'b'
].
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
"
]
arr
=
m
.
create_string_array
(
False
)
assert
dtype
==
arr
.
dtype
def
test_array_array
():
from
sys
import
byteorder
e
=
'<'
if
byteorder
==
'little'
else
'>'
e
=
"<"
if
byteorder
==
"little"
else
">"
arr
=
m
.
create_array_array
(
3
)
assert
str
(
arr
.
dtype
)
==
(
"{{'names':['a','b','c','d'], "
+
"'formats':[('S4', (3,)),('"
+
e
+
"i4', (2,)),('u1', (3,)),('{e}f4', (4, 2))], "
+
"'offsets':[0,12,20,24], 'itemsize':56}}"
).
format
(
e
=
e
)
"{{'names':['a','b','c','d'], "
+
"'formats':[('S4', (3,)),('"
+
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
)
==
[
"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}}"
,
"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}}"
,
"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}}"
,
"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}}"
,
"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}}"
,
"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}}"
,
]
assert
arr
[
'a'
].
tolist
()
==
[[
b
'ABCD'
,
b
'KLMN'
,
b
'UVWX'
],
[
b
'WXYZ'
,
b
'GHIJ'
,
b
'QRST'
],
[
b
'STUV'
,
b
'CDEF'
,
b
'MNOP'
]]
assert
arr
[
'b'
].
tolist
()
==
[[
0
,
1
],
[
1000
,
1001
],
[
2000
,
2001
]]
assert
arr
[
"a"
].
tolist
()
==
[
[
b
"ABCD"
,
b
"KLMN"
,
b
"UVWX"
],
[
b
"WXYZ"
,
b
"GHIJ"
,
b
"QRST"
],
[
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
def
test_enum_array
():
from
sys
import
byteorder
e
=
'<'
if
byteorder
==
'little'
else
'>'
e
=
"<"
if
byteorder
==
"little"
else
">"
arr
=
m
.
create_enum_array
(
3
)
dtype
=
arr
.
dtype
assert
dtype
==
np
.
dtype
([(
'e1'
,
e
+
'i8'
),
(
'e2'
,
'u1'
)])
assert
m
.
print_enum_array
(
arr
)
==
[
"e1=A,e2=X"
,
"e1=B,e2=Y"
,
"e1=A,e2=X"
]
assert
arr
[
'e1'
].
tolist
()
==
[
-
1
,
1
,
-
1
]
assert
arr
[
'e2'
].
tolist
()
==
[
1
,
2
,
1
]
assert
dtype
==
np
.
dtype
([(
"e1"
,
e
+
"i8"
),
(
"e2"
,
"u1"
)])
assert
m
.
print_enum_array
(
arr
)
==
[
"e1=A,e2=X"
,
"e1=B,e2=Y"
,
"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
def
test_complex_array
():
from
sys
import
byteorder
e
=
'<'
if
byteorder
==
'little'
else
'>'
e
=
"<"
if
byteorder
==
"little"
else
">"
arr
=
m
.
create_complex_array
(
3
)
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
)
==
[
"c:(0,0.25),(0.5,0.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
[
'
cdbl
'
].
tolist
()
==
[
0.5
+
0.75j
,
1.5
+
1.75j
,
2.5
+
2.75j
]
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
m
.
create_complex_array
(
0
).
dtype
==
dtype
def
test_signature
(
doc
):
assert
doc
(
m
.
create_rec_nested
)
==
\
"create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]"
assert
(
doc
(
m
.
create_rec_nested
)
==
"create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]"
)
def
test_scalar_conversion
():
n
=
3
arrays
=
[
m
.
create_rec_simple
(
n
),
m
.
create_rec_packed
(
n
),
m
.
create_rec_nested
(
n
),
m
.
create_enum_array
(
n
)]
arrays
=
[
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
]
for
i
,
func
in
enumerate
(
funcs
):
...
...
@@ -290,7 +355,7 @@ def test_scalar_conversion():
else
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
func
(
arr
[
0
])
assert
'
incompatible function arguments
'
in
str
(
excinfo
.
value
)
assert
"
incompatible function arguments
"
in
str
(
excinfo
.
value
)
def
test_vectorize
():
...
...
@@ -304,14 +369,14 @@ def test_vectorize():
def
test_cls_and_dtype_conversion
(
simple_dtype
):
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
()
s
.
uint_
=
2
assert
m
.
f_simple
(
s
)
==
20
# 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.
np
.
testing
.
assert_array_equal
(
m
.
f_simple_vectorized
(
s_recarray
),
[
20
])
...
...
@@ -327,17 +392,16 @@ def test_cls_and_dtype_conversion(simple_dtype):
assert
s_recarray_scalar
.
dtype
==
simple_dtype
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
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.
assert
m
.
f_simple
(
m
.
SimpleStruct
.
fromtuple
(
s_recarray_scalar
.
item
()))
==
20
assert
m
.
f_simple
(
m
.
SimpleStruct
.
fromtuple
(
s_recarray_scalar
.
item
()))
==
20
# Show that an array of dtype=object does *not* convert.
s_array_object
=
np
.
array
([
s
])
assert
s_array_object
.
dtype
==
object
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
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)`
s_array
=
np
.
array
([
s
.
astuple
()],
dtype
=
simple_dtype
)
np
.
testing
.
assert_array_equal
(
m
.
f_simple_vectorized
(
s_array
),
[
20
])
...
...
@@ -346,12 +410,13 @@ def test_cls_and_dtype_conversion(simple_dtype):
def
test_register_dtype
():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
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"
)
def
test_str_leak
():
from
sys
import
getrefcount
fmt
=
"f4"
pytest
.
gc_collect
()
start
=
getrefcount
(
fmt
)
...
...
tests/test_numpy_vectorize.py
View file @
c50f90ec
...
...
@@ -17,28 +17,40 @@ def test_vectorize(capture):
assert
capture
==
"my_func(x:int=1, y:float=2, z:float=3)"
with
capture
:
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=3, y:float=4, z:float=3)
"""
)
with
capture
:
a
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
order
=
'F'
)
b
=
np
.
array
([[
10
,
20
],
[
30
,
40
]],
order
=
'F'
)
a
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
order
=
"F"
)
b
=
np
.
array
([[
10
,
20
],
[
30
,
40
]],
order
=
"F"
)
c
=
3
result
=
f
(
a
,
b
,
c
)
assert
np
.
allclose
(
result
,
a
*
b
*
c
)
assert
result
.
flags
.
f_contiguous
# 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=3, y:float=30, 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)
"""
)
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
capture
==
"""
assert
(
capture
==
"""
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=5, y:float=6, z:float=3)
...
...
@@ -46,10 +58,13 @@ def test_vectorize(capture):
my_func(x:int=9, y:float=10, z:float=3)
my_func(x:int=11, y:float=12, z:float=3)
"""
)
with
capture
:
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
capture
==
"""
assert
(
capture
==
"""
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=3, y:float=4, z:float=2)
...
...
@@ -57,10 +72,13 @@ def test_vectorize(capture):
my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=6, y:float=4, z:float=2)
"""
)
with
capture
:
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
capture
==
"""
assert
(
capture
==
"""
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=3, y:float=2, z:float=2)
...
...
@@ -68,10 +86,17 @@ def test_vectorize(capture):
my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
"""
)
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
capture
==
"""
assert
(
capture
==
"""
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=3, y:float=2, z:float=2)
...
...
@@ -79,36 +104,53 @@ def test_vectorize(capture):
my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
"""
)
with
capture
:
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
capture
==
"""
assert
(
capture
==
"""
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=4, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
"""
)
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
capture
==
"""
assert
(
capture
==
"""
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=4, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
"""
)
def
test_type_selection
():
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.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
):
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
"""
# noqa: E501 line too long
)
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
(
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
(
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
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'
)
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
(
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
(
1
,
z2
,
z3
)
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
z1
,
1
,
z3
)
==
trivial
.
c_trivial
...
...
@@ -135,7 +185,7 @@ def test_trivial_broadcasting():
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
y1
=
np
.
array
(
z1
,
order
=
'F'
)
y1
=
np
.
array
(
z1
,
order
=
"F"
)
y2
=
np
.
array
(
y1
)
y3
=
np
.
array
(
y1
)
assert
vectorized_is_trivial
(
y1
,
y2
,
y3
)
==
trivial
.
f_trivial
...
...
@@ -156,30 +206,41 @@ def test_trivial_broadcasting():
def
test_passthrough_arguments
(
doc
):
assert
doc
(
m
.
vec_passthrough
)
==
(
"vec_passthrough("
+
", "
.
join
([
"arg0: float"
,
"arg1: numpy.ndarray[numpy.float64]"
,
"arg2: numpy.ndarray[numpy.float64]"
,
"arg3: numpy.ndarray[numpy.int32]"
,
"arg4: int"
,
"arg5: m.numpy_vectorize.NonPODClass"
,
"arg6: numpy.ndarray[numpy.float64]"
])
+
") -> object"
)
b
=
np
.
array
([[
10
,
20
,
30
]],
dtype
=
'float64'
)
"vec_passthrough("
+
", "
.
join
(
[
"arg0: float"
,
"arg1: numpy.ndarray[numpy.float64]"
,
"arg2: numpy.ndarray[numpy.float64]"
,
"arg3: numpy.ndarray[numpy.int32]"
,
"arg4: int"
,
"arg5: m.numpy_vectorize.NonPODClass"
,
"arg6: numpy.ndarray[numpy.float64]"
,
]
)
+
") -> object"
)
b
=
np
.
array
([[
10
,
20
,
30
]],
dtype
=
"float64"
)
c
=
np
.
array
([
100
,
200
])
# NOT a vectorized argument
d
=
np
.
array
([[
1000
],
[
2000
],
[
3000
]],
dtype
=
'
int
'
)
g
=
np
.
array
([[
1000000
,
2000000
,
3000000
]],
dtype
=
'
int
'
)
# requires casting
d
=
np
.
array
([[
1000
],
[
2000
],
[
3000
]],
dtype
=
"
int
"
)
g
=
np
.
array
([[
1000000
,
2000000
,
3000000
]],
dtype
=
"
int
"
)
# requires casting
assert
np
.
all
(
m
.
vec_passthrough
(
1
,
b
,
c
,
d
,
10000
,
m
.
NonPODClass
(
100000
),
g
)
==
np
.
array
([[
1111111
,
2111121
,
3111131
],
[
1112111
,
2112121
,
3112131
],
[
1113111
,
2113121
,
3113131
]]))
m
.
vec_passthrough
(
1
,
b
,
c
,
d
,
10000
,
m
.
NonPODClass
(
100000
),
g
)
==
np
.
array
(
[
[
1111111
,
2111121
,
3111131
],
[
1112111
,
2112121
,
3112131
],
[
1113111
,
2113121
,
3113131
],
]
)
)
def
test_method_vectorization
():
o
=
m
.
VectorizeTestClass
(
3
)
x
=
np
.
array
([
1
,
2
],
dtype
=
'
int
'
)
y
=
np
.
array
([[
10
],
[
20
]],
dtype
=
'
float32
'
)
x
=
np
.
array
([
1
,
2
],
dtype
=
"
int
"
)
y
=
np
.
array
([[
10
],
[
20
]],
dtype
=
"
float32
"
)
assert
np
.
all
(
o
.
method
(
x
,
y
)
==
[[
14
,
15
],
[
24
,
25
]])
...
...
@@ -188,7 +249,7 @@ def test_array_collapse():
assert
not
isinstance
(
m
.
vectorized_func
(
np
.
array
(
1
),
2
,
3
),
np
.
ndarray
)
z
=
m
.
vectorized_func
([
1
],
2
,
3
)
assert
isinstance
(
z
,
np
.
ndarray
)
assert
z
.
shape
==
(
1
,
)
assert
z
.
shape
==
(
1
,)
z
=
m
.
vectorized_func
(
1
,
[[[
2
]]],
3
)
assert
isinstance
(
z
,
np
.
ndarray
)
assert
z
.
shape
==
(
1
,
1
,
1
)
...
...
tests/test_opaque_types.py
View file @
c50f90ec
...
...
@@ -32,12 +32,15 @@ def test_pointers(msg):
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
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:
1. (arg0: capsule) -> int
Invoked with: [1, 2, 3]
"""
# noqa: E501 line too long
)
assert
m
.
return_null_str
()
is
None
assert
m
.
get_null_str_value
(
m
.
return_null_str
())
is
not
None
...
...
tests/test_operator_overloading.py
View file @
c50f90ec
...
...
@@ -56,23 +56,23 @@ def test_operator_overloading():
del
v3
assert
cstats
.
alive
()
==
0
assert
cstats
.
values
()
==
[
'
[1.000000, 2.000000]
'
,
'
[3.000000, -1.000000]
'
,
'
[1.000000, 2.000000]
'
,
'
[-3.000000, 1.000000]
'
,
'
[4.000000, 1.000000]
'
,
'
[-2.000000, 3.000000]
'
,
'
[-7.000000, -6.000000]
'
,
'
[9.000000, 10.000000]
'
,
'
[8.000000, 16.000000]
'
,
'
[0.125000, 0.250000]
'
,
'
[7.000000, 6.000000]
'
,
'
[9.000000, 10.000000]
'
,
'
[8.000000, 16.000000]
'
,
'
[8.000000, 4.000000]
'
,
'
[3.000000, -2.000000]
'
,
'
[3.000000, -0.500000]
'
,
'
[6.000000, -2.000000]
'
,
"
[1.000000, 2.000000]
"
,
"
[3.000000, -1.000000]
"
,
"
[1.000000, 2.000000]
"
,
"
[-3.000000, 1.000000]
"
,
"
[4.000000, 1.000000]
"
,
"
[-2.000000, 3.000000]
"
,
"
[-7.000000, -6.000000]
"
,
"
[9.000000, 10.000000]
"
,
"
[8.000000, 16.000000]
"
,
"
[0.125000, 0.250000]
"
,
"
[7.000000, 6.000000]
"
,
"
[9.000000, 10.000000]
"
,
"
[8.000000, 16.000000]
"
,
"
[8.000000, 4.000000]
"
,
"
[3.000000, -2.000000]
"
,
"
[3.000000, -0.500000]
"
,
"
[6.000000, -2.000000]
"
,
]
assert
cstats
.
default_constructions
==
0
assert
cstats
.
copy_constructions
==
0
...
...
tests/test_pickling.py
View file @
c50f90ec
...
...
@@ -42,5 +42,6 @@ def test_roundtrip_with_dict(cls_name):
def
test_enum_pickle
():
from
pybind11_tests
import
enums
as
e
data
=
pickle
.
dumps
(
e
.
EOne
,
2
)
assert
e
.
EOne
==
pickle
.
loads
(
data
)
tests/test_pytypes.py
View file @
c50f90ec
...
...
@@ -28,13 +28,16 @@ def test_list(capture, doc):
lst
.
append
(
"value2"
)
m
.
print_list
(
lst
)
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
Entry at position 0: value
list item 0: inserted-0
list item 1: overwritten
list item 2: inserted-2
list item 3: value2
"""
)
assert
doc
(
m
.
get_list
)
==
"get_list() -> list"
assert
doc
(
m
.
print_list
)
==
"print_list(arg0: list) -> None"
...
...
@@ -52,12 +55,15 @@ def test_set(capture, doc):
with
capture
:
s
.
add
(
"key4"
)
m
.
print_set
(
s
)
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
key: key1
key: key2
key: key3
key: key4
"""
)
assert
not
m
.
set_contains
(
set
([]),
42
)
assert
m
.
set_contains
({
42
},
42
)
...
...
@@ -74,10 +80,13 @@ def test_dict(capture, doc):
with
capture
:
d
[
"key2"
]
=
"value2"
m
.
print_dict
(
d
)
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
key: key, value=value
key: key2, value=value2
"""
)
assert
not
m
.
dict_contains
({},
42
)
assert
m
.
dict_contains
({
42
:
None
},
42
)
...
...
@@ -137,28 +146,37 @@ def test_capsule(capture):
a
=
m
.
return_capsule_with_destructor
()
del
a
pytest
.
gc_collect
()
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
creating capsule
destructing capsule
"""
)
with
capture
:
a
=
m
.
return_capsule_with_destructor_2
()
del
a
pytest
.
gc_collect
()
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
creating capsule
destructing capsule: 1234
"""
)
with
capture
:
a
=
m
.
return_capsule_with_name_and_destructor
()
del
a
pytest
.
gc_collect
()
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
created capsule (1234, 'pointer type description')
destructing capsule (1234, 'pointer type description')
"""
)
def
test_accessors
():
...
...
@@ -212,7 +230,7 @@ def test_constructors():
assert
m
.
default_constructors
()
==
expected
data
=
{
bytes
:
b
'
41
'
,
# Currently no supported or working conversions.
bytes
:
b
"
41
"
,
# Currently no supported or working conversions.
str
:
42
,
bool
:
"Not empty"
,
int
:
"42"
,
...
...
@@ -221,14 +239,14 @@ def test_constructors():
list
:
range
(
3
),
dict
:
[(
"two"
,
2
),
(
"one"
,
1
),
(
"three"
,
3
)],
set
:
[
4
,
4
,
5
,
6
,
6
,
6
],
memoryview
:
b
'
abc
'
memoryview
:
b
"
abc
"
,
}
inputs
=
{
k
.
__name__
:
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.
inputs
[
"bytes"
]
=
b
'
41
'
inputs
[
"bytes"
]
=
b
"
41
"
inputs
[
"str"
]
=
42
expected
[
"bytes"
]
=
b
'
41
'
expected
[
"bytes"
]
=
b
"
41
"
expected
[
"str"
]
=
u
"42"
assert
m
.
converting_constructors
(
inputs
)
==
expected
...
...
@@ -255,7 +273,8 @@ def test_non_converting_constructors():
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
nonconverting_constructor
(
t
,
v
)
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
...
...
@@ -263,12 +282,12 @@ def test_pybind11_str_raw_str():
# specifically to exercise pybind11::str::raw_str
cvt
=
m
.
convert_to_pybind11_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
(
False
)
==
u
"False"
assert
cvt
(
True
)
==
u
"True"
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
(())
==
u
"()"
assert
cvt
((
18
,))
==
u
"(18,)"
...
...
@@ -283,29 +302,40 @@ def test_pybind11_str_raw_str():
valid_utf8
=
valid_orig
.
encode
(
"utf-8"
)
valid_cvt
=
cvt
(
valid_utf8
)
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
)
assert
type
(
malformed_cvt
)
==
bytes
# Probably surprising.
assert
malformed_cvt
==
b
'
\x80
'
assert
malformed_cvt
==
b
"
\x80
"
def
test_implicit_casting
():
"""Tests implicit casting when assigning or appending to dicts and lists."""
z
=
m
.
get_implicit_casting
()
assert
z
[
'd'
]
==
{
'char*_i1'
:
'abc'
,
'char*_i2'
:
'abc'
,
'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
[
"d"
]
==
{
"char*_i1"
:
"abc"
,
"char*_i2"
:
"abc"
,
"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
):
with
capture
:
m
.
print_function
()
assert
capture
==
"""
assert
(
capture
==
"""
Hello, World!
1 2.0 three True -- multiple args
*args-and-a-custom-separator
...
...
@@ -313,14 +343,15 @@ def test_print(capture):
flush
py::print + str.format = this
"""
)
assert
capture
.
stderr
==
"this goes to stderr"
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
print_failure
()
assert
str
(
excinfo
.
value
)
==
"make_tuple(): unable to convert "
+
(
"argument of type 'UnregisteredType' to Python object"
if
debug_enabled
else
"arguments to Python object (compile in debug mode for details)"
if
debug_enabled
else
"arguments to Python object (compile in debug mode for details)"
)
...
...
@@ -342,8 +373,23 @@ def test_hash():
def
test_number_protocol
():
for
a
,
b
in
[(
1
,
1
),
(
3
,
5
)]:
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
]
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
,
]
assert
m
.
test_number_protocol
(
a
,
b
)
==
li
...
...
@@ -360,13 +406,16 @@ def test_issue2361():
assert
"'NoneType' object is not iterable"
in
str
(
excinfo
.
value
)
@
pytest
.
mark
.
parametrize
(
'method, args, fmt, expected_view'
,
[
(
m
.
test_memoryview_object
,
(
b
'red'
,),
'B'
,
b
'red'
),
(
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_from_buffer
,
(
True
,),
'H'
,
[
2
,
7
,
1
,
8
]),
(
m
.
test_memoryview_from_buffer_nativeformat
,
(),
'@i'
,
[
4
,
7
,
5
]),
])
@
pytest
.
mark
.
parametrize
(
"method, args, fmt, expected_view"
,
[
(
m
.
test_memoryview_object
,
(
b
"red"
,),
"B"
,
b
"red"
),
(
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_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
):
view
=
method
(
*
args
)
assert
isinstance
(
view
,
memoryview
)
...
...
@@ -380,12 +429,15 @@ def test_memoryview(method, args, fmt, expected_view):
@
pytest
.
mark
.
xfail
(
"env.PYPY"
,
reason
=
"getrefcount is not available"
)
@
pytest
.
mark
.
parametrize
(
'method'
,
[
m
.
test_memoryview_object
,
m
.
test_memoryview_buffer_info
,
])
@
pytest
.
mark
.
parametrize
(
"method"
,
[
m
.
test_memoryview_object
,
m
.
test_memoryview_buffer_info
,
],
)
def
test_memoryview_refcount
(
method
):
buf
=
b
'
\x0a\x0b\x0c\x0d
'
buf
=
b
"
\x0a\x0b\x0c\x0d
"
ref_before
=
sys
.
getrefcount
(
buf
)
view
=
method
(
buf
)
ref_after
=
sys
.
getrefcount
(
buf
)
...
...
@@ -396,13 +448,13 @@ def test_memoryview_refcount(method):
def
test_memoryview_from_buffer_empty_shape
():
view
=
m
.
test_memoryview_from_buffer_empty_shape
()
assert
isinstance
(
view
,
memoryview
)
assert
view
.
format
==
'B'
assert
view
.
format
==
"B"
if
env
.
PY2
:
# Python 2 behavior is weird, but Python 3 (the future) is fine.
# PyPy3 has <memoryview, while CPython 2 has <memory
assert
bytes
(
view
).
startswith
(
b
'
<memory
'
)
assert
bytes
(
view
).
startswith
(
b
"
<memory
"
)
else
:
assert
bytes
(
view
)
==
b
''
assert
bytes
(
view
)
==
b
""
def
test_test_memoryview_from_buffer_invalid_strides
():
...
...
@@ -422,13 +474,15 @@ def test_test_memoryview_from_buffer_nullptr():
def
test_memoryview_from_memory
():
view
=
m
.
test_memoryview_from_memory
()
assert
isinstance
(
view
,
memoryview
)
assert
view
.
format
==
'B'
assert
bytes
(
view
)
==
b
'
\xff\xe1\xab\x37
'
assert
view
.
format
==
"B"
assert
bytes
(
view
)
==
b
"
\xff\xe1\xab\x37
"
def
test_builtin_functions
():
assert
m
.
get_len
([
i
for
i
in
range
(
42
)])
==
42
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
m
.
get_len
(
i
for
i
in
range
(
42
))
assert
str
(
exc_info
.
value
)
in
[
"object of type 'generator' has no len()"
,
"'generator' has no length"
]
# PyPy
assert
str
(
exc_info
.
value
)
in
[
"object of type 'generator' has no len()"
,
"'generator' has no length"
,
]
# PyPy
tests/test_sequences_and_iterators.py
View file @
c50f90ec
...
...
@@ -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
):
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
():
...
...
@@ -51,7 +53,7 @@ def test_sequence():
cstats
=
ConstructorStats
.
get
(
m
.
Sequence
)
s
=
m
.
Sequence
(
5
)
assert
cstats
.
values
()
==
[
'
of size
'
,
'5'
]
assert
cstats
.
values
()
==
[
"
of size
"
,
"5"
]
assert
"Sequence"
in
repr
(
s
)
assert
len
(
s
)
==
5
...
...
@@ -62,16 +64,16 @@ def test_sequence():
assert
isclose
(
s
[
0
],
12.34
)
and
isclose
(
s
[
3
],
56.78
)
rev
=
reversed
(
s
)
assert
cstats
.
values
()
==
[
'
of size
'
,
'5'
]
assert
cstats
.
values
()
==
[
"
of size
"
,
"5"
]
rev2
=
s
[::
-
1
]
assert
cstats
.
values
()
==
[
'
of size
'
,
'5'
]
assert
cstats
.
values
()
==
[
"
of size
"
,
"5"
]
it
=
iter
(
m
.
Sequence
(
0
))
for
_
in
range
(
3
):
# __next__ must continue to raise StopIteration
with
pytest
.
raises
(
StopIteration
):
next
(
it
)
assert
cstats
.
values
()
==
[
'
of size
'
,
'0'
]
assert
cstats
.
values
()
==
[
"
of size
"
,
"0"
]
expected
=
[
0
,
56.78
,
0
,
0
,
12.34
]
assert
allclose
(
rev
,
expected
)
...
...
@@ -79,7 +81,7 @@ def test_sequence():
assert
rev
==
rev2
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
])
...
...
@@ -103,10 +105,11 @@ def test_sequence():
def
test_sequence_length
():
"""#2076: Exception raised by len(arg) should be propagated """
class
BadLen
(
RuntimeError
):
pass
class
SequenceLike
()
:
class
SequenceLike
:
def
__getitem__
(
self
,
i
):
return
None
...
...
@@ -121,17 +124,17 @@ def test_sequence_length():
def
test_map_iterator
():
sm
=
m
.
StringMap
({
'
hi
'
:
'
bye
'
,
'
black
'
:
'
white
'
})
assert
sm
[
'
hi
'
]
==
'
bye
'
sm
=
m
.
StringMap
({
"
hi
"
:
"
bye
"
,
"
black
"
:
"
white
"
})
assert
sm
[
"
hi
"
]
==
"
bye
"
assert
len
(
sm
)
==
2
assert
sm
[
'
black
'
]
==
'
white
'
assert
sm
[
"
black
"
]
==
"
white
"
with
pytest
.
raises
(
KeyError
):
assert
sm
[
'
orange
'
]
sm
[
'
orange
'
]
=
'
banana
'
assert
sm
[
'
orange
'
]
==
'
banana
'
assert
sm
[
"
orange
"
]
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
:
assert
sm
[
k
]
==
expected
[
k
]
for
k
,
v
in
sm
.
items
():
...
...
@@ -179,7 +182,8 @@ def test_iterator_passthrough():
"""#181: iterator passthrough did not compile"""
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
():
...
...
tests/test_smart_ptr.py
View file @
c50f90ec
...
...
@@ -7,7 +7,9 @@ from pybind11_tests import ConstructorStats # noqa: E402
def
test_smart_ptr
(
capture
):
# 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
with
capture
:
m
.
print_object_1
(
o
)
...
...
@@ -16,8 +18,9 @@ def test_smart_ptr(capture):
m
.
print_object_4
(
o
)
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
],
start
=
4
):
for
i
,
o
in
enumerate
(
[
m
.
make_myobject1_1
(),
m
.
make_myobject1_2
(),
m
.
MyObject1
(
6
),
7
],
start
=
4
):
print
(
o
)
with
capture
:
if
not
isinstance
(
o
,
int
):
...
...
@@ -29,11 +32,15 @@ def test_smart_ptr(capture):
m
.
print_myobject1_2
(
o
)
m
.
print_myobject1_3
(
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
)
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
.
default_constructions
==
0
assert
cstats
.
copy_constructions
==
0
...
...
@@ -42,7 +49,9 @@ def test_smart_ptr(capture):
assert
cstats
.
move_assignments
==
0
# 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
)
with
capture
:
m
.
print_myobject2_1
(
o
)
...
...
@@ -55,7 +64,7 @@ def test_smart_ptr(capture):
assert
cstats
.
alive
()
==
1
o
=
None
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
.
copy_constructions
==
0
# assert cstats.move_constructions >= 0 # Doesn't invoke any
...
...
@@ -63,7 +72,9 @@ def test_smart_ptr(capture):
assert
cstats
.
move_assignments
==
0
# 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
)
with
capture
:
m
.
print_myobject3_1
(
o
)
...
...
@@ -76,7 +87,7 @@ def test_smart_ptr(capture):
assert
cstats
.
alive
()
==
1
o
=
None
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
.
copy_constructions
==
0
# assert cstats.move_constructions >= 0 # Doesn't invoke any
...
...
@@ -96,7 +107,7 @@ def test_smart_ptr(capture):
# ref<>
cstats
=
m
.
cstats_ref
()
assert
cstats
.
alive
()
==
0
assert
cstats
.
values
()
==
[
'
from pointer
'
]
*
10
assert
cstats
.
values
()
==
[
"
from pointer
"
]
*
10
assert
cstats
.
default_constructions
==
30
assert
cstats
.
copy_constructions
==
12
# assert cstats.move_constructions >= 0 # Doesn't invoke any
...
...
@@ -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)
assert
stats
.
alive
()
==
2
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)
assert
stats
.
alive
()
==
2
...
...
@@ -200,12 +213,16 @@ def test_shared_ptr_from_this_and_references():
assert
s
.
set_ref
(
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
s
.
set_ref
(
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
s
.
set_ref
(
holder_copy
)
assert
s
.
set_holder
(
holder_copy
)
...
...
@@ -277,8 +294,10 @@ def test_smart_ptr_from_default():
instance
=
m
.
HeldByDefaultHolder
()
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
HeldByDefaultHolder
.
load_shared_ptr
(
instance
)
assert
"Unable to load a custom holder type from a "
\
"default-holder instance"
in
str
(
excinfo
.
value
)
assert
(
"Unable to load a custom holder type from a "
"default-holder instance"
in
str
(
excinfo
.
value
)
)
def
test_shared_ptr_gc
():
...
...
tests/test_stl.py
View file @
c50f90ec
...
...
@@ -88,7 +88,7 @@ def test_recursive_casting():
assert
m
.
cast_rv_nested
()
==
[[[{
"b"
:
"rvalue"
,
"c"
:
"rvalue"
}],
[{
"a"
:
"rvalue"
}]]]
assert
m
.
cast_lv_nested
()
==
{
"a"
:
[[[
"lvalue"
,
"lvalue"
]],
[[
"lvalue"
,
"lvalue"
]]],
"b"
:
[[[
"lvalue"
,
"lvalue"
],
[
"lvalue"
,
"lvalue"
]]]
"b"
:
[[[
"lvalue"
,
"lvalue"
],
[
"lvalue"
,
"lvalue"
]]]
,
}
# Issue #853 test case:
...
...
@@ -106,15 +106,15 @@ def test_move_out_container():
assert
[
x
.
value
for
x
in
moved_out_list
]
==
[
0
,
1
,
2
]
@
pytest
.
mark
.
skipif
(
not
hasattr
(
m
,
"has_optional"
),
reason
=
'
no <optional>
'
)
@
pytest
.
mark
.
skipif
(
not
hasattr
(
m
,
"has_optional"
),
reason
=
"
no <optional>
"
)
def
test_optional
():
assert
m
.
double_or_zero
(
None
)
==
0
assert
m
.
double_or_zero
(
42
)
==
84
pytest
.
raises
(
TypeError
,
m
.
double_or_zero
,
'
foo
'
)
pytest
.
raises
(
TypeError
,
m
.
double_or_zero
,
"
foo
"
)
assert
m
.
half_or_none
(
0
)
is
None
assert
m
.
half_or_none
(
42
)
==
21
pytest
.
raises
(
TypeError
,
m
.
half_or_none
,
'
foo
'
)
pytest
.
raises
(
TypeError
,
m
.
half_or_none
,
"
foo
"
)
assert
m
.
test_nullopt
()
==
42
assert
m
.
test_nullopt
(
None
)
==
42
...
...
@@ -134,15 +134,17 @@ def test_optional():
assert
holder
.
member_initialized
()
@
pytest
.
mark
.
skipif
(
not
hasattr
(
m
,
"has_exp_optional"
),
reason
=
'no <experimental/optional>'
)
@
pytest
.
mark
.
skipif
(
not
hasattr
(
m
,
"has_exp_optional"
),
reason
=
"no <experimental/optional>"
)
def
test_exp_optional
():
assert
m
.
double_or_zero_exp
(
None
)
==
0
assert
m
.
double_or_zero_exp
(
42
)
==
84
pytest
.
raises
(
TypeError
,
m
.
double_or_zero_exp
,
'
foo
'
)
pytest
.
raises
(
TypeError
,
m
.
double_or_zero_exp
,
"
foo
"
)
assert
m
.
half_or_none_exp
(
0
)
is
None
assert
m
.
half_or_none_exp
(
42
)
==
21
pytest
.
raises
(
TypeError
,
m
.
half_or_none_exp
,
'
foo
'
)
pytest
.
raises
(
TypeError
,
m
.
half_or_none_exp
,
"
foo
"
)
assert
m
.
test_nullopt_exp
()
==
42
assert
m
.
test_nullopt_exp
(
None
)
==
42
...
...
@@ -160,7 +162,7 @@ def test_exp_optional():
assert
holder
.
member_initialized
()
@
pytest
.
mark
.
skipif
(
not
hasattr
(
m
,
"load_variant"
),
reason
=
'
no <variant>
'
)
@
pytest
.
mark
.
skipif
(
not
hasattr
(
m
,
"load_variant"
),
reason
=
"
no <variant>
"
)
def
test_variant
(
doc
):
assert
m
.
load_variant
(
1
)
==
"int"
assert
m
.
load_variant
(
"1"
)
==
"std::string"
...
...
@@ -172,34 +174,44 @@ def test_variant(doc):
assert
m
.
cast_variant
()
==
(
5
,
"Hello"
)
assert
doc
(
m
.
load_variant
)
==
"load_variant(arg0: Union[int, str, float, None]) -> str"
assert
(
doc
(
m
.
load_variant
)
==
"load_variant(arg0: Union[int, str, float, None]) -> str"
)
def
test_vec_of_reference_wrapper
():
"""#171: Can't return reference wrappers (or STL structures containing them)"""
assert
str
(
m
.
return_vec_of_reference_wrapper
(
UserType
(
4
)))
==
\
"[UserType(1), UserType(2), UserType(3), UserType(4)]"
assert
(
str
(
m
.
return_vec_of_reference_wrapper
(
UserType
(
4
)))
==
"[UserType(1), UserType(2), UserType(3), UserType(4)]"
)
def
test_stl_pass_by_pointer
(
msg
):
"""Passing nullptr or None to an STL container pointer is not expected to work"""
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
stl_pass_by_pointer
()
# default value is `nullptr`
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
1. (v: List[int] = None) -> List[int]
Invoked with:
"""
# noqa: E501 line too long
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
stl_pass_by_pointer
(
None
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
1. (v: List[int] = None) -> List[int]
Invoked with: None
"""
# noqa: E501 line too long
)
assert
m
.
stl_pass_by_pointer
([
1
,
2
,
3
])
==
[
1
,
2
,
3
]
...
...
@@ -209,10 +221,12 @@ def test_missing_header_message():
<pybind11/stl.h> should result in a helpful suggestion in the error message"""
import
pybind11_cross_module_tests
as
cm
expected_message
=
(
"Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,
\n
"
"<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic
\n
"
"conversions are optional and require extra headers to be included
\n
"
"when compiling your pybind11 module."
)
expected_message
=
(
"Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,
\n
"
"<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic
\n
"
"conversions are optional and require extra headers to be included
\n
"
"when compiling your pybind11 module."
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
cm
.
missing_header_arg
([
1.0
,
2.0
,
3.0
])
...
...
@@ -226,9 +240,9 @@ def test_missing_header_message():
def
test_function_with_string_and_vector_string_arg
():
"""Check if a string is NOT implicitly converted to a list, which was the
behavior before fix of issue #1258"""
assert
m
.
func_with_string_or_vector_string_arg_overload
((
'A'
,
'B'
,
))
==
2
assert
m
.
func_with_string_or_vector_string_arg_overload
([
'A'
,
'B'
])
==
2
assert
m
.
func_with_string_or_vector_string_arg_overload
(
'A'
)
==
3
assert
m
.
func_with_string_or_vector_string_arg_overload
((
"A"
,
"B"
))
==
2
assert
m
.
func_with_string_or_vector_string_arg_overload
([
"A"
,
"B"
])
==
2
assert
m
.
func_with_string_or_vector_string_arg_overload
(
"A"
)
==
3
def
test_stl_ownership
():
...
...
@@ -247,6 +261,6 @@ def test_array_cast_sequence():
def
test_issue_1561
():
""" check fix for issue #1561 """
bar
=
m
.
Issue1561Outer
()
bar
.
list
=
[
m
.
Issue1561Inner
(
'
bar
'
)]
bar
.
list
=
[
m
.
Issue1561Inner
(
"
bar
"
)]
bar
.
list
assert
bar
.
list
[
0
].
data
==
'
bar
'
assert
bar
.
list
[
0
].
data
==
"
bar
"
tests/test_stl_binders.py
View file @
c50f90ec
...
...
@@ -45,7 +45,7 @@ def test_vector_int():
# test error handling, and that the vector is unchanged
with
pytest
.
raises
(
RuntimeError
):
v_int2
.
extend
([
8
,
'a'
])
v_int2
.
extend
([
8
,
"a"
])
assert
v_int2
==
m
.
VectorInt
([
0
,
99
,
2
,
3
,
4
,
5
,
6
,
7
])
...
...
@@ -79,8 +79,8 @@ def test_vector_buffer():
assert
mv
[
2
]
==
5
mv
[
2
]
=
6
else
:
assert
mv
[
2
]
==
'
\x05
'
mv
[
2
]
=
'
\x06
'
assert
mv
[
2
]
==
"
\x05
"
mv
[
2
]
=
"
\x06
"
assert
v
[
2
]
==
6
if
not
env
.
PY2
:
...
...
@@ -114,11 +114,17 @@ def test_vector_buffer_numpy():
v
=
m
.
get_vectorstruct
()
assert
v
[
0
].
x
==
5
ma
=
np
.
asarray
(
v
)
ma
[
1
][
'x'
]
=
99
ma
[
1
][
"x"
]
=
99
assert
v
[
1
].
x
==
99
v
=
m
.
VectorStruct
(
np
.
zeros
(
3
,
dtype
=
np
.
dtype
([(
'w'
,
'bool'
),
(
'x'
,
'I'
),
(
'y'
,
'float64'
),
(
'z'
,
'bool'
)],
align
=
True
)))
v
=
m
.
VectorStruct
(
np
.
zeros
(
3
,
dtype
=
np
.
dtype
(
[(
"w"
,
"bool"
),
(
"x"
,
"I"
),
(
"y"
,
"float64"
),
(
"z"
,
"bool"
)],
align
=
True
),
)
)
assert
len
(
v
)
==
3
b
=
np
.
array
([
1
,
2
,
3
,
4
],
dtype
=
np
.
uint8
)
...
...
@@ -151,31 +157,31 @@ def test_vector_custom():
def
test_map_string_double
():
mm
=
m
.
MapStringDouble
()
mm
[
'a'
]
=
1
mm
[
'b'
]
=
2.5
mm
[
"a"
]
=
1
mm
[
"b"
]
=
2.5
assert
list
(
mm
)
==
[
'a'
,
'b'
]
assert
list
(
mm
.
items
())
==
[(
'a'
,
1
),
(
'b'
,
2.5
)]
assert
list
(
mm
)
==
[
"a"
,
"b"
]
assert
list
(
mm
.
items
())
==
[(
"a"
,
1
),
(
"b"
,
2.5
)]
assert
str
(
mm
)
==
"MapStringDouble{a: 1, b: 2.5}"
um
=
m
.
UnorderedMapStringDouble
()
um
[
'
ua
'
]
=
1.1
um
[
'
ub
'
]
=
2.6
um
[
"
ua
"
]
=
1.1
um
[
"
ub
"
]
=
2.6
assert
sorted
(
list
(
um
))
==
[
'
ua
'
,
'
ub
'
]
assert
sorted
(
list
(
um
.
items
()))
==
[(
'
ua
'
,
1.1
),
(
'
ub
'
,
2.6
)]
assert
sorted
(
list
(
um
))
==
[
"
ua
"
,
"
ub
"
]
assert
sorted
(
list
(
um
.
items
()))
==
[(
"
ua
"
,
1.1
),
(
"
ub
"
,
2.6
)]
assert
"UnorderedMapStringDouble"
in
str
(
um
)
def
test_map_string_double_const
():
mc
=
m
.
MapStringDoubleConst
()
mc
[
'a'
]
=
10
mc
[
'b'
]
=
20.5
mc
[
"a"
]
=
10
mc
[
"b"
]
=
20.5
assert
str
(
mc
)
==
"MapStringDoubleConst{a: 10, b: 20.5}"
umc
=
m
.
UnorderedMapStringDoubleConst
()
umc
[
'a'
]
=
11
umc
[
'b'
]
=
21.5
umc
[
"a"
]
=
11
umc
[
"b"
]
=
21.5
str
(
umc
)
...
...
@@ -196,7 +202,7 @@ def test_noncopyable_containers():
i
=
1
for
j
in
dnc
:
assert
(
j
.
value
==
i
)
assert
j
.
value
==
i
i
+=
1
# std::map
...
...
@@ -265,21 +271,21 @@ def test_noncopyable_containers():
def
test_map_delitem
():
mm
=
m
.
MapStringDouble
()
mm
[
'a'
]
=
1
mm
[
'b'
]
=
2.5
mm
[
"a"
]
=
1
mm
[
"b"
]
=
2.5
assert
list
(
mm
)
==
[
'a'
,
'b'
]
assert
list
(
mm
.
items
())
==
[(
'a'
,
1
),
(
'b'
,
2.5
)]
del
mm
[
'a'
]
assert
list
(
mm
)
==
[
'b'
]
assert
list
(
mm
.
items
())
==
[(
'b'
,
2.5
)]
assert
list
(
mm
)
==
[
"a"
,
"b"
]
assert
list
(
mm
.
items
())
==
[(
"a"
,
1
),
(
"b"
,
2.5
)]
del
mm
[
"a"
]
assert
list
(
mm
)
==
[
"b"
]
assert
list
(
mm
.
items
())
==
[(
"b"
,
2.5
)]
um
=
m
.
UnorderedMapStringDouble
()
um
[
'
ua
'
]
=
1.1
um
[
'
ub
'
]
=
2.6
assert
sorted
(
list
(
um
))
==
[
'
ua
'
,
'
ub
'
]
assert
sorted
(
list
(
um
.
items
()))
==
[(
'
ua
'
,
1.1
),
(
'
ub
'
,
2.6
)]
del
um
[
'
ua
'
]
assert
sorted
(
list
(
um
))
==
[
'
ub
'
]
assert
sorted
(
list
(
um
.
items
()))
==
[(
'
ub
'
,
2.6
)]
um
[
"
ua
"
]
=
1.1
um
[
"
ub
"
]
=
2.6
assert
sorted
(
list
(
um
))
==
[
"
ua
"
,
"
ub
"
]
assert
sorted
(
list
(
um
.
items
()))
==
[(
"
ua
"
,
1.1
),
(
"
ub
"
,
2.6
)]
del
um
[
"
ua
"
]
assert
sorted
(
list
(
um
))
==
[
"
ub
"
]
assert
sorted
(
list
(
um
.
items
()))
==
[(
"
ub
"
,
2.6
)]
tests/test_tagbased_polymorphic.py
View file @
c50f90ec
...
...
@@ -5,16 +5,24 @@ from pybind11_tests import tagbased_polymorphic as m
def
test_downcast
():
zoo
=
m
.
create_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
]
==
[
"Fido"
,
"Ginger"
,
"Hertzl"
,
"Tiger"
,
"Leo"
"Fido"
,
"Ginger"
,
"Hertzl"
,
"Tiger"
,
"Leo"
,
]
zoo
[
1
].
sound
=
"woooooo"
assert
[
dog
.
bark
()
for
dog
in
zoo
[:
3
]]
==
[
"Labrador Fido goes WOOF!"
,
"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"
]
zoo
[
0
].
excitement
-=
1000
...
...
tests/test_virtual_functions.py
View file @
c50f90ec
...
...
@@ -14,18 +14,18 @@ def test_override(capture, msg):
self
.
data
=
"Hello world"
def
run
(
self
,
value
):
print
(
'
ExtendedExampleVirt::run(%i), calling parent..
'
%
value
)
print
(
"
ExtendedExampleVirt::run(%i), calling parent..
"
%
value
)
return
super
(
ExtendedExampleVirt
,
self
).
run
(
value
+
1
)
def
run_bool
(
self
):
print
(
'
ExtendedExampleVirt::run_bool()
'
)
print
(
"
ExtendedExampleVirt::run_bool()
"
)
return
False
def
get_string1
(
self
):
return
"override1"
def
pure_virtual
(
self
):
print
(
'
ExtendedExampleVirt::pure_virtual(): %s
'
%
self
.
data
)
print
(
"
ExtendedExampleVirt::pure_virtual(): %s
"
%
self
.
data
)
class
ExtendedExampleVirt2
(
ExtendedExampleVirt
):
def
__init__
(
self
,
state
):
...
...
@@ -37,21 +37,30 @@ def test_override(capture, msg):
ex12
=
m
.
ExampleVirt
(
10
)
with
capture
:
assert
m
.
runExampleVirt
(
ex12
,
20
)
==
30
assert
capture
==
"""
assert
(
capture
==
"""
Original implementation of ExampleVirt::run(state=10, value=20, str1=default1, str2=default2)
"""
# noqa: E501 line too long
)
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
runExampleVirtVirtual
(
ex12
)
assert
msg
(
excinfo
.
value
)
==
'Tried to call pure virtual function "ExampleVirt::pure_virtual"'
assert
(
msg
(
excinfo
.
value
)
==
'Tried to call pure virtual function "ExampleVirt::pure_virtual"'
)
ex12p
=
ExtendedExampleVirt
(
10
)
with
capture
:
assert
m
.
runExampleVirt
(
ex12p
,
20
)
==
32
assert
capture
==
"""
assert
(
capture
==
"""
ExtendedExampleVirt::run(20), calling parent..
Original implementation of ExampleVirt::run(state=11, value=21, str1=override1, str2=default2)
"""
# noqa: E501 line too long
)
with
capture
:
assert
m
.
runExampleVirtBool
(
ex12p
)
is
False
assert
capture
==
"ExtendedExampleVirt::run_bool()"
...
...
@@ -62,16 +71,19 @@ def test_override(capture, msg):
ex12p2
=
ExtendedExampleVirt2
(
15
)
with
capture
:
assert
m
.
runExampleVirt
(
ex12p2
,
50
)
==
68
assert
capture
==
"""
assert
(
capture
==
"""
ExtendedExampleVirt::run(50), calling parent..
Original implementation of ExampleVirt::run(state=17, value=51, str1=override1, str2=override2)
"""
# noqa: E501 line too long
)
cstats
=
ConstructorStats
.
get
(
m
.
ExampleVirt
)
assert
cstats
.
alive
()
==
3
del
ex12
,
ex12p
,
ex12p2
assert
cstats
.
alive
()
==
0
assert
cstats
.
values
()
==
[
'
10
'
,
'
11
'
,
'
17
'
]
assert
cstats
.
values
()
==
[
"
10
"
,
"
11
"
,
"
17
"
]
assert
cstats
.
copy_constructions
==
0
assert
cstats
.
move_constructions
>=
0
...
...
@@ -82,6 +94,7 @@ def test_alias_delay_initialization1(capture):
If we just create and use an A instance directly, the trampoline initialization is
bypassed and we only initialize an A() instead (for performance reasons).
"""
class
B
(
m
.
A
):
def
__init__
(
self
):
super
(
B
,
self
).
__init__
()
...
...
@@ -103,12 +116,15 @@ def test_alias_delay_initialization1(capture):
m
.
call_f
(
b
)
del
b
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
PyA.PyA()
PyA.f()
In python f()
PyA.~PyA()
"""
)
def
test_alias_delay_initialization2
(
capture
):
...
...
@@ -118,6 +134,7 @@ def test_alias_delay_initialization2(capture):
performance penalty, it also allows us to do more things with the trampoline
class such as defining local variables and performing construction/destruction.
"""
class
B2
(
m
.
A2
):
def
__init__
(
self
):
super
(
B2
,
self
).
__init__
()
...
...
@@ -135,7 +152,9 @@ def test_alias_delay_initialization2(capture):
m
.
call_f
(
a3
)
del
a3
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
PyA2.PyA2()
PyA2.f()
A2.f()
...
...
@@ -145,6 +164,7 @@ def test_alias_delay_initialization2(capture):
A2.f()
PyA2.~PyA2()
"""
)
# Python subclass version
with
capture
:
...
...
@@ -152,20 +172,22 @@ def test_alias_delay_initialization2(capture):
m
.
call_f
(
b2
)
del
b2
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
PyA2.PyA2()
PyA2.f()
In python B2.f()
PyA2.~PyA2()
"""
)
# PyPy: Reference count > 1 causes call with noncopyable instance
# to fail in ncv1.print_nc()
@
pytest
.
mark
.
xfail
(
"env.PYPY"
)
@
pytest
.
mark
.
skipif
(
not
hasattr
(
m
,
"NCVirt"
),
reason
=
"NCVirt does not work on Intel/PGI/NVCC compilers"
not
hasattr
(
m
,
"NCVirt"
),
reason
=
"NCVirt does not work on Intel/PGI/NVCC compilers"
)
def
test_move_support
():
class
NCVirtExt
(
m
.
NCVirt
):
...
...
@@ -205,8 +227,8 @@ def test_move_support():
del
ncv1
,
ncv2
assert
nc_stats
.
alive
()
==
0
assert
mv_stats
.
alive
()
==
0
assert
nc_stats
.
values
()
==
[
'4'
,
'9'
,
'9'
,
'9'
]
assert
mv_stats
.
values
()
==
[
'4'
,
'5'
,
'7'
,
'7'
]
assert
nc_stats
.
values
()
==
[
"4"
,
"9"
,
"9"
,
"9"
]
assert
mv_stats
.
values
()
==
[
"4"
,
"5"
,
"7"
,
"7"
]
assert
nc_stats
.
copy_constructions
==
0
assert
mv_stats
.
copy_constructions
==
1
assert
nc_stats
.
move_constructions
>=
0
...
...
@@ -215,6 +237,7 @@ def test_move_support():
def
test_dispatch_issue
(
msg
):
"""#159: virtual function dispatch has problems with similar-named functions"""
class
PyClass1
(
m
.
DispatchIssue
):
def
dispatch
(
self
):
return
"Yay.."
...
...
@@ -223,7 +246,10 @@ def test_dispatch_issue(msg):
def
dispatch
(
self
):
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
super
(
PyClass2
,
self
).
dispatch
()
assert
msg
(
excinfo
.
value
)
==
'Tried to call pure virtual function "Base::dispatch"'
assert
(
msg
(
excinfo
.
value
)
==
'Tried to call pure virtual function "Base::dispatch"'
)
p
=
PyClass1
()
return
m
.
dispatch_issue_go
(
p
)
...
...
@@ -339,7 +365,7 @@ def test_inherited_virtuals():
class
DT
(
m
.
D_Tpl
):
def
say_something
(
self
,
times
):
return
"DT says:"
+
(
'
quack
'
*
times
)
return
"DT says:"
+
(
"
quack
"
*
times
)
def
unlucky_number
(
self
):
return
1234
...
...
@@ -355,7 +381,7 @@ def test_inherited_virtuals():
class
DT2
(
DT
):
def
say_something
(
self
,
times
):
return
"DT2: "
+
(
'
QUACK
'
*
times
)
return
"DT2: "
+
(
"
QUACK
"
*
times
)
def
unlucky_number
(
self
):
return
-
3
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment