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
bdfb50f3
Commit
bdfb50f3
authored
Jun 07, 2017
by
Dean Moldovan
Browse files
Move tests from test_issues.cpp/py into appropriate files
parent
44e9a4e6
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
471 additions
and
632 deletions
+471
-632
tests/CMakeLists.txt
tests/CMakeLists.txt
+1
-2
tests/test_copy_move.cpp
tests/test_copy_move.cpp
+19
-0
tests/test_copy_move.py
tests/test_copy_move.py
+10
-0
tests/test_inheritance.cpp
tests/test_inheritance.cpp
+20
-0
tests/test_inheritance.py
tests/test_inheritance.py
+13
-0
tests/test_issues.cpp
tests/test_issues.cpp
+0
-377
tests/test_issues.py
tests/test_issues.py
+0
-243
tests/test_methods_and_attributes.cpp
tests/test_methods_and_attributes.cpp
+16
-0
tests/test_methods_and_attributes.py
tests/test_methods_and_attributes.py
+52
-8
tests/test_modules.cpp
tests/test_modules.cpp
+43
-0
tests/test_modules.py
tests/test_modules.py
+7
-0
tests/test_operator_overloading.cpp
tests/test_operator_overloading.cpp
+69
-1
tests/test_operator_overloading.py
tests/test_operator_overloading.py
+55
-1
tests/test_python_types.cpp
tests/test_python_types.cpp
+27
-0
tests/test_python_types.py
tests/test_python_types.py
+14
-0
tests/test_sequences_and_iterators.cpp
tests/test_sequences_and_iterators.cpp
+10
-0
tests/test_sequences_and_iterators.py
tests/test_sequences_and_iterators.py
+17
-0
tests/test_smart_ptr.cpp
tests/test_smart_ptr.cpp
+29
-0
tests/test_smart_ptr.py
tests/test_smart_ptr.py
+12
-0
tests/test_virtual_functions.cpp
tests/test_virtual_functions.cpp
+57
-0
No files found.
tests/CMakeLists.txt
View file @
bdfb50f3
...
...
@@ -40,7 +40,6 @@ set(PYBIND11_TEST_FILES
test_eval.cpp
test_exceptions.cpp
test_inheritance.cpp
test_issues.cpp
test_kwargs_and_defaults.cpp
test_methods_and_attributes.cpp
test_modules.cpp
...
...
@@ -59,7 +58,7 @@ set(PYBIND11_TEST_FILES
)
# Invoking cmake with something like:
# cmake -DPYBIND11_TEST_OVERRIDE="test_
issue
s.cpp;test_picking.cpp" ..
# cmake -DPYBIND11_TEST_OVERRIDE="test_
callback
s.cpp;test_picking.cpp" ..
# lets you override the tests that get compiled and run. You can restore to all tests with:
# cmake -DPYBIND11_TEST_OVERRIDE= ..
if
(
PYBIND11_TEST_OVERRIDE
)
...
...
tests/test_copy_move.cpp
View file @
bdfb50f3
...
...
@@ -187,4 +187,23 @@ test_initializer copy_move_policies([](py::module &m) {
static
PrivateOpNew
x
{};
return
x
;
},
py
::
return_value_policy
::
reference
);
// #389: rvp::move should fall-through to copy on non-movable objects
struct
MoveIssue1
{
int
v
;
MoveIssue1
(
int
v
)
:
v
{
v
}
{}
MoveIssue1
(
const
MoveIssue1
&
c
)
=
default
;
MoveIssue1
(
MoveIssue1
&&
)
=
delete
;
};
struct
MoveIssue2
{
int
v
;
MoveIssue2
(
int
v
)
:
v
{
v
}
{}
MoveIssue2
(
MoveIssue2
&&
)
=
default
;
};
py
::
class_
<
MoveIssue1
>
(
m
,
"MoveIssue1"
).
def
(
py
::
init
<
int
>
()).
def_readwrite
(
"value"
,
&
MoveIssue1
::
v
);
py
::
class_
<
MoveIssue2
>
(
m
,
"MoveIssue2"
).
def
(
py
::
init
<
int
>
()).
def_readwrite
(
"value"
,
&
MoveIssue2
::
v
);
m
.
def
(
"get_moveissue1"
,
[](
int
i
)
{
return
new
MoveIssue1
(
i
);
},
py
::
return_value_policy
::
move
);
m
.
def
(
"get_moveissue2"
,
[](
int
i
)
{
return
MoveIssue2
(
i
);
},
py
::
return_value_policy
::
move
);
});
tests/test_copy_move.py
View file @
bdfb50f3
...
...
@@ -109,3 +109,13 @@ def test_private_op_new():
assert
"the object is neither movable nor copyable"
in
str
(
excinfo
.
value
)
assert
m
.
private_op_new_reference
().
value
==
1
def
test_move_fallback
():
"""#389: rvp::move should fall-through to copy on non-movable objects"""
from
pybind11_tests
import
get_moveissue1
,
get_moveissue2
m2
=
get_moveissue2
(
2
)
assert
m2
.
value
==
2
m1
=
get_moveissue1
(
1
)
assert
m1
.
value
==
1
tests/test_inheritance.cpp
View file @
bdfb50f3
...
...
@@ -120,4 +120,24 @@ test_initializer inheritance([](py::module &m) {
py
::
class_
<
MismatchBase2
>
(
m
,
"MismatchBase2"
);
py
::
class_
<
MismatchDerived2
,
std
::
shared_ptr
<
MismatchDerived2
>
,
MismatchBase2
>
(
m
,
"MismatchDerived2"
);
});
// #511: problem with inheritance + overwritten def_static
struct
MyBase
{
static
std
::
unique_ptr
<
MyBase
>
make
()
{
return
std
::
unique_ptr
<
MyBase
>
(
new
MyBase
());
}
};
struct
MyDerived
:
MyBase
{
static
std
::
unique_ptr
<
MyDerived
>
make
()
{
return
std
::
unique_ptr
<
MyDerived
>
(
new
MyDerived
());
}
};
py
::
class_
<
MyBase
>
(
m
,
"MyBase"
)
.
def_static
(
"make"
,
&
MyBase
::
make
);
py
::
class_
<
MyDerived
,
MyBase
>
(
m
,
"MyDerived"
)
.
def_static
(
"make"
,
&
MyDerived
::
make
)
.
def_static
(
"make2"
,
&
MyDerived
::
make
);
});
tests/test_inheritance.py
View file @
bdfb50f3
...
...
@@ -76,3 +76,16 @@ def test_holder():
assert
str
(
excinfo
.
value
)
==
(
"generic_type: type
\"
MismatchDerived2
\"
has a "
"non-default holder type while its base "
"
\"
MismatchBase2
\"
does not"
)
def
test_inheritance_override_def_static
():
"""#511: problem with inheritance + overwritten def_static"""
from
pybind11_tests
import
MyBase
,
MyDerived
b
=
MyBase
.
make
()
d1
=
MyDerived
.
make2
()
d2
=
MyDerived
.
make
()
assert
isinstance
(
b
,
MyBase
)
assert
isinstance
(
d1
,
MyDerived
)
assert
isinstance
(
d2
,
MyDerived
)
tests/test_issues.cpp
deleted
100644 → 0
View file @
44e9a4e6
/*
tests/test_issues.cpp -- collection of testcases for miscellaneous issues
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
*/
#include "pybind11_tests.h"
#include "constructor_stats.h"
#include <pybind11/stl.h>
#include <pybind11/operators.h>
#include <pybind11/complex.h>
#define TRACKERS(CLASS) CLASS() { print_default_created(this); } ~CLASS() { print_destroyed(this); }
struct
NestABase
{
int
value
=
-
2
;
TRACKERS
(
NestABase
)
};
struct
NestA
:
NestABase
{
int
value
=
3
;
NestA
&
operator
+=
(
int
i
)
{
value
+=
i
;
return
*
this
;
}
TRACKERS
(
NestA
)
};
struct
NestB
{
NestA
a
;
int
value
=
4
;
NestB
&
operator
-=
(
int
i
)
{
value
-=
i
;
return
*
this
;
}
TRACKERS
(
NestB
)
};
struct
NestC
{
NestB
b
;
int
value
=
5
;
NestC
&
operator
*=
(
int
i
)
{
value
*=
i
;
return
*
this
;
}
TRACKERS
(
NestC
)
};
/// #393
class
OpTest1
{};
class
OpTest2
{};
OpTest1
operator
+
(
const
OpTest1
&
,
const
OpTest1
&
)
{
py
::
print
(
"Add OpTest1 with OpTest1"
);
return
OpTest1
();
}
OpTest2
operator
+
(
const
OpTest2
&
,
const
OpTest2
&
)
{
py
::
print
(
"Add OpTest2 with OpTest2"
);
return
OpTest2
();
}
OpTest2
operator
+
(
const
OpTest2
&
,
const
OpTest1
&
)
{
py
::
print
(
"Add OpTest2 with OpTest1"
);
return
OpTest2
();
}
// #461
class
Dupe1
{
public:
Dupe1
(
int
v
)
:
v_
{
v
}
{}
int
get_value
()
const
{
return
v_
;
}
private:
int
v_
;
};
class
Dupe2
{};
class
Dupe3
{};
class
DupeException
:
public
std
::
runtime_error
{};
// #478
template
<
typename
T
>
class
custom_unique_ptr
{
public:
custom_unique_ptr
()
{
print_default_created
(
this
);
}
custom_unique_ptr
(
T
*
ptr
)
:
_ptr
{
ptr
}
{
print_created
(
this
,
ptr
);
}
custom_unique_ptr
(
custom_unique_ptr
<
T
>
&&
move
)
:
_ptr
{
move
.
_ptr
}
{
move
.
_ptr
=
nullptr
;
print_move_created
(
this
);
}
custom_unique_ptr
&
operator
=
(
custom_unique_ptr
<
T
>
&&
move
)
{
print_move_assigned
(
this
);
if
(
_ptr
)
destruct_ptr
();
_ptr
=
move
.
_ptr
;
move
.
_ptr
=
nullptr
;
return
*
this
;
}
custom_unique_ptr
(
const
custom_unique_ptr
<
T
>
&
)
=
delete
;
void
operator
=
(
const
custom_unique_ptr
<
T
>
&
copy
)
=
delete
;
~
custom_unique_ptr
()
{
print_destroyed
(
this
);
if
(
_ptr
)
destruct_ptr
();
}
private:
T
*
_ptr
=
nullptr
;
void
destruct_ptr
()
{
delete
_ptr
;
}
};
PYBIND11_DECLARE_HOLDER_TYPE
(
T
,
custom_unique_ptr
<
T
>
);
/// Issue #528: templated constructor
struct
TplConstrClass
{
template
<
typename
T
>
TplConstrClass
(
const
T
&
arg
)
:
str
{
arg
}
{}
std
::
string
str
;
bool
operator
==
(
const
TplConstrClass
&
t
)
const
{
return
t
.
str
==
str
;
}
};
namespace
std
{
template
<
>
struct
hash
<
TplConstrClass
>
{
size_t
operator
()(
const
TplConstrClass
&
t
)
const
{
return
std
::
hash
<
std
::
string
>
()(
t
.
str
);
}
};
}
void
init_issues
(
py
::
module
&
m
)
{
py
::
module
m2
=
m
.
def_submodule
(
"issues"
);
// #137: const char* isn't handled properly
m2
.
def
(
"print_cchar"
,
[](
const
char
*
s
)
{
return
std
::
string
(
s
);
});
// #150: char bindings broken
m2
.
def
(
"print_char"
,
[](
char
c
)
{
return
std
::
string
(
1
,
c
);
});
// #159: virtual function dispatch has problems with similar-named functions
struct
Base
{
virtual
std
::
string
dispatch
()
const
{
/* for some reason MSVC2015 can't compile this if the function is pure virtual */
return
{};
};
};
struct
DispatchIssue
:
Base
{
virtual
std
::
string
dispatch
()
const
{
PYBIND11_OVERLOAD_PURE
(
std
::
string
,
Base
,
dispatch
,
/* no arguments */
);
}
};
py
::
class_
<
Base
,
DispatchIssue
>
(
m2
,
"DispatchIssue"
)
.
def
(
py
::
init
<>
())
.
def
(
"dispatch"
,
&
Base
::
dispatch
);
m2
.
def
(
"dispatch_issue_go"
,
[](
const
Base
*
b
)
{
return
b
->
dispatch
();
});
struct
Placeholder
{
int
i
;
Placeholder
(
int
i
)
:
i
(
i
)
{
}
};
py
::
class_
<
Placeholder
>
(
m2
,
"Placeholder"
)
.
def
(
py
::
init
<
int
>
())
.
def
(
"__repr__"
,
[](
const
Placeholder
&
p
)
{
return
"Placeholder["
+
std
::
to_string
(
p
.
i
)
+
"]"
;
});
// #181: iterator passthrough did not compile
m2
.
def
(
"iterator_passthrough"
,
[](
py
::
iterator
s
)
->
py
::
iterator
{
return
py
::
make_iterator
(
std
::
begin
(
s
),
std
::
end
(
s
));
});
// #187: issue involving std::shared_ptr<> return value policy & garbage collection
struct
ElementBase
{
virtual
void
foo
()
{
}
/* Force creation of virtual table */
};
struct
ElementA
:
ElementBase
{
ElementA
(
int
v
)
:
v
(
v
)
{
}
int
value
()
{
return
v
;
}
int
v
;
};
struct
ElementList
{
void
add
(
std
::
shared_ptr
<
ElementBase
>
e
)
{
l
.
push_back
(
e
);
}
std
::
vector
<
std
::
shared_ptr
<
ElementBase
>>
l
;
};
py
::
class_
<
ElementBase
,
std
::
shared_ptr
<
ElementBase
>>
(
m2
,
"ElementBase"
);
py
::
class_
<
ElementA
,
ElementBase
,
std
::
shared_ptr
<
ElementA
>>
(
m2
,
"ElementA"
)
.
def
(
py
::
init
<
int
>
())
.
def
(
"value"
,
&
ElementA
::
value
);
py
::
class_
<
ElementList
,
std
::
shared_ptr
<
ElementList
>>
(
m2
,
"ElementList"
)
.
def
(
py
::
init
<>
())
.
def
(
"add"
,
&
ElementList
::
add
)
.
def
(
"get"
,
[](
ElementList
&
el
)
{
py
::
list
list
;
for
(
auto
&
e
:
el
.
l
)
list
.
append
(
py
::
cast
(
e
));
return
list
;
});
// (no id): should not be able to pass 'None' to a reference argument
m2
.
def
(
"get_element"
,
[](
ElementA
&
el
)
{
return
el
.
value
();
});
// (no id): don't cast doubles to ints
m2
.
def
(
"expect_float"
,
[](
float
f
)
{
return
f
;
});
m2
.
def
(
"expect_int"
,
[](
int
i
)
{
return
i
;
});
try
{
py
::
class_
<
Placeholder
>
(
m2
,
"Placeholder"
);
throw
std
::
logic_error
(
"Expected an exception!"
);
}
catch
(
std
::
runtime_error
&
)
{
/* All good */
}
// Issue #283: __str__ called on uninitialized instance when constructor arguments invalid
class
StrIssue
{
public:
StrIssue
(
int
i
)
:
val
{
i
}
{}
StrIssue
()
:
StrIssue
(
-
1
)
{}
int
value
()
const
{
return
val
;
}
private:
int
val
;
};
py
::
class_
<
StrIssue
>
si
(
m2
,
"StrIssue"
);
si
.
def
(
py
::
init
<
int
>
())
.
def
(
py
::
init
<>
())
.
def
(
"__str__"
,
[](
const
StrIssue
&
si
)
{
return
"StrIssue["
+
std
::
to_string
(
si
.
value
())
+
"]"
;
})
;
// Issue #328: first member in a class can't be used in operators
py
::
class_
<
NestABase
>
(
m2
,
"NestABase"
).
def
(
py
::
init
<>
()).
def_readwrite
(
"value"
,
&
NestABase
::
value
);
py
::
class_
<
NestA
>
(
m2
,
"NestA"
).
def
(
py
::
init
<>
()).
def
(
py
::
self
+=
int
())
.
def
(
"as_base"
,
[](
NestA
&
a
)
->
NestABase
&
{
return
(
NestABase
&
)
a
;
},
py
::
return_value_policy
::
reference_internal
);
py
::
class_
<
NestB
>
(
m2
,
"NestB"
).
def
(
py
::
init
<>
()).
def
(
py
::
self
-=
int
()).
def_readwrite
(
"a"
,
&
NestB
::
a
);
py
::
class_
<
NestC
>
(
m2
,
"NestC"
).
def
(
py
::
init
<>
()).
def
(
py
::
self
*=
int
()).
def_readwrite
(
"b"
,
&
NestC
::
b
);
m2
.
def
(
"get_NestA"
,
[](
const
NestA
&
a
)
{
return
a
.
value
;
});
m2
.
def
(
"get_NestB"
,
[](
const
NestB
&
b
)
{
return
b
.
value
;
});
m2
.
def
(
"get_NestC"
,
[](
const
NestC
&
c
)
{
return
c
.
value
;
});
// Issue 389: r_v_p::move should fall-through to copy on non-movable objects
class
MoveIssue1
{
public:
MoveIssue1
(
int
v
)
:
v
{
v
}
{}
MoveIssue1
(
const
MoveIssue1
&
c
)
{
v
=
c
.
v
;
}
MoveIssue1
(
MoveIssue1
&&
)
=
delete
;
int
v
;
};
class
MoveIssue2
{
public:
MoveIssue2
(
int
v
)
:
v
{
v
}
{}
MoveIssue2
(
MoveIssue2
&&
)
=
default
;
int
v
;
};
py
::
class_
<
MoveIssue1
>
(
m2
,
"MoveIssue1"
).
def
(
py
::
init
<
int
>
()).
def_readwrite
(
"value"
,
&
MoveIssue1
::
v
);
py
::
class_
<
MoveIssue2
>
(
m2
,
"MoveIssue2"
).
def
(
py
::
init
<
int
>
()).
def_readwrite
(
"value"
,
&
MoveIssue2
::
v
);
m2
.
def
(
"get_moveissue1"
,
[](
int
i
)
->
MoveIssue1
*
{
return
new
MoveIssue1
(
i
);
},
py
::
return_value_policy
::
move
);
m2
.
def
(
"get_moveissue2"
,
[](
int
i
)
{
return
MoveIssue2
(
i
);
},
py
::
return_value_policy
::
move
);
// Issues 392/397: overridding reference-returning functions
class
OverrideTest
{
public:
struct
A
{
std
::
string
value
=
"hi"
;
};
std
::
string
v
;
A
a
;
explicit
OverrideTest
(
const
std
::
string
&
v
)
:
v
{
v
}
{}
virtual
std
::
string
str_value
()
{
return
v
;
}
virtual
std
::
string
&
str_ref
()
{
return
v
;
}
virtual
A
A_value
()
{
return
a
;
}
virtual
A
&
A_ref
()
{
return
a
;
}
};
class
PyOverrideTest
:
public
OverrideTest
{
public:
using
OverrideTest
::
OverrideTest
;
std
::
string
str_value
()
override
{
PYBIND11_OVERLOAD
(
std
::
string
,
OverrideTest
,
str_value
);
}
// Not allowed (uncommenting should hit a static_assert failure): we can't get a reference
// to a python numeric value, since we only copy values in the numeric type caster:
// std::string &str_ref() override { PYBIND11_OVERLOAD(std::string &, OverrideTest, str_ref); }
// But we can work around it like this:
private:
std
::
string
_tmp
;
std
::
string
str_ref_helper
()
{
PYBIND11_OVERLOAD
(
std
::
string
,
OverrideTest
,
str_ref
);
}
public:
std
::
string
&
str_ref
()
override
{
return
_tmp
=
str_ref_helper
();
}
A
A_value
()
override
{
PYBIND11_OVERLOAD
(
A
,
OverrideTest
,
A_value
);
}
A
&
A_ref
()
override
{
PYBIND11_OVERLOAD
(
A
&
,
OverrideTest
,
A_ref
);
}
};
py
::
class_
<
OverrideTest
::
A
>
(
m2
,
"OverrideTest_A"
)
.
def_readwrite
(
"value"
,
&
OverrideTest
::
A
::
value
);
py
::
class_
<
OverrideTest
,
PyOverrideTest
>
(
m2
,
"OverrideTest"
)
.
def
(
py
::
init
<
const
std
::
string
&>
())
.
def
(
"str_value"
,
&
OverrideTest
::
str_value
)
// .def("str_ref", &OverrideTest::str_ref)
.
def
(
"A_value"
,
&
OverrideTest
::
A_value
)
.
def
(
"A_ref"
,
&
OverrideTest
::
A_ref
);
/// Issue 393: need to return NotSupported to ensure correct arithmetic operator behavior
py
::
class_
<
OpTest1
>
(
m2
,
"OpTest1"
)
.
def
(
py
::
init
<>
())
.
def
(
py
::
self
+
py
::
self
);
py
::
class_
<
OpTest2
>
(
m2
,
"OpTest2"
)
.
def
(
py
::
init
<>
())
.
def
(
py
::
self
+
py
::
self
)
.
def
(
"__add__"
,
[](
const
OpTest2
&
c2
,
const
OpTest1
&
c1
)
{
return
c2
+
c1
;
})
.
def
(
"__radd__"
,
[](
const
OpTest2
&
c2
,
const
OpTest1
&
c1
)
{
return
c2
+
c1
;
});
// Issue 388: Can't make iterators via make_iterator() with different r/v policies
static
std
::
vector
<
int
>
list
=
{
1
,
2
,
3
};
m2
.
def
(
"make_iterator_1"
,
[]()
{
return
py
::
make_iterator
<
py
::
return_value_policy
::
copy
>
(
list
);
});
m2
.
def
(
"make_iterator_2"
,
[]()
{
return
py
::
make_iterator
<
py
::
return_value_policy
::
automatic
>
(
list
);
});
static
std
::
vector
<
std
::
string
>
nothrows
;
// Issue 461: registering two things with the same name:
py
::
class_
<
Dupe1
>
(
m2
,
"Dupe1"
)
.
def
(
"get_value"
,
&
Dupe1
::
get_value
)
;
m2
.
def
(
"dupe1_factory"
,
[](
int
v
)
{
return
new
Dupe1
(
v
);
});
py
::
class_
<
Dupe2
>
(
m2
,
"Dupe2"
);
py
::
exception
<
DupeException
>
(
m2
,
"DupeException"
);
try
{
m2
.
def
(
"Dupe1"
,
[](
int
v
)
{
return
new
Dupe1
(
v
);
});
nothrows
.
emplace_back
(
"Dupe1"
);
}
catch
(
std
::
runtime_error
&
)
{}
try
{
py
::
class_
<
Dupe3
>
(
m2
,
"dupe1_factory"
);
nothrows
.
emplace_back
(
"dupe1_factory"
);
}
catch
(
std
::
runtime_error
&
)
{}
try
{
py
::
exception
<
Dupe3
>
(
m2
,
"Dupe2"
);
nothrows
.
emplace_back
(
"Dupe2"
);
}
catch
(
std
::
runtime_error
&
)
{}
try
{
m2
.
def
(
"DupeException"
,
[]()
{
return
30
;
});
nothrows
.
emplace_back
(
"DupeException1"
);
}
catch
(
std
::
runtime_error
&
)
{}
try
{
py
::
class_
<
DupeException
>
(
m2
,
"DupeException"
);
nothrows
.
emplace_back
(
"DupeException2"
);
}
catch
(
std
::
runtime_error
&
)
{}
m2
.
def
(
"dupe_exception_failures"
,
[]()
{
py
::
list
l
;
for
(
auto
&
e
:
nothrows
)
l
.
append
(
py
::
cast
(
e
));
return
l
;
});
/// Issue #471: shared pointer instance not dellocated
class
SharedChild
:
public
std
::
enable_shared_from_this
<
SharedChild
>
{
public:
SharedChild
()
{
print_created
(
this
);
}
~
SharedChild
()
{
print_destroyed
(
this
);
}
};
class
SharedParent
{
public:
SharedParent
()
:
child
(
std
::
make_shared
<
SharedChild
>
())
{
}
const
SharedChild
&
get_child
()
const
{
return
*
child
;
}
private:
std
::
shared_ptr
<
SharedChild
>
child
;
};
py
::
class_
<
SharedChild
,
std
::
shared_ptr
<
SharedChild
>>
(
m
,
"SharedChild"
);
py
::
class_
<
SharedParent
,
std
::
shared_ptr
<
SharedParent
>>
(
m
,
"SharedParent"
)
.
def
(
py
::
init
<>
())
.
def
(
"get_child"
,
&
SharedParent
::
get_child
,
py
::
return_value_policy
::
reference
);
/// Issue/PR #478: unique ptrs constructed and freed without destruction
class
SpecialHolderObj
{
public:
int
val
=
0
;
SpecialHolderObj
*
ch
=
nullptr
;
SpecialHolderObj
(
int
v
,
bool
make_child
=
true
)
:
val
{
v
},
ch
{
make_child
?
new
SpecialHolderObj
(
val
+
1
,
false
)
:
nullptr
}
{
print_created
(
this
,
val
);
}
~
SpecialHolderObj
()
{
delete
ch
;
print_destroyed
(
this
);
}
SpecialHolderObj
*
child
()
{
return
ch
;
}
};
py
::
class_
<
SpecialHolderObj
,
custom_unique_ptr
<
SpecialHolderObj
>>
(
m
,
"SpecialHolderObj"
)
.
def
(
py
::
init
<
int
>
())
.
def
(
"child"
,
&
SpecialHolderObj
::
child
,
pybind11
::
return_value_policy
::
reference_internal
)
.
def_readwrite
(
"val"
,
&
SpecialHolderObj
::
val
)
.
def_static
(
"holder_cstats"
,
&
ConstructorStats
::
get
<
custom_unique_ptr
<
SpecialHolderObj
>>
,
py
::
return_value_policy
::
reference
);
/// Issue #484: number conversion generates unhandled exceptions
m2
.
def
(
"test_complex"
,
[](
float
x
)
{
py
::
print
(
"{}"
_s
.
format
(
x
));
});
m2
.
def
(
"test_complex"
,
[](
std
::
complex
<
float
>
x
)
{
py
::
print
(
"({}, {})"
_s
.
format
(
x
.
real
(),
x
.
imag
()));
});
/// Issue #511: problem with inheritance + overwritten def_static
struct
MyBase
{
static
std
::
unique_ptr
<
MyBase
>
make
()
{
return
std
::
unique_ptr
<
MyBase
>
(
new
MyBase
());
}
};
struct
MyDerived
:
MyBase
{
static
std
::
unique_ptr
<
MyDerived
>
make
()
{
return
std
::
unique_ptr
<
MyDerived
>
(
new
MyDerived
());
}
};
py
::
class_
<
MyBase
>
(
m2
,
"MyBase"
)
.
def_static
(
"make"
,
&
MyBase
::
make
);
py
::
class_
<
MyDerived
,
MyBase
>
(
m2
,
"MyDerived"
)
.
def_static
(
"make"
,
&
MyDerived
::
make
)
.
def_static
(
"make2"
,
&
MyDerived
::
make
);
py
::
dict
d
;
std
::
string
bar
=
"bar"
;
d
[
"str"
]
=
bar
;
d
[
"num"
]
=
3.7
;
/// Issue #528: templated constructor
m2
.
def
(
"tpl_constr_vector"
,
[](
std
::
vector
<
TplConstrClass
>
&
)
{});
m2
.
def
(
"tpl_constr_map"
,
[](
std
::
unordered_map
<
TplConstrClass
,
TplConstrClass
>
&
)
{});
m2
.
def
(
"tpl_constr_set"
,
[](
std
::
unordered_set
<
TplConstrClass
>
&
)
{});
#if defined(PYBIND11_HAS_OPTIONAL)
m2
.
def
(
"tpl_constr_optional"
,
[](
std
::
optional
<
TplConstrClass
>
&
)
{});
#elif defined(PYBIND11_HAS_EXP_OPTIONAL)
m2
.
def
(
"tpl_constr_optional"
,
[](
std
::
experimental
::
optional
<
TplConstrClass
>
&
)
{});
#endif
}
// MSVC workaround: trying to use a lambda here crashes MSVC
test_initializer
issues
(
&
init_issues
);
tests/test_issues.py
deleted
100644 → 0
View file @
44e9a4e6
import
pytest
from
pybind11_tests
import
ConstructorStats
def
test_regressions
():
from
pybind11_tests.issues
import
print_cchar
,
print_char
# #137: const char* isn't handled properly
assert
print_cchar
(
"const char *"
)
==
"const char *"
# #150: char bindings broken
assert
print_char
(
"c"
)
==
"c"
def
test_dispatch_issue
(
msg
):
"""#159: virtual function dispatch has problems with similar-named functions"""
from
pybind11_tests.issues
import
DispatchIssue
,
dispatch_issue_go
class
PyClass1
(
DispatchIssue
):
def
dispatch
(
self
):
return
"Yay.."
class
PyClass2
(
DispatchIssue
):
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"'
p
=
PyClass1
()
return
dispatch_issue_go
(
p
)
b
=
PyClass2
()
assert
dispatch_issue_go
(
b
)
==
"Yay.."
def
test_iterator_passthrough
():
"""#181: iterator passthrough did not compile"""
from
pybind11_tests.issues
import
iterator_passthrough
assert
list
(
iterator_passthrough
(
iter
([
3
,
5
,
7
,
9
,
11
,
13
,
15
])))
==
[
3
,
5
,
7
,
9
,
11
,
13
,
15
]
def
test_shared_ptr_gc
():
"""// #187: issue involving std::shared_ptr<> return value policy & garbage collection"""
from
pybind11_tests.issues
import
ElementList
,
ElementA
el
=
ElementList
()
for
i
in
range
(
10
):
el
.
add
(
ElementA
(
i
))
pytest
.
gc_collect
()
for
i
,
v
in
enumerate
(
el
.
get
()):
assert
i
==
v
.
value
()
def
test_no_id
(
msg
):
from
pybind11_tests.issues
import
get_element
,
expect_float
,
expect_int
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
get_element
(
None
)
assert
msg
(
excinfo
.
value
)
==
"""
get_element(): incompatible function arguments. The following argument types are supported:
1. (arg0: m.issues.ElementA) -> int
Invoked with: None
"""
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
expect_int
(
5.2
)
assert
msg
(
excinfo
.
value
)
==
"""
expect_int(): incompatible function arguments. The following argument types are supported:
1. (arg0: int) -> int
Invoked with: 5.2
"""
assert
expect_float
(
12
)
==
12
def
test_str_issue
(
msg
):
"""Issue #283: __str__ called on uninitialized instance when constructor arguments invalid"""
from
pybind11_tests.issues
import
StrIssue
assert
str
(
StrIssue
(
3
))
==
"StrIssue[3]"
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
str
(
StrIssue
(
"no"
,
"such"
,
"constructor"
))
assert
msg
(
excinfo
.
value
)
==
"""
__init__(): incompatible constructor arguments. The following argument types are supported:
1. m.issues.StrIssue(arg0: int)
2. m.issues.StrIssue()
Invoked with: 'no', 'such', 'constructor'
"""
def
test_nested
():
""" #328: first member in a class can't be used in operators"""
from
pybind11_tests.issues
import
NestA
,
NestB
,
NestC
,
get_NestA
,
get_NestB
,
get_NestC
a
=
NestA
()
b
=
NestB
()
c
=
NestC
()
a
+=
10
assert
get_NestA
(
a
)
==
13
b
.
a
+=
100
assert
get_NestA
(
b
.
a
)
==
103
c
.
b
.
a
+=
1000
assert
get_NestA
(
c
.
b
.
a
)
==
1003
b
-=
1
assert
get_NestB
(
b
)
==
3
c
.
b
-=
3
assert
get_NestB
(
c
.
b
)
==
1
c
*=
7
assert
get_NestC
(
c
)
==
35
abase
=
a
.
as_base
()
assert
abase
.
value
==
-
2
a
.
as_base
().
value
+=
44
assert
abase
.
value
==
42
assert
c
.
b
.
a
.
as_base
().
value
==
-
2
c
.
b
.
a
.
as_base
().
value
+=
44
assert
c
.
b
.
a
.
as_base
().
value
==
42
del
c
pytest
.
gc_collect
()
del
a
# Should't delete while abase is still alive
pytest
.
gc_collect
()
assert
abase
.
value
==
42
del
abase
,
b
pytest
.
gc_collect
()
def
test_move_fallback
():
from
pybind11_tests.issues
import
get_moveissue1
,
get_moveissue2
m2
=
get_moveissue2
(
2
)
assert
m2
.
value
==
2
m1
=
get_moveissue1
(
1
)
assert
m1
.
value
==
1
def
test_override_ref
():
from
pybind11_tests.issues
import
OverrideTest
o
=
OverrideTest
(
"asdf"
)
# Not allowed (see associated .cpp comment)
# i = o.str_ref()
# assert o.str_ref() == "asdf"
assert
o
.
str_value
()
==
"asdf"
assert
o
.
A_value
().
value
==
"hi"
a
=
o
.
A_ref
()
assert
a
.
value
==
"hi"
a
.
value
=
"bye"
assert
a
.
value
==
"bye"
def
test_operators_notimplemented
(
capture
):
from
pybind11_tests.issues
import
OpTest1
,
OpTest2
with
capture
:
c1
,
c2
=
OpTest1
(),
OpTest2
()
c1
+
c1
c2
+
c2
c2
+
c1
c1
+
c2
assert
capture
==
"""
Add OpTest1 with OpTest1
Add OpTest2 with OpTest2
Add OpTest2 with OpTest1
Add OpTest2 with OpTest1
"""
def
test_iterator_rvpolicy
():
""" Issue 388: Can't make iterators via make_iterator() with different r/v policies """
from
pybind11_tests.issues
import
make_iterator_1
from
pybind11_tests.issues
import
make_iterator_2
assert
list
(
make_iterator_1
())
==
[
1
,
2
,
3
]
assert
list
(
make_iterator_2
())
==
[
1
,
2
,
3
]
assert
not
isinstance
(
make_iterator_1
(),
type
(
make_iterator_2
()))
def
test_dupe_assignment
():
""" Issue 461: overwriting a class with a function """
from
pybind11_tests.issues
import
dupe_exception_failures
assert
dupe_exception_failures
()
==
[]
def
test_enable_shared_from_this_with_reference_rvp
():
""" Issue #471: shared pointer instance not dellocated """
from
pybind11_tests
import
SharedParent
,
SharedChild
parent
=
SharedParent
()
child
=
parent
.
get_child
()
cstats
=
ConstructorStats
.
get
(
SharedChild
)
assert
cstats
.
alive
()
==
1
del
child
,
parent
assert
cstats
.
alive
()
==
0
def
test_non_destructed_holders
():
""" Issue #478: unique ptrs constructed and freed without destruction """
from
pybind11_tests
import
SpecialHolderObj
a
=
SpecialHolderObj
(
123
)
b
=
a
.
child
()
assert
a
.
val
==
123
assert
b
.
val
==
124
cstats
=
SpecialHolderObj
.
holder_cstats
()
assert
cstats
.
alive
()
==
1
del
b
assert
cstats
.
alive
()
==
1
del
a
assert
cstats
.
alive
()
==
0
def
test_complex_cast
(
capture
):
""" Issue #484: number conversion generates unhandled exceptions """
from
pybind11_tests.issues
import
test_complex
with
capture
:
test_complex
(
1
)
test_complex
(
2j
)
assert
capture
==
"""
1.0
(0.0, 2.0)
"""
def
test_inheritance_override_def_static
():
from
pybind11_tests.issues
import
MyBase
,
MyDerived
b
=
MyBase
.
make
()
d1
=
MyDerived
.
make2
()
d2
=
MyDerived
.
make
()
assert
isinstance
(
b
,
MyBase
)
assert
isinstance
(
d1
,
MyDerived
)
assert
isinstance
(
d2
,
MyDerived
)
tests/test_methods_and_attributes.cpp
View file @
bdfb50f3
...
...
@@ -170,6 +170,13 @@ int none3(std::shared_ptr<NoneTester> &obj) { return obj ? obj->answer : -1; }
int
none4
(
std
::
shared_ptr
<
NoneTester
>
*
obj
)
{
return
obj
&&
*
obj
?
(
*
obj
)
->
answer
:
-
1
;
}
int
none5
(
std
::
shared_ptr
<
NoneTester
>
obj
)
{
return
obj
?
obj
->
answer
:
-
1
;
}
struct
StrIssue
{
int
val
=
-
1
;
StrIssue
()
=
default
;
StrIssue
(
int
i
)
:
val
{
i
}
{}
};
test_initializer
methods_and_attributes
([](
py
::
module
&
m
)
{
py
::
class_
<
ExampleMandA
>
emna
(
m
,
"ExampleMandA"
);
emna
.
def
(
py
::
init
<>
())
...
...
@@ -315,6 +322,8 @@ test_initializer methods_and_attributes([](py::module &m) {
m
.
def
(
"floats_preferred"
,
[](
double
f
)
{
return
0.5
*
f
;
},
py
::
arg
(
"f"
));
m
.
def
(
"floats_only"
,
[](
double
f
)
{
return
0.5
*
f
;
},
py
::
arg
(
"f"
).
noconvert
());
m
.
def
(
"ints_preferred"
,
[](
int
i
)
{
return
i
/
2
;
},
py
::
arg
(
"i"
));
m
.
def
(
"ints_only"
,
[](
int
i
)
{
return
i
/
2
;
},
py
::
arg
(
"i"
).
noconvert
());
/// Issue/PR #648: bad arg default debugging output
#if !defined(NDEBUG)
...
...
@@ -344,4 +353,11 @@ test_initializer methods_and_attributes([](py::module &m) {
m
.
def
(
"ok_none4"
,
&
none4
,
py
::
arg
().
none
(
true
));
m
.
def
(
"ok_none5"
,
&
none5
);
// Issue #283: __str__ called on uninitialized instance when constructor arguments invalid
py
::
class_
<
StrIssue
>
(
m
,
"StrIssue"
)
.
def
(
py
::
init
<
int
>
())
.
def
(
py
::
init
<>
())
.
def
(
"__str__"
,
[](
const
StrIssue
&
si
)
{
return
"StrIssue["
+
std
::
to_string
(
si
.
val
)
+
"]"
;
}
);
});
tests/test_methods_and_attributes.py
View file @
bdfb50f3
...
...
@@ -304,9 +304,9 @@ def test_cyclic_gc():
def
test_noconvert_args
(
msg
):
from
pybind11_tests
import
ArgInspector
,
arg_inspect_func
,
floats_only
,
floats_preferred
import
pybind11_tests
as
m
a
=
ArgInspector
()
a
=
m
.
ArgInspector
()
assert
msg
(
a
.
f
(
"hi"
))
==
"""
loading ArgInspector1 argument WITH conversion allowed. Argument value = hi
"""
...
...
@@ -330,15 +330,15 @@ def test_noconvert_args(msg):
"""
assert
(
a
.
h
(
"arg 1"
)
==
"loading ArgInspector2 argument WITHOUT conversion allowed. Argument value = arg 1"
)
assert
msg
(
arg_inspect_func
(
"A1"
,
"A2"
))
==
"""
assert
msg
(
m
.
arg_inspect_func
(
"A1"
,
"A2"
))
==
"""
loading ArgInspector2 argument WITH conversion allowed. Argument value = A1
loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = A2
"""
assert
floats_preferred
(
4
)
==
2.0
assert
floats_only
(
4.0
)
==
2.0
assert
m
.
floats_preferred
(
4
)
==
2.0
assert
m
.
floats_only
(
4.0
)
==
2.0
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
floats_only
(
4
)
m
.
floats_only
(
4
)
assert
msg
(
excinfo
.
value
)
==
"""
floats_only(): incompatible function arguments. The following argument types are supported:
1. (f: float) -> float
...
...
@@ -346,6 +346,27 @@ def test_noconvert_args(msg):
Invoked with: 4
"""
assert
m
.
ints_preferred
(
4
)
==
2
assert
m
.
ints_preferred
(
True
)
==
0
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
ints_preferred
(
4.0
)
assert
msg
(
excinfo
.
value
)
==
"""
ints_preferred(): incompatible function arguments. The following argument types are supported:
1. (i: int) -> int
Invoked with: 4.0
"""
# noqa: E501 line too long
assert
m
.
ints_only
(
4
)
==
2
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
ints_only
(
4.0
)
assert
msg
(
excinfo
.
value
)
==
"""
ints_only(): incompatible function arguments. The following argument types are supported:
1. (i: int) -> int
Invoked with: 4.0
"""
def
test_bad_arg_default
(
msg
):
from
pybind11_tests
import
debug_enabled
,
bad_arg_def_named
,
bad_arg_def_unnamed
...
...
@@ -371,7 +392,7 @@ def test_bad_arg_default(msg):
)
def
test_accepts_none
():
def
test_accepts_none
(
msg
):
from
pybind11_tests
import
(
NoneTester
,
no_none1
,
no_none2
,
no_none3
,
no_none4
,
no_none5
,
ok_none1
,
ok_none2
,
ok_none3
,
ok_none4
,
ok_none5
)
...
...
@@ -407,9 +428,32 @@ def test_accepts_none():
# The first one still raises because you can't pass None as a lvalue reference arg:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
ok_none1
(
None
)
==
-
1
assert
"incompatible function arguments"
in
str
(
excinfo
.
value
)
assert
msg
(
excinfo
.
value
)
==
"""
ok_none1(): incompatible function arguments. The following argument types are supported:
1. (arg0: m.NoneTester) -> int
Invoked with: None
"""
# The rest take the argument as pointer or holder, and accept None:
assert
ok_none2
(
None
)
==
-
1
assert
ok_none3
(
None
)
==
-
1
assert
ok_none4
(
None
)
==
-
1
assert
ok_none5
(
None
)
==
-
1
def
test_str_issue
(
msg
):
"""#283: __str__ called on uninitialized instance when constructor arguments invalid"""
from
pybind11_tests
import
StrIssue
assert
str
(
StrIssue
(
3
))
==
"StrIssue[3]"
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
str
(
StrIssue
(
"no"
,
"such"
,
"constructor"
))
assert
msg
(
excinfo
.
value
)
==
"""
__init__(): incompatible constructor arguments. The following argument types are supported:
1. m.StrIssue(arg0: int)
2. m.StrIssue()
Invoked with: 'no', 'such', 'constructor'
"""
tests/test_modules.cpp
View file @
bdfb50f3
...
...
@@ -55,4 +55,47 @@ test_initializer modules([](py::module &m) {
.
def_readwrite
(
"a2"
,
&
B
::
a2
);
m
.
attr
(
"OD"
)
=
py
::
module
::
import
(
"collections"
).
attr
(
"OrderedDict"
);
// Registering two things with the same name
m
.
def
(
"duplicate_registration"
,
[]()
{
class
Dupe1
{
};
class
Dupe2
{
};
class
Dupe3
{
};
class
DupeException
{
};
auto
dm
=
py
::
module
(
"dummy"
);
auto
failures
=
py
::
list
();
py
::
class_
<
Dupe1
>
(
dm
,
"Dupe1"
);
py
::
class_
<
Dupe2
>
(
dm
,
"Dupe2"
);
dm
.
def
(
"dupe1_factory"
,
[]()
{
return
Dupe1
();
});
py
::
exception
<
DupeException
>
(
dm
,
"DupeException"
);
try
{
py
::
class_
<
Dupe1
>
(
dm
,
"Dupe1"
);
failures
.
append
(
"Dupe1 class"
);
}
catch
(
std
::
runtime_error
&
)
{}
try
{
dm
.
def
(
"Dupe1"
,
[]()
{
return
Dupe1
();
});
failures
.
append
(
"Dupe1 function"
);
}
catch
(
std
::
runtime_error
&
)
{}
try
{
py
::
class_
<
Dupe3
>
(
dm
,
"dupe1_factory"
);
failures
.
append
(
"dupe1_factory"
);
}
catch
(
std
::
runtime_error
&
)
{}
try
{
py
::
exception
<
Dupe3
>
(
dm
,
"Dupe2"
);
failures
.
append
(
"Dupe2"
);
}
catch
(
std
::
runtime_error
&
)
{}
try
{
dm
.
def
(
"DupeException"
,
[]()
{
return
30
;
});
failures
.
append
(
"DupeException1"
);
}
catch
(
std
::
runtime_error
&
)
{}
try
{
py
::
class_
<
DupeException
>
(
dm
,
"DupeException"
);
failures
.
append
(
"DupeException2"
);
}
catch
(
std
::
runtime_error
&
)
{}
return
failures
;
});
});
tests/test_modules.py
View file @
bdfb50f3
...
...
@@ -61,3 +61,10 @@ def test_pydoc():
assert
pybind11_tests
.
__doc__
==
"pybind11 test module"
assert
pydoc
.
text
.
docmodule
(
pybind11_tests
)
def
test_duplicate_registration
():
"""Registering two things with the same name"""
from
pybind11_tests
import
duplicate_registration
assert
duplicate_registration
()
==
[]
tests/test_operator_overloading.cpp
View file @
bdfb50f3
...
...
@@ -56,7 +56,38 @@ private:
float
x
,
y
;
};
test_initializer
operator_overloading
([](
py
::
module
&
m
)
{
class
C1
{
};
class
C2
{
};
int
operator
+
(
const
C1
&
,
const
C1
&
)
{
return
11
;
}
int
operator
+
(
const
C2
&
,
const
C2
&
)
{
return
22
;
}
int
operator
+
(
const
C2
&
,
const
C1
&
)
{
return
21
;
}
int
operator
+
(
const
C1
&
,
const
C2
&
)
{
return
12
;
}
struct
NestABase
{
int
value
=
-
2
;
};
struct
NestA
:
NestABase
{
int
value
=
3
;
NestA
&
operator
+=
(
int
i
)
{
value
+=
i
;
return
*
this
;
}
};
struct
NestB
{
NestA
a
;
int
value
=
4
;
NestB
&
operator
-=
(
int
i
)
{
value
-=
i
;
return
*
this
;
}
};
struct
NestC
{
NestB
b
;
int
value
=
5
;
NestC
&
operator
*=
(
int
i
)
{
value
*=
i
;
return
*
this
;
}
};
test_initializer
operator_overloading
([](
py
::
module
&
pm
)
{
auto
m
=
pm
.
def_submodule
(
"operators"
);
py
::
class_
<
Vector2
>
(
m
,
"Vector2"
)
.
def
(
py
::
init
<
float
,
float
>
())
.
def
(
py
::
self
+
py
::
self
)
...
...
@@ -81,4 +112,41 @@ test_initializer operator_overloading([](py::module &m) {
;
m
.
attr
(
"Vector"
)
=
m
.
attr
(
"Vector2"
);
// #393: need to return NotSupported to ensure correct arithmetic operator behavior
py
::
class_
<
C1
>
(
m
,
"C1"
)
.
def
(
py
::
init
<>
())
.
def
(
py
::
self
+
py
::
self
);
py
::
class_
<
C2
>
(
m
,
"C2"
)
.
def
(
py
::
init
<>
())
.
def
(
py
::
self
+
py
::
self
)
.
def
(
"__add__"
,
[](
const
C2
&
c2
,
const
C1
&
c1
)
{
return
c2
+
c1
;
})
.
def
(
"__radd__"
,
[](
const
C2
&
c2
,
const
C1
&
c1
)
{
return
c1
+
c2
;
});
// #328: first member in a class can't be used in operators
py
::
class_
<
NestABase
>
(
m
,
"NestABase"
)
.
def
(
py
::
init
<>
())
.
def_readwrite
(
"value"
,
&
NestABase
::
value
);
py
::
class_
<
NestA
>
(
m
,
"NestA"
)
.
def
(
py
::
init
<>
())
.
def
(
py
::
self
+=
int
())
.
def
(
"as_base"
,
[](
NestA
&
a
)
->
NestABase
&
{
return
(
NestABase
&
)
a
;
},
py
::
return_value_policy
::
reference_internal
);
py
::
class_
<
NestB
>
(
m
,
"NestB"
)
.
def
(
py
::
init
<>
())
.
def
(
py
::
self
-=
int
())
.
def_readwrite
(
"a"
,
&
NestB
::
a
);
py
::
class_
<
NestC
>
(
m
,
"NestC"
)
.
def
(
py
::
init
<>
())
.
def
(
py
::
self
*=
int
())
.
def_readwrite
(
"b"
,
&
NestC
::
b
);
m
.
def
(
"get_NestA"
,
[](
const
NestA
&
a
)
{
return
a
.
value
;
});
m
.
def
(
"get_NestB"
,
[](
const
NestB
&
b
)
{
return
b
.
value
;
});
m
.
def
(
"get_NestC"
,
[](
const
NestC
&
c
)
{
return
c
.
value
;
});
});
tests/test_operator_overloading.py
View file @
bdfb50f3
import
pytest
from
pybind11_tests
import
ConstructorStats
def
test_operator_overloading
():
from
pybind11_tests
import
Vector2
,
Vector
,
ConstructorStats
from
pybind11_tests
.operators
import
Vector2
,
Vector
v1
=
Vector2
(
1
,
2
)
v2
=
Vector
(
3
,
-
1
)
...
...
@@ -51,3 +55,53 @@ def test_operator_overloading():
assert
cstats
.
move_constructions
>=
10
assert
cstats
.
copy_assignments
==
0
assert
cstats
.
move_assignments
==
0
def
test_operators_notimplemented
():
"""#393: need to return NotSupported to ensure correct arithmetic operator behavior"""
from
pybind11_tests.operators
import
C1
,
C2
c1
,
c2
=
C1
(),
C2
()
assert
c1
+
c1
==
11
assert
c2
+
c2
==
22
assert
c2
+
c1
==
21
assert
c1
+
c2
==
12
def
test_nested
():
"""#328: first member in a class can't be used in operators"""
from
pybind11_tests.operators
import
NestA
,
NestB
,
NestC
,
get_NestA
,
get_NestB
,
get_NestC
a
=
NestA
()
b
=
NestB
()
c
=
NestC
()
a
+=
10
assert
get_NestA
(
a
)
==
13
b
.
a
+=
100
assert
get_NestA
(
b
.
a
)
==
103
c
.
b
.
a
+=
1000
assert
get_NestA
(
c
.
b
.
a
)
==
1003
b
-=
1
assert
get_NestB
(
b
)
==
3
c
.
b
-=
3
assert
get_NestB
(
c
.
b
)
==
1
c
*=
7
assert
get_NestC
(
c
)
==
35
abase
=
a
.
as_base
()
assert
abase
.
value
==
-
2
a
.
as_base
().
value
+=
44
assert
abase
.
value
==
42
assert
c
.
b
.
a
.
as_base
().
value
==
-
2
c
.
b
.
a
.
as_base
().
value
+=
44
assert
c
.
b
.
a
.
as_base
().
value
==
42
del
c
pytest
.
gc_collect
()
del
a
# Should't delete while abase is still alive
pytest
.
gc_collect
()
assert
abase
.
value
==
42
del
abase
,
b
pytest
.
gc_collect
()
tests/test_python_types.cpp
View file @
bdfb50f3
...
...
@@ -11,6 +11,7 @@
#include "pybind11_tests.h"
#include "constructor_stats.h"
#include <pybind11/stl.h>
#include <pybind11/complex.h>
#ifdef _WIN32
# include <io.h>
...
...
@@ -215,6 +216,17 @@ std::vector<std::reference_wrapper<IncrIntWrapper>> incr_int_wrappers() {
return
r
;
};
/// Issue #528: templated constructor
struct
TplCtorClass
{
template
<
typename
T
>
TplCtorClass
(
const
T
&
)
{
}
bool
operator
==
(
const
TplCtorClass
&
)
const
{
return
true
;
}
};
namespace
std
{
template
<
>
struct
hash
<
TplCtorClass
>
{
size_t
operator
()(
const
TplCtorClass
&
)
const
{
return
0
;
}
};
}
test_initializer
python_types
([](
py
::
module
&
m
)
{
/* No constructor is explicitly defined below. An exception is raised when
trying to construct it directly from Python */
...
...
@@ -501,6 +513,8 @@ test_initializer python_types([](py::module &m) {
);
});
m
.
def
(
"string_roundtrip"
,
[](
const
char
*
s
)
{
return
s
;
});
// Some test characters in utf16 and utf32 encodings. The last one (the 𝐀) contains a null byte
char32_t
a32
=
0x61
/*a*/
,
z32
=
0x7a
/*z*/
,
ib32
=
0x203d
/*‽*/
,
cake32
=
0x1f382
/*🎂*/
,
mathbfA32
=
0x1d400
/*𝐀*/
;
char16_t
b16
=
0x62
/*b*/
,
z16
=
0x7a
,
ib16
=
0x203d
,
cake16_1
=
0xd83c
,
cake16_2
=
0xdf82
,
mathbfA16_1
=
0xd835
,
mathbfA16_2
=
0xdc00
;
...
...
@@ -661,6 +675,19 @@ test_initializer python_types([](py::module &m) {
return
l
;
});
/// Issue #484: number conversion generates unhandled exceptions
m
.
def
(
"test_complex"
,
[](
float
x
)
{
return
"{}"
_s
.
format
(
x
);
});
m
.
def
(
"test_complex"
,
[](
std
::
complex
<
float
>
x
)
{
return
"({}, {})"
_s
.
format
(
x
.
real
(),
x
.
imag
());
});
/// Issue #528: templated constructor
m
.
def
(
"tpl_ctor_vector"
,
[](
std
::
vector
<
TplCtorClass
>
&
)
{});
m
.
def
(
"tpl_ctor_map"
,
[](
std
::
unordered_map
<
TplCtorClass
,
TplCtorClass
>
&
)
{});
m
.
def
(
"tpl_ctor_set"
,
[](
std
::
unordered_set
<
TplCtorClass
>
&
)
{});
#if defined(PYBIND11_HAS_OPTIONAL)
m
.
def
(
"tpl_constr_optional"
,
[](
std
::
optional
<
TplCtorClass
>
&
)
{});
#elif defined(PYBIND11_HAS_EXP_OPTIONAL)
m
.
def
(
"tpl_constr_optional"
,
[](
std
::
experimental
::
optional
<
TplCtorClass
>
&
)
{});
#endif
});
#if defined(_MSC_VER)
...
...
tests/test_python_types.py
View file @
bdfb50f3
...
...
@@ -452,6 +452,12 @@ def test_implicit_casting():
assert
z
[
'l'
]
==
[
3
,
6
,
9
,
12
,
15
]
def
test_simple_string
():
from
pybind11_tests
import
string_roundtrip
assert
string_roundtrip
(
"const char *"
)
==
"const char *"
def
test_unicode_conversion
():
"""Tests unicode conversion and error reporting."""
import
pybind11_tests
...
...
@@ -699,3 +705,11 @@ def test_reference_wrapper():
assert
refwrap_iiw
(
IncrIntWrapper
(
5
))
==
5
assert
refwrap_call_iiw
(
IncrIntWrapper
(
10
),
refwrap_iiw
)
==
[
10
,
10
,
10
,
10
]
def
test_complex_cast
():
"""#484: number conversion generates unhandled exceptions"""
from
pybind11_tests
import
test_complex
assert
test_complex
(
1
)
==
"1.0"
assert
test_complex
(
2j
)
==
"(0.0, 2.0)"
tests/test_sequences_and_iterators.cpp
View file @
bdfb50f3
...
...
@@ -351,4 +351,14 @@ test_initializer sequences_and_iterators([](py::module &pm) {
m
.
def
(
"tuple_iterator"
,
[](
py
::
tuple
x
)
{
return
test_random_access_iterator
(
x
);
});
m
.
def
(
"list_iterator"
,
[](
py
::
list
x
)
{
return
test_random_access_iterator
(
x
);
});
m
.
def
(
"sequence_iterator"
,
[](
py
::
sequence
x
)
{
return
test_random_access_iterator
(
x
);
});
// #181: iterator passthrough did not compile
m
.
def
(
"iterator_passthrough"
,
[](
py
::
iterator
s
)
->
py
::
iterator
{
return
py
::
make_iterator
(
std
::
begin
(
s
),
std
::
end
(
s
));
});
// #388: Can't make iterators via make_iterator() with different r/v policies
static
std
::
vector
<
int
>
list
=
{
1
,
2
,
3
};
m
.
def
(
"make_iterator_1"
,
[]()
{
return
py
::
make_iterator
<
py
::
return_value_policy
::
copy
>
(
list
);
});
m
.
def
(
"make_iterator_2"
,
[]()
{
return
py
::
make_iterator
<
py
::
return_value_policy
::
automatic
>
(
list
);
});
});
tests/test_sequences_and_iterators.py
View file @
bdfb50f3
...
...
@@ -147,3 +147,20 @@ def test_python_iterator_in_cpp():
assert
all
(
m
.
tuple_iterator
(
tuple
(
r
)))
assert
all
(
m
.
list_iterator
(
list
(
r
)))
assert
all
(
m
.
sequence_iterator
(
r
))
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
]
def
test_iterator_rvp
():
"""#388: Can't make iterators via make_iterator() with different r/v policies """
import
pybind11_tests.sequences_and_iterators
as
m
assert
list
(
m
.
make_iterator_1
())
==
[
1
,
2
,
3
]
assert
list
(
m
.
make_iterator_2
())
==
[
1
,
2
,
3
]
assert
not
isinstance
(
m
.
make_iterator_1
(),
type
(
m
.
make_iterator_2
()))
tests/test_smart_ptr.cpp
View file @
bdfb50f3
...
...
@@ -259,6 +259,18 @@ public:
PYBIND11_DECLARE_HOLDER_TYPE
(
T
,
CustomUniquePtr
<
T
>
);
struct
ElementBase
{
virtual
void
foo
()
{
}
/* Force creation of virtual table */
};
struct
ElementA
:
ElementBase
{
ElementA
(
int
v
)
:
v
(
v
)
{
}
int
value
()
{
return
v
;
}
int
v
;
};
struct
ElementList
{
void
add
(
std
::
shared_ptr
<
ElementBase
>
e
)
{
l
.
push_back
(
e
);
}
std
::
vector
<
std
::
shared_ptr
<
ElementBase
>>
l
;
};
test_initializer
smart_ptr_and_references
([](
py
::
module
&
pm
)
{
auto
m
=
pm
.
def_submodule
(
"smart_ptr"
);
...
...
@@ -309,4 +321,21 @@ test_initializer smart_ptr_and_references([](py::module &pm) {
py
::
class_
<
HeldByDefaultHolder
>
(
m
,
"HeldByDefaultHolder"
)
.
def
(
py
::
init
<>
())
.
def_static
(
"load_shared_ptr"
,
[](
std
::
shared_ptr
<
HeldByDefaultHolder
>
)
{});
// #187: issue involving std::shared_ptr<> return value policy & garbage collection
py
::
class_
<
ElementBase
,
std
::
shared_ptr
<
ElementBase
>>
(
m
,
"ElementBase"
);
py
::
class_
<
ElementA
,
ElementBase
,
std
::
shared_ptr
<
ElementA
>>
(
m
,
"ElementA"
)
.
def
(
py
::
init
<
int
>
())
.
def
(
"value"
,
&
ElementA
::
value
);
py
::
class_
<
ElementList
,
std
::
shared_ptr
<
ElementList
>>
(
m
,
"ElementList"
)
.
def
(
py
::
init
<>
())
.
def
(
"add"
,
&
ElementList
::
add
)
.
def
(
"get"
,
[](
ElementList
&
el
)
{
py
::
list
list
;
for
(
auto
&
e
:
el
.
l
)
list
.
append
(
py
::
cast
(
e
));
return
list
;
});
});
tests/test_smart_ptr.py
View file @
bdfb50f3
...
...
@@ -234,3 +234,15 @@ def test_smart_ptr_from_default():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
HeldByDefaultHolder
.
load_shared_ptr
(
instance
)
assert
"Unable to load a custom holder type from a default-holder instance"
in
str
(
excinfo
)
def
test_shared_ptr_gc
():
"""#187: issue involving std::shared_ptr<> return value policy & garbage collection"""
from
pybind11_tests.smart_ptr
import
ElementList
,
ElementA
el
=
ElementList
()
for
i
in
range
(
10
):
el
.
add
(
ElementA
(
i
))
pytest
.
gc_collect
()
for
i
,
v
in
enumerate
(
el
.
get
()):
assert
i
==
v
.
value
()
tests/test_virtual_functions.cpp
View file @
bdfb50f3
...
...
@@ -311,6 +311,16 @@ void initialize_inherited_virtuals(py::module &m) {
};
struct
Base
{
/* for some reason MSVC2015 can't compile this if the function is pure virtual */
virtual
std
::
string
dispatch
()
const
{
return
{};
};
};
struct
DispatchIssue
:
Base
{
virtual
std
::
string
dispatch
()
const
{
PYBIND11_OVERLOAD_PURE
(
std
::
string
,
Base
,
dispatch
,
/* no arguments */
);
}
};
test_initializer
virtual_functions
([](
py
::
module
&
m
)
{
py
::
class_
<
ExampleVirt
,
PyExampleVirt
>
(
m
,
"ExampleVirt"
)
...
...
@@ -341,4 +351,51 @@ test_initializer virtual_functions([](py::module &m) {
m
.
def
(
"cstats_debug"
,
&
ConstructorStats
::
get
<
ExampleVirt
>
);
initialize_inherited_virtuals
(
m
);
// #159: virtual function dispatch has problems with similar-named functions
py
::
class_
<
Base
,
DispatchIssue
>
(
m
,
"DispatchIssue"
)
.
def
(
py
::
init
<>
())
.
def
(
"dispatch"
,
&
Base
::
dispatch
);
m
.
def
(
"dispatch_issue_go"
,
[](
const
Base
*
b
)
{
return
b
->
dispatch
();
});
// #392/397: overridding reference-returning functions
class
OverrideTest
{
public:
struct
A
{
std
::
string
value
=
"hi"
;
};
std
::
string
v
;
A
a
;
explicit
OverrideTest
(
const
std
::
string
&
v
)
:
v
{
v
}
{}
virtual
std
::
string
str_value
()
{
return
v
;
}
virtual
std
::
string
&
str_ref
()
{
return
v
;
}
virtual
A
A_value
()
{
return
a
;
}
virtual
A
&
A_ref
()
{
return
a
;
}
};
class
PyOverrideTest
:
public
OverrideTest
{
public:
using
OverrideTest
::
OverrideTest
;
std
::
string
str_value
()
override
{
PYBIND11_OVERLOAD
(
std
::
string
,
OverrideTest
,
str_value
);
}
// Not allowed (uncommenting should hit a static_assert failure): we can't get a reference
// to a python numeric value, since we only copy values in the numeric type caster:
// std::string &str_ref() override { PYBIND11_OVERLOAD(std::string &, OverrideTest, str_ref); }
// But we can work around it like this:
private:
std
::
string
_tmp
;
std
::
string
str_ref_helper
()
{
PYBIND11_OVERLOAD
(
std
::
string
,
OverrideTest
,
str_ref
);
}
public:
std
::
string
&
str_ref
()
override
{
return
_tmp
=
str_ref_helper
();
}
A
A_value
()
override
{
PYBIND11_OVERLOAD
(
A
,
OverrideTest
,
A_value
);
}
A
&
A_ref
()
override
{
PYBIND11_OVERLOAD
(
A
&
,
OverrideTest
,
A_ref
);
}
};
py
::
class_
<
OverrideTest
::
A
>
(
m
,
"OverrideTest_A"
)
.
def_readwrite
(
"value"
,
&
OverrideTest
::
A
::
value
);
py
::
class_
<
OverrideTest
,
PyOverrideTest
>
(
m
,
"OverrideTest"
)
.
def
(
py
::
init
<
const
std
::
string
&>
())
.
def
(
"str_value"
,
&
OverrideTest
::
str_value
)
// .def("str_ref", &OverrideTest::str_ref)
.
def
(
"A_value"
,
&
OverrideTest
::
A_value
)
.
def
(
"A_ref"
,
&
OverrideTest
::
A_ref
);
});
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