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
e315e1fe
Unverified
Commit
e315e1fe
authored
Oct 04, 2021
by
Henry Schreiner
Browse files
Merge branch 'master' into stable
parents
71fd5241
97976c16
Changes
143
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
285 additions
and
15 deletions
+285
-15
tests/test_cmake_build/installed_function/CMakeLists.txt
tests/test_cmake_build/installed_function/CMakeLists.txt
+2
-1
tests/test_cmake_build/installed_target/CMakeLists.txt
tests/test_cmake_build/installed_target/CMakeLists.txt
+2
-1
tests/test_cmake_build/subdirectory_embed/CMakeLists.txt
tests/test_cmake_build/subdirectory_embed/CMakeLists.txt
+4
-2
tests/test_cmake_build/subdirectory_function/CMakeLists.txt
tests/test_cmake_build/subdirectory_function/CMakeLists.txt
+2
-1
tests/test_cmake_build/subdirectory_target/CMakeLists.txt
tests/test_cmake_build/subdirectory_target/CMakeLists.txt
+2
-1
tests/test_cmake_build/test.py
tests/test_cmake_build/test.py
+4
-0
tests/test_copy_move.cpp
tests/test_copy_move.cpp
+7
-7
tests/test_copy_move.py
tests/test_copy_move.py
+1
-0
tests/test_custom_type_casters.py
tests/test_custom_type_casters.py
+1
-0
tests/test_custom_type_setup.cpp
tests/test_custom_type_setup.cpp
+41
-0
tests/test_custom_type_setup.py
tests/test_custom_type_setup.py
+50
-0
tests/test_eigen.cpp
tests/test_eigen.cpp
+4
-0
tests/test_eigen.py
tests/test_eigen.py
+1
-0
tests/test_embed/CMakeLists.txt
tests/test_embed/CMakeLists.txt
+1
-0
tests/test_embed/external_module.cpp
tests/test_embed/external_module.cpp
+1
-1
tests/test_embed/test_interpreter.cpp
tests/test_embed/test_interpreter.cpp
+42
-1
tests/test_embed/test_interpreter.py
tests/test_embed/test_interpreter.py
+5
-0
tests/test_enum.cpp
tests/test_enum.cpp
+61
-0
tests/test_enum.py
tests/test_enum.py
+36
-0
tests/test_eval.cpp
tests/test_eval.cpp
+18
-0
No files found.
tests/test_cmake_build/installed_function/CMakeLists.txt
View file @
e315e1fe
...
...
@@ -35,4 +35,5 @@ add_custom_target(
PYTHONPATH=$<TARGET_FILE_DIR:test_installed_function>
${
_Python_EXECUTABLE
}
${
PROJECT_SOURCE_DIR
}
/../test.py
${
PROJECT_NAME
}
)
${
PROJECT_NAME
}
DEPENDS test_installed_function
)
tests/test_cmake_build/installed_target/CMakeLists.txt
View file @
e315e1fe
...
...
@@ -42,4 +42,5 @@ add_custom_target(
PYTHONPATH=$<TARGET_FILE_DIR:test_installed_target>
${
_Python_EXECUTABLE
}
${
PROJECT_SOURCE_DIR
}
/../test.py
${
PROJECT_NAME
}
)
${
PROJECT_NAME
}
DEPENDS test_installed_target
)
tests/test_cmake_build/subdirectory_embed/CMakeLists.txt
View file @
e315e1fe
...
...
@@ -23,8 +23,10 @@ add_executable(test_subdirectory_embed ../embed.cpp)
target_link_libraries
(
test_subdirectory_embed PRIVATE pybind11::embed
)
set_target_properties
(
test_subdirectory_embed PROPERTIES OUTPUT_NAME test_cmake_build
)
add_custom_target
(
check_subdirectory_embed $<TARGET_FILE:test_subdirectory_embed>
"
${
PROJECT_SOURCE_DIR
}
/../test.py"
)
add_custom_target
(
check_subdirectory_embed
$<TARGET_FILE:test_subdirectory_embed>
"
${
PROJECT_SOURCE_DIR
}
/../test.py"
DEPENDS test_subdirectory_embed
)
# Test custom export group -- PYBIND11_EXPORT_NAME
add_library
(
test_embed_lib ../embed.cpp
)
...
...
tests/test_cmake_build/subdirectory_function/CMakeLists.txt
View file @
e315e1fe
...
...
@@ -31,4 +31,5 @@ add_custom_target(
PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_function>
${
_Python_EXECUTABLE
}
${
PROJECT_SOURCE_DIR
}
/../test.py
${
PROJECT_NAME
}
)
${
PROJECT_NAME
}
DEPENDS test_subdirectory_function
)
tests/test_cmake_build/subdirectory_target/CMakeLists.txt
View file @
e315e1fe
...
...
@@ -37,4 +37,5 @@ add_custom_target(
PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_target>
${
_Python_EXECUTABLE
}
${
PROJECT_SOURCE_DIR
}
/../test.py
${
PROJECT_NAME
}
)
${
PROJECT_NAME
}
DEPENDS test_subdirectory_target
)
tests/test_cmake_build/test.py
View file @
e315e1fe
# -*- coding: utf-8 -*-
import
sys
import
test_cmake_build
if
str
is
not
bytes
:
# If not Python2
assert
isinstance
(
__file__
,
str
)
# Test this is properly set
assert
test_cmake_build
.
add
(
1
,
2
)
==
3
print
(
"{} imports, runs, and adds: 1 + 2 = 3"
.
format
(
sys
.
argv
[
1
]))
tests/test_copy_move.cpp
View file @
e315e1fe
...
...
@@ -37,7 +37,7 @@ template <> lacking_move_ctor empty<lacking_move_ctor>::instance_ = {};
class
MoveOnlyInt
{
public:
MoveOnlyInt
()
{
print_default_created
(
this
);
}
MoveOnlyInt
(
int
v
)
:
value
{
v
}
{
print_created
(
this
,
value
);
}
explicit
MoveOnlyInt
(
int
v
)
:
value
{
v
}
{
print_created
(
this
,
value
);
}
MoveOnlyInt
(
MoveOnlyInt
&&
m
)
noexcept
{
print_move_created
(
this
,
m
.
value
);
std
::
swap
(
value
,
m
.
value
);
...
...
@@ -56,7 +56,7 @@ public:
class
MoveOrCopyInt
{
public:
MoveOrCopyInt
()
{
print_default_created
(
this
);
}
MoveOrCopyInt
(
int
v
)
:
value
{
v
}
{
print_created
(
this
,
value
);
}
explicit
MoveOrCopyInt
(
int
v
)
:
value
{
v
}
{
print_created
(
this
,
value
);
}
MoveOrCopyInt
(
MoveOrCopyInt
&&
m
)
noexcept
{
print_move_created
(
this
,
m
.
value
);
std
::
swap
(
value
,
m
.
value
);
...
...
@@ -75,7 +75,7 @@ public:
class
CopyOnlyInt
{
public:
CopyOnlyInt
()
{
print_default_created
(
this
);
}
CopyOnlyInt
(
int
v
)
:
value
{
v
}
{
print_created
(
this
,
value
);
}
explicit
CopyOnlyInt
(
int
v
)
:
value
{
v
}
{
print_created
(
this
,
value
);
}
CopyOnlyInt
(
const
CopyOnlyInt
&
c
)
{
print_copy_created
(
this
,
c
.
value
);
value
=
c
.
value
;
}
CopyOnlyInt
&
operator
=
(
const
CopyOnlyInt
&
c
)
{
print_copy_assigned
(
this
,
c
.
value
);
value
=
c
.
value
;
return
*
this
;
}
~
CopyOnlyInt
()
{
print_destroyed
(
this
);
}
...
...
@@ -107,8 +107,8 @@ public:
if
(
!
src
)
return
none
().
release
();
return
cast
(
*
src
,
policy
,
parent
);
}
operator
CopyOnlyInt
*
()
{
return
&
value
;
}
operator
CopyOnlyInt
&
()
{
return
value
;
}
explicit
operator
CopyOnlyInt
*
()
{
return
&
value
;
}
explicit
operator
CopyOnlyInt
&
()
{
return
value
;
}
template
<
typename
T
>
using
cast_op_type
=
pybind11
::
detail
::
cast_op_type
<
T
>
;
};
PYBIND11_NAMESPACE_END
(
detail
)
...
...
@@ -219,7 +219,7 @@ TEST_SUBMODULE(copy_move_policies, m) {
// #389: rvp::move should fall-through to copy on non-movable objects
struct
MoveIssue1
{
int
v
;
MoveIssue1
(
int
v
)
:
v
{
v
}
{}
explicit
MoveIssue1
(
int
v
)
:
v
{
v
}
{}
MoveIssue1
(
const
MoveIssue1
&
c
)
=
default
;
MoveIssue1
(
MoveIssue1
&&
)
=
delete
;
};
...
...
@@ -227,7 +227,7 @@ TEST_SUBMODULE(copy_move_policies, m) {
struct
MoveIssue2
{
int
v
;
MoveIssue2
(
int
v
)
:
v
{
v
}
{}
explicit
MoveIssue2
(
int
v
)
:
v
{
v
}
{}
MoveIssue2
(
MoveIssue2
&&
)
=
default
;
};
py
::
class_
<
MoveIssue2
>
(
m
,
"MoveIssue2"
).
def
(
py
::
init
<
int
>
()).
def_readwrite
(
"value"
,
&
MoveIssue2
::
v
);
...
...
tests/test_copy_move.py
View file @
e315e1fe
# -*- coding: utf-8 -*-
import
pytest
from
pybind11_tests
import
copy_move_policies
as
m
...
...
tests/test_custom_type_casters.py
View file @
e315e1fe
# -*- coding: utf-8 -*-
import
pytest
from
pybind11_tests
import
custom_type_casters
as
m
...
...
tests/test_custom_type_setup.cpp
0 → 100644
View file @
e315e1fe
/*
tests/test_custom_type_setup.cpp -- Tests `pybind11::custom_type_setup`
Copyright (c) Google LLC
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/pybind11.h>
#include "pybind11_tests.h"
namespace
py
=
pybind11
;
namespace
{
struct
OwnsPythonObjects
{
py
::
object
value
=
py
::
none
();
};
}
// namespace
TEST_SUBMODULE
(
custom_type_setup
,
m
)
{
py
::
class_
<
OwnsPythonObjects
>
cls
(
m
,
"OwnsPythonObjects"
,
py
::
custom_type_setup
([](
PyHeapTypeObject
*
heap_type
)
{
auto
*
type
=
&
heap_type
->
ht_type
;
type
->
tp_flags
|=
Py_TPFLAGS_HAVE_GC
;
type
->
tp_traverse
=
[](
PyObject
*
self_base
,
visitproc
visit
,
void
*
arg
)
{
auto
&
self
=
py
::
cast
<
OwnsPythonObjects
&>
(
py
::
handle
(
self_base
));
Py_VISIT
(
self
.
value
.
ptr
());
return
0
;
};
type
->
tp_clear
=
[](
PyObject
*
self_base
)
{
auto
&
self
=
py
::
cast
<
OwnsPythonObjects
&>
(
py
::
handle
(
self_base
));
self
.
value
=
py
::
none
();
return
0
;
};
}));
cls
.
def
(
py
::
init
<>
());
cls
.
def_readwrite
(
"value"
,
&
OwnsPythonObjects
::
value
);
}
tests/test_custom_type_setup.py
0 → 100644
View file @
e315e1fe
# -*- coding: utf-8 -*-
import
gc
import
weakref
import
pytest
import
env
# noqa: F401
from
pybind11_tests
import
custom_type_setup
as
m
@
pytest
.
fixture
def
gc_tester
():
"""Tests that an object is garbage collected.
Assumes that any unreferenced objects are fully collected after calling
`gc.collect()`. That is true on CPython, but does not appear to reliably
hold on PyPy.
"""
weak_refs
=
[]
def
add_ref
(
obj
):
# PyPy does not support `gc.is_tracked`.
if
hasattr
(
gc
,
"is_tracked"
):
assert
gc
.
is_tracked
(
obj
)
weak_refs
.
append
(
weakref
.
ref
(
obj
))
yield
add_ref
gc
.
collect
()
for
ref
in
weak_refs
:
assert
ref
()
is
None
# PyPy does not seem to reliably garbage collect.
@
pytest
.
mark
.
skipif
(
"env.PYPY"
)
def
test_self_cycle
(
gc_tester
):
obj
=
m
.
OwnsPythonObjects
()
obj
.
value
=
obj
gc_tester
(
obj
)
# PyPy does not seem to reliably garbage collect.
@
pytest
.
mark
.
skipif
(
"env.PYPY"
)
def
test_indirect_cycle
(
gc_tester
):
obj
=
m
.
OwnsPythonObjects
()
obj_list
=
[
obj
]
obj
.
value
=
obj_list
gc_tester
(
obj
)
tests/test_eigen.cpp
View file @
e315e1fe
...
...
@@ -178,6 +178,7 @@ TEST_SUBMODULE(eigen, m) {
ReturnTester
()
{
print_created
(
this
);
}
~
ReturnTester
()
{
print_destroyed
(
this
);
}
static
Eigen
::
MatrixXd
create
()
{
return
Eigen
::
MatrixXd
::
Ones
(
10
,
10
);
}
// NOLINTNEXTLINE(readability-const-return-type)
static
const
Eigen
::
MatrixXd
createConst
()
{
return
Eigen
::
MatrixXd
::
Ones
(
10
,
10
);
}
Eigen
::
MatrixXd
&
get
()
{
return
mat
;
}
Eigen
::
MatrixXd
*
getPtr
()
{
return
&
mat
;
}
...
...
@@ -244,6 +245,9 @@ TEST_SUBMODULE(eigen, m) {
// test_fixed, and various other tests
m
.
def
(
"fixed_r"
,
[
mat
]()
->
FixedMatrixR
{
return
FixedMatrixR
(
mat
);
});
// Our Eigen does a hack which respects constness through the numpy writeable flag.
// Therefore, the const return actually affects this type despite being an rvalue.
// NOLINTNEXTLINE(readability-const-return-type)
m
.
def
(
"fixed_r_const"
,
[
mat
]()
->
const
FixedMatrixR
{
return
FixedMatrixR
(
mat
);
});
m
.
def
(
"fixed_c"
,
[
mat
]()
->
FixedMatrixC
{
return
FixedMatrixC
(
mat
);
});
m
.
def
(
"fixed_copy_r"
,
[](
const
FixedMatrixR
&
m
)
->
FixedMatrixR
{
return
m
;
});
...
...
tests/test_eigen.py
View file @
e315e1fe
# -*- coding: utf-8 -*-
import
pytest
from
pybind11_tests
import
ConstructorStats
np
=
pytest
.
importorskip
(
"numpy"
)
...
...
tests/test_embed/CMakeLists.txt
View file @
e315e1fe
...
...
@@ -31,6 +31,7 @@ endif()
add_custom_target
(
cpptest
COMMAND
"$<TARGET_FILE:test_embed>"
DEPENDS test_embed
WORKING_DIRECTORY
"
${
CMAKE_CURRENT_BINARY_DIR
}
"
)
pybind11_add_module
(
external_module THIN_LTO external_module.cpp
)
...
...
tests/test_embed/external_module.cpp
View file @
e315e1fe
...
...
@@ -9,7 +9,7 @@ namespace py = pybind11;
PYBIND11_MODULE
(
external_module
,
m
)
{
class
A
{
public:
A
(
int
value
)
:
v
{
value
}
{};
explicit
A
(
int
value
)
:
v
{
value
}
{};
int
v
;
};
...
...
tests/test_embed/test_interpreter.cpp
View file @
e315e1fe
...
...
@@ -8,6 +8,7 @@
#include <catch.hpp>
#include <cstdlib>
#include <fstream>
#include <functional>
#include <thread>
...
...
@@ -18,11 +19,12 @@ using namespace py::literals;
class
Widget
{
public:
Widget
(
std
::
string
message
)
:
message
(
std
::
move
(
message
))
{}
explicit
Widget
(
std
::
string
message
)
:
message
(
std
::
move
(
message
))
{}
virtual
~
Widget
()
=
default
;
std
::
string
the_message
()
const
{
return
message
;
}
virtual
int
the_answer
()
const
=
0
;
virtual
std
::
string
argv0
()
const
=
0
;
private:
std
::
string
message
;
...
...
@@ -32,6 +34,7 @@ class PyWidget final : public Widget {
using
Widget
::
Widget
;
int
the_answer
()
const
override
{
PYBIND11_OVERRIDE_PURE
(
int
,
Widget
,
the_answer
);
}
std
::
string
argv0
()
const
override
{
PYBIND11_OVERRIDE_PURE
(
std
::
string
,
Widget
,
argv0
);
}
};
PYBIND11_EMBEDDED_MODULE
(
widget_module
,
m
)
{
...
...
@@ -74,8 +77,24 @@ TEST_CASE("Import error handling") {
REQUIRE_NOTHROW
(
py
::
module_
::
import
(
"widget_module"
));
REQUIRE_THROWS_WITH
(
py
::
module_
::
import
(
"throw_exception"
),
"ImportError: C++ Error"
);
#if PY_VERSION_HEX >= 0x03030000
REQUIRE_THROWS_WITH
(
py
::
module_
::
import
(
"throw_error_already_set"
),
Catch
::
Contains
(
"ImportError: initialization failed"
));
auto
locals
=
py
::
dict
(
"is_keyerror"
_a
=
false
,
"message"
_a
=
"not set"
);
py
::
exec
(
R"(
try:
import throw_error_already_set
except ImportError as e:
is_keyerror = type(e.__cause__) == KeyError
message = str(e.__cause__)
)"
,
py
::
globals
(),
locals
);
REQUIRE
(
locals
[
"is_keyerror"
].
cast
<
bool
>
()
==
true
);
REQUIRE
(
locals
[
"message"
].
cast
<
std
::
string
>
()
==
"'missing'"
);
#else
REQUIRE_THROWS_WITH
(
py
::
module_
::
import
(
"throw_error_already_set"
),
Catch
::
Contains
(
"ImportError: KeyError"
));
#endif
}
TEST_CASE
(
"There can be only one interpreter"
)
{
...
...
@@ -283,3 +302,25 @@ TEST_CASE("Reload module from file") {
result
=
module_
.
attr
(
"test"
)().
cast
<
int
>
();
REQUIRE
(
result
==
2
);
}
TEST_CASE
(
"sys.argv gets initialized properly"
)
{
py
::
finalize_interpreter
();
{
py
::
scoped_interpreter
default_scope
;
auto
module
=
py
::
module
::
import
(
"test_interpreter"
);
auto
py_widget
=
module
.
attr
(
"DerivedWidget"
)(
"The question"
);
const
auto
&
cpp_widget
=
py_widget
.
cast
<
const
Widget
&>
();
REQUIRE
(
cpp_widget
.
argv0
().
empty
());
}
{
char
*
argv
[]
=
{
strdup
(
"a.out"
)};
py
::
scoped_interpreter
argv_scope
(
true
,
1
,
argv
);
std
::
free
(
argv
[
0
]);
auto
module
=
py
::
module
::
import
(
"test_interpreter"
);
auto
py_widget
=
module
.
attr
(
"DerivedWidget"
)(
"The question"
);
const
auto
&
cpp_widget
=
py_widget
.
cast
<
const
Widget
&>
();
REQUIRE
(
cpp_widget
.
argv0
()
==
"a.out"
);
}
py
::
initialize_interpreter
();
}
tests/test_embed/test_interpreter.py
View file @
e315e1fe
# -*- coding: utf-8 -*-
import
sys
from
widget_module
import
Widget
...
...
@@ -8,3 +10,6 @@ class DerivedWidget(Widget):
def
the_answer
(
self
):
return
42
def
argv0
(
self
):
return
sys
.
argv
[
0
]
tests/test_enum.cpp
View file @
e315e1fe
...
...
@@ -84,4 +84,65 @@ TEST_SUBMODULE(enums, m) {
.
value
(
"ONE"
,
SimpleEnum
::
THREE
)
.
export_values
();
});
// test_enum_scalar
enum
UnscopedUCharEnum
:
unsigned
char
{};
enum
class
ScopedShortEnum
:
short
{};
enum
class
ScopedLongEnum
:
long
{};
enum
UnscopedUInt64Enum
:
std
::
uint64_t
{};
static_assert
(
py
::
detail
::
all_of
<
std
::
is_same
<
py
::
enum_
<
UnscopedUCharEnum
>::
Scalar
,
unsigned
char
>
,
std
::
is_same
<
py
::
enum_
<
ScopedShortEnum
>::
Scalar
,
short
>
,
std
::
is_same
<
py
::
enum_
<
ScopedLongEnum
>::
Scalar
,
long
>
,
std
::
is_same
<
py
::
enum_
<
UnscopedUInt64Enum
>::
Scalar
,
std
::
uint64_t
>
>::
value
,
"Error during the deduction of enum's scalar type with normal integer underlying"
);
// test_enum_scalar_with_char_underlying
enum
class
ScopedCharEnum
:
char
{
Zero
,
Positive
};
enum
class
ScopedWCharEnum
:
wchar_t
{
Zero
,
Positive
};
enum
class
ScopedChar32Enum
:
char32_t
{
Zero
,
Positive
};
enum
class
ScopedChar16Enum
:
char16_t
{
Zero
,
Positive
};
// test the scalar of char type enums according to chapter 'Character types'
// from https://en.cppreference.com/w/cpp/language/types
static_assert
(
py
::
detail
::
any_of
<
std
::
is_same
<
py
::
enum_
<
ScopedCharEnum
>::
Scalar
,
signed
char
>
,
// e.g. gcc on x86
std
::
is_same
<
py
::
enum_
<
ScopedCharEnum
>::
Scalar
,
unsigned
char
>
// e.g. arm linux
>::
value
,
"char should be cast to either signed char or unsigned char"
);
static_assert
(
sizeof
(
py
::
enum_
<
ScopedWCharEnum
>::
Scalar
)
==
2
||
sizeof
(
py
::
enum_
<
ScopedWCharEnum
>::
Scalar
)
==
4
,
"wchar_t should be either 16 bits (Windows) or 32 (everywhere else)"
);
static_assert
(
py
::
detail
::
all_of
<
std
::
is_same
<
py
::
enum_
<
ScopedChar32Enum
>::
Scalar
,
std
::
uint_least32_t
>
,
std
::
is_same
<
py
::
enum_
<
ScopedChar16Enum
>::
Scalar
,
std
::
uint_least16_t
>
>::
value
,
"char32_t, char16_t (and char8_t)'s size, signedness, and alignment is determined"
);
#if defined(PYBIND11_HAS_U8STRING)
enum
class
ScopedChar8Enum
:
char8_t
{
Zero
,
Positive
};
static_assert
(
std
::
is_same
<
py
::
enum_
<
ScopedChar8Enum
>::
Scalar
,
unsigned
char
>::
value
);
#endif
// test_char_underlying_enum
py
::
enum_
<
ScopedCharEnum
>
(
m
,
"ScopedCharEnum"
)
.
value
(
"Zero"
,
ScopedCharEnum
::
Zero
)
.
value
(
"Positive"
,
ScopedCharEnum
::
Positive
);
py
::
enum_
<
ScopedWCharEnum
>
(
m
,
"ScopedWCharEnum"
)
.
value
(
"Zero"
,
ScopedWCharEnum
::
Zero
)
.
value
(
"Positive"
,
ScopedWCharEnum
::
Positive
);
py
::
enum_
<
ScopedChar32Enum
>
(
m
,
"ScopedChar32Enum"
)
.
value
(
"Zero"
,
ScopedChar32Enum
::
Zero
)
.
value
(
"Positive"
,
ScopedChar32Enum
::
Positive
);
py
::
enum_
<
ScopedChar16Enum
>
(
m
,
"ScopedChar16Enum"
)
.
value
(
"Zero"
,
ScopedChar16Enum
::
Zero
)
.
value
(
"Positive"
,
ScopedChar16Enum
::
Positive
);
// test_bool_underlying_enum
enum
class
ScopedBoolEnum
:
bool
{
FALSE
,
TRUE
};
// bool is unsigned (std::is_signed returns false) and 1-byte long, so represented with u8
static_assert
(
std
::
is_same
<
py
::
enum_
<
ScopedBoolEnum
>::
Scalar
,
std
::
uint8_t
>::
value
,
""
);
py
::
enum_
<
ScopedBoolEnum
>
(
m
,
"ScopedBoolEnum"
)
.
value
(
"FALSE"
,
ScopedBoolEnum
::
FALSE
)
.
value
(
"TRUE"
,
ScopedBoolEnum
::
TRUE
);
}
tests/test_enum.py
View file @
e315e1fe
# -*- coding: utf-8 -*-
import
pytest
import
env
from
pybind11_tests
import
enums
as
m
...
...
@@ -217,10 +219,16 @@ def test_binary_operators():
def
test_enum_to_int
():
m
.
test_enum_to_int
(
m
.
Flags
.
Read
)
m
.
test_enum_to_int
(
m
.
ClassWithUnscopedEnum
.
EMode
.
EFirstMode
)
m
.
test_enum_to_int
(
m
.
ScopedCharEnum
.
Positive
)
m
.
test_enum_to_int
(
m
.
ScopedBoolEnum
.
TRUE
)
m
.
test_enum_to_uint
(
m
.
Flags
.
Read
)
m
.
test_enum_to_uint
(
m
.
ClassWithUnscopedEnum
.
EMode
.
EFirstMode
)
m
.
test_enum_to_uint
(
m
.
ScopedCharEnum
.
Positive
)
m
.
test_enum_to_uint
(
m
.
ScopedBoolEnum
.
TRUE
)
m
.
test_enum_to_long_long
(
m
.
Flags
.
Read
)
m
.
test_enum_to_long_long
(
m
.
ClassWithUnscopedEnum
.
EMode
.
EFirstMode
)
m
.
test_enum_to_long_long
(
m
.
ScopedCharEnum
.
Positive
)
m
.
test_enum_to_long_long
(
m
.
ScopedBoolEnum
.
TRUE
)
def
test_duplicate_enum_name
():
...
...
@@ -229,6 +237,34 @@ def test_duplicate_enum_name():
assert
str
(
excinfo
.
value
)
==
'SimpleEnum: element "ONE" already exists!'
def
test_char_underlying_enum
():
# Issue #1331/PR #1334:
assert
type
(
m
.
ScopedCharEnum
.
Positive
.
__int__
())
is
int
assert
int
(
m
.
ScopedChar16Enum
.
Zero
)
==
0
assert
hash
(
m
.
ScopedChar32Enum
.
Positive
)
==
1
if
env
.
PY2
:
assert
m
.
ScopedCharEnum
.
Positive
.
__getstate__
()
==
1
# long
else
:
assert
type
(
m
.
ScopedCharEnum
.
Positive
.
__getstate__
())
is
int
assert
m
.
ScopedWCharEnum
(
1
)
==
m
.
ScopedWCharEnum
.
Positive
with
pytest
.
raises
(
TypeError
):
# Even if the underlying type is char, only an int can be used to construct the enum:
m
.
ScopedCharEnum
(
"0"
)
def
test_bool_underlying_enum
():
assert
type
(
m
.
ScopedBoolEnum
.
TRUE
.
__int__
())
is
int
assert
int
(
m
.
ScopedBoolEnum
.
FALSE
)
==
0
assert
hash
(
m
.
ScopedBoolEnum
.
TRUE
)
==
1
if
env
.
PY2
:
assert
m
.
ScopedBoolEnum
.
TRUE
.
__getstate__
()
==
1
# long
else
:
assert
type
(
m
.
ScopedBoolEnum
.
TRUE
.
__getstate__
())
is
int
assert
m
.
ScopedBoolEnum
(
1
)
==
m
.
ScopedBoolEnum
.
TRUE
# Enum could construct with a bool
# (bool is a strict subclass of int, and False will be converted to 0)
assert
m
.
ScopedBoolEnum
(
False
)
==
m
.
ScopedBoolEnum
.
FALSE
def
test_docstring_signatures
():
for
enum_type
in
[
m
.
ScopedEnum
,
m
.
UnscopedEnum
]:
for
attr
in
enum_type
.
__dict__
.
values
():
...
...
tests/test_eval.cpp
View file @
e315e1fe
...
...
@@ -98,4 +98,22 @@ TEST_SUBMODULE(eval_, m) {
auto
int_class
=
py
::
eval
(
"isinstance(42, int)"
,
global
);
return
global
;
});
// test_eval_closure
m
.
def
(
"test_eval_closure"
,
[]()
{
py
::
dict
global
;
global
[
"closure_value"
]
=
42
;
py
::
dict
local
;
local
[
"closure_value"
]
=
0
;
py
::
exec
(
R"(
local_value = closure_value
def func_global():
return closure_value
def func_local():
return local_value
)"
,
global
,
local
);
return
std
::
make_pair
(
global
,
local
);
});
}
Prev
1
2
3
4
5
6
7
8
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