Commit 93716147 authored by Henry Schreiner's avatar Henry Schreiner
Browse files

Merge branch 'master' into stable

parents acae9301 45f792ef
......@@ -36,6 +36,10 @@ def test_from_python():
# https://foss.heptapod.net/pypy/pypy/-/issues/2444
# TODO: fix on recent PyPy
@pytest.mark.xfail(
env.PYPY, reason="PyPy 7.3.7 doesn't clear this anymore", strict=False
)
def test_to_python():
mat = m.Matrix(5, 4)
assert memoryview(mat).shape == (5, 4)
......
......@@ -19,7 +19,7 @@ PYBIND11_NAMESPACE_BEGIN(detail)
template <>
class type_caster<ConstRefCasted> {
public:
static constexpr auto name = _<ConstRefCasted>();
static constexpr auto name = const_name<ConstRefCasted>();
// Input is unimportant, a new value will always be constructed based on the
// cast operator.
......@@ -140,11 +140,35 @@ TEST_SUBMODULE(builtin_casters, m) {
m.def("string_view16_return", []() { return std::u16string_view(u"utf16 secret \U0001f382"); });
m.def("string_view32_return", []() { return std::u32string_view(U"utf32 secret \U0001f382"); });
// The inner lambdas here are to also test implicit conversion
using namespace std::literals;
m.def("string_view_bytes", []() { return [](py::bytes b) { return b; }("abc \x80\x80 def"sv); });
m.def("string_view_str", []() { return [](py::str s) { return s; }("abc \342\200\275 def"sv); });
m.def("string_view_from_bytes", [](const py::bytes &b) { return [](std::string_view s) { return s; }(b); });
#if PY_MAJOR_VERSION >= 3
m.def("string_view_memoryview", []() {
static constexpr auto val = "Have some \360\237\216\202"sv;
return py::memoryview::from_memory(val);
});
#endif
# ifdef PYBIND11_HAS_U8STRING
m.def("string_view8_print", [](std::u8string_view s) { py::print(s, s.size()); });
m.def("string_view8_chars", [](std::u8string_view s) { py::list l; for (auto c : s) l.append((std::uint8_t) c); return l; });
m.def("string_view8_return", []() { return std::u8string_view(u8"utf8 secret \U0001f382"); });
m.def("string_view8_str", []() { return py::str{std::u8string_view{u8"abc ‽ def"}}; });
# endif
struct TypeWithBothOperatorStringAndStringView {
// NOLINTNEXTLINE(google-explicit-constructor)
operator std::string() const { return "success"; }
// NOLINTNEXTLINE(google-explicit-constructor)
operator std::string_view() const { return "failure"; }
};
m.def("bytes_from_type_with_both_operator_string_and_string_view",
[]() { return py::bytes(TypeWithBothOperatorStringAndStringView()); });
m.def("str_from_type_with_both_operator_string_and_string_view",
[]() { return py::str(TypeWithBothOperatorStringAndStringView()); });
#endif
// test_integer_casting
......
......@@ -206,6 +206,17 @@ def test_string_view(capture):
"""
)
assert m.string_view_bytes() == b"abc \x80\x80 def"
assert m.string_view_str() == u"abc ‽ def"
assert m.string_view_from_bytes(u"abc ‽ def".encode("utf-8")) == u"abc ‽ def"
if hasattr(m, "has_u8string"):
assert m.string_view8_str() == u"abc ‽ def"
if not env.PY2:
assert m.string_view_memoryview() == "Have some 🎂".encode()
assert m.bytes_from_type_with_both_operator_string_and_string_view() == b"success"
assert m.str_from_type_with_both_operator_string_and_string_view() == "success"
def test_integer_casting():
"""Issue #929 - out-of-range integer values shouldn't be accepted"""
......@@ -299,7 +310,8 @@ def test_int_convert():
assert noconvert(7) == 7
cant_convert(3.14159)
# TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
if (3, 8) <= env.PY < (3, 10):
# TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
if (3, 8) <= env.PY < (3, 10) and env.CPYTHON:
with env.deprecated_call():
assert convert(Int()) == 42
else:
......@@ -334,7 +346,9 @@ def test_numpy_int_convert():
# The implicit conversion from np.float32 is undesirable but currently accepted.
# TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
if (3, 8) <= env.PY < (3, 10):
# TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
# https://github.com/pybind/pybind11/issues/3408
if (3, 8) <= env.PY < (3, 10) and env.CPYTHON:
with env.deprecated_call():
assert convert(np.float32(3.14159)) == 3
else:
......
......@@ -85,13 +85,13 @@ public:
PYBIND11_NAMESPACE_BEGIN(pybind11)
PYBIND11_NAMESPACE_BEGIN(detail)
template <> struct type_caster<MoveOnlyInt> {
PYBIND11_TYPE_CASTER(MoveOnlyInt, _("MoveOnlyInt"));
PYBIND11_TYPE_CASTER(MoveOnlyInt, const_name("MoveOnlyInt"));
bool load(handle src, bool) { value = MoveOnlyInt(src.cast<int>()); return true; }
static handle cast(const MoveOnlyInt &m, return_value_policy r, handle p) { return pybind11::cast(m.value, r, p); }
};
template <> struct type_caster<MoveOrCopyInt> {
PYBIND11_TYPE_CASTER(MoveOrCopyInt, _("MoveOrCopyInt"));
PYBIND11_TYPE_CASTER(MoveOrCopyInt, const_name("MoveOrCopyInt"));
bool load(handle src, bool) { value = MoveOrCopyInt(src.cast<int>()); return true; }
static handle cast(const MoveOrCopyInt &m, return_value_policy r, handle p) { return pybind11::cast(m.value, r, p); }
};
......@@ -100,7 +100,7 @@ template <> struct type_caster<CopyOnlyInt> {
protected:
CopyOnlyInt value;
public:
static constexpr auto name = _("CopyOnlyInt");
static constexpr auto name = const_name("CopyOnlyInt");
bool load(handle src, bool) { value = CopyOnlyInt(src.cast<int>()); return true; }
static handle cast(const CopyOnlyInt &m, return_value_policy r, handle p) { return pybind11::cast(m.value, r, p); }
static handle cast(const CopyOnlyInt *src, return_value_policy policy, handle parent) {
......
......@@ -18,7 +18,12 @@ class ArgAlwaysConverts { };
namespace pybind11 { namespace detail {
template <> struct type_caster<ArgInspector1> {
public:
// Classic
#ifndef _
PYBIND11_TYPE_CASTER(ArgInspector1, _("ArgInspector1"));
#else
PYBIND11_TYPE_CASTER(ArgInspector1, const_name("ArgInspector1"));
#endif
bool load(handle src, bool convert) {
value.arg = "loading ArgInspector1 argument " +
......@@ -33,7 +38,7 @@ public:
};
template <> struct type_caster<ArgInspector2> {
public:
PYBIND11_TYPE_CASTER(ArgInspector2, _("ArgInspector2"));
PYBIND11_TYPE_CASTER(ArgInspector2, const_name("ArgInspector2"));
bool load(handle src, bool convert) {
value.arg = "loading ArgInspector2 argument " +
......@@ -48,7 +53,7 @@ public:
};
template <> struct type_caster<ArgAlwaysConverts> {
public:
PYBIND11_TYPE_CASTER(ArgAlwaysConverts, _("ArgAlwaysConverts"));
PYBIND11_TYPE_CASTER(ArgAlwaysConverts, const_name("ArgAlwaysConverts"));
bool load(handle, bool convert) {
return convert;
......@@ -76,7 +81,7 @@ public:
};
namespace pybind11 { namespace detail {
template <> struct type_caster<DestructionTester> {
PYBIND11_TYPE_CASTER(DestructionTester, _("DestructionTester"));
PYBIND11_TYPE_CASTER(DestructionTester, const_name("DestructionTester"));
bool load(handle, bool) { return true; }
static handle cast(const DestructionTester &, return_value_policy, handle) {
......
......@@ -25,7 +25,7 @@ pybind11_enable_warnings(test_embed)
target_link_libraries(test_embed PRIVATE pybind11::embed Catch2::Catch2 Threads::Threads)
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
file(COPY test_interpreter.py DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
file(COPY test_interpreter.py test_trampoline.py DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
endif()
add_custom_target(
......
......@@ -37,6 +37,22 @@ class PyWidget final : public Widget {
std::string argv0() const override { PYBIND11_OVERRIDE_PURE(std::string, Widget, argv0); }
};
class test_override_cache_helper {
public:
virtual int func() { return 0; }
test_override_cache_helper() = default;
virtual ~test_override_cache_helper() = default;
// Non-copyable
test_override_cache_helper &operator=(test_override_cache_helper const &Right) = delete;
test_override_cache_helper(test_override_cache_helper const &Copy) = delete;
};
class test_override_cache_helper_trampoline : public test_override_cache_helper {
int func() override { PYBIND11_OVERRIDE(int, test_override_cache_helper, func); }
};
PYBIND11_EMBEDDED_MODULE(widget_module, m) {
py::class_<Widget, PyWidget>(m, "Widget")
.def(py::init<std::string>())
......@@ -45,6 +61,12 @@ PYBIND11_EMBEDDED_MODULE(widget_module, m) {
m.def("add", [](int i, int j) { return i + j; });
}
PYBIND11_EMBEDDED_MODULE(trampoline_module, m) {
py::class_<test_override_cache_helper, test_override_cache_helper_trampoline, std::shared_ptr<test_override_cache_helper>>(m, "test_override_cache_helper")
.def(py::init_alias<>())
.def("func", &test_override_cache_helper::func);
}
PYBIND11_EMBEDDED_MODULE(throw_exception, ) {
throw std::runtime_error("C++ Error");
}
......@@ -73,6 +95,33 @@ TEST_CASE("Pass classes and data between modules defined in C++ and Python") {
REQUIRE(cpp_widget.the_answer() == 42);
}
TEST_CASE("Override cache") {
auto module_ = py::module_::import("test_trampoline");
REQUIRE(py::hasattr(module_, "func"));
REQUIRE(py::hasattr(module_, "func2"));
auto locals = py::dict(**module_.attr("__dict__"));
int i = 0;
for (; i < 1500; ++i) {
std::shared_ptr<test_override_cache_helper> p_obj;
std::shared_ptr<test_override_cache_helper> p_obj2;
py::object loc_inst = locals["func"]();
p_obj = py::cast<std::shared_ptr<test_override_cache_helper>>(loc_inst);
int ret = p_obj->func();
REQUIRE(ret == 42);
loc_inst = locals["func2"]();
p_obj2 = py::cast<std::shared_ptr<test_override_cache_helper>>(loc_inst);
p_obj2->func();
}
}
TEST_CASE("Import error handling") {
REQUIRE_NOTHROW(py::module_::import("widget_module"));
REQUIRE_THROWS_WITH(py::module_::import("throw_exception"),
......
# -*- coding: utf-8 -*-
import trampoline_module
def func():
class Test(trampoline_module.test_override_cache_helper):
def func(self):
return 42
return Test()
def func2():
class Test(trampoline_module.test_override_cache_helper):
pass
return Test()
......@@ -3,7 +3,7 @@ import sys
import pytest
import env # noqa: F401
import env
import pybind11_cross_module_tests as cm
from pybind11_tests import exceptions as m
......@@ -97,6 +97,8 @@ def ignore_pytest_unraisable_warning(f):
return f
# TODO: find out why this fails on PyPy, https://foss.heptapod.net/pypy/pypy/-/issues/3583
@pytest.mark.xfail(env.PYPY, reason="Failure on PyPy 3.8 (7.3.7)", strict=False)
@ignore_pytest_unraisable_warning
def test_python_alreadyset_in_destructor(monkeypatch, capsys):
hooked = False
......
......@@ -56,6 +56,23 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
m.def("mixed_plus_args_kwargs_defaults", mixed_plus_both,
py::arg("i") = 1, py::arg("j") = 3.14159);
m.def("args_kwonly",
[](int i, double j, const py::args &args, int z) { return py::make_tuple(i, j, args, z); },
"i"_a, "j"_a, "z"_a);
m.def("args_kwonly_kwargs",
[](int i, double j, const py::args &args, int z, const py::kwargs &kwargs) {
return py::make_tuple(i, j, args, z, kwargs); },
"i"_a, "j"_a, py::kw_only{}, "z"_a);
m.def("args_kwonly_kwargs_defaults",
[](int i, double j, const py::args &args, int z, const py::kwargs &kwargs) {
return py::make_tuple(i, j, args, z, kwargs); },
"i"_a = 1, "j"_a = 3.14159, "z"_a = 42);
m.def("args_kwonly_full_monty",
[](int h, int i, double j, const py::args &args, int z, const py::kwargs &kwargs) {
return py::make_tuple(h, i, j, args, z, kwargs); },
py::arg() = 1, py::arg() = 2, py::pos_only{}, "j"_a = 3.14159, "z"_a = 42);
// test_args_refcount
// PyPy needs a garbage collection to get the reference count values to match CPython's behaviour
#ifdef PYPY_VERSION
......@@ -150,4 +167,21 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
"class_default_argument",
[](py::object a) { return py::repr(std::move(a)); },
"a"_a = py::module_::import("decimal").attr("Decimal"));
// Initial implementation of kw_only was broken when used on a method/constructor before any
// other arguments
// https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987
struct first_arg_kw_only {};
py::class_<first_arg_kw_only>(m, "first_arg_kw_only")
.def(py::init([](int) { return first_arg_kw_only(); }),
py::kw_only(), // This being before any args was broken
py::arg("i") = 0)
.def("method", [](first_arg_kw_only&, int, int) {},
py::kw_only(), // and likewise here
py::arg("i") = 1, py::arg("j") = 2)
// Closely related: pos_only marker didn't show up properly when it was before any other
// arguments (although that is fairly useless in practice).
.def("pos_only", [](first_arg_kw_only&, int, int) {},
py::pos_only{}, py::arg("i"), py::arg("j"));
}
......@@ -141,6 +141,53 @@ def test_mixed_args_and_kwargs(msg):
""" # noqa: E501 line too long
)
# Arguments after a py::args are automatically keyword-only (pybind 2.9+)
assert m.args_kwonly(2, 2.5, z=22) == (2, 2.5, (), 22)
assert m.args_kwonly(2, 2.5, "a", "b", "c", z=22) == (2, 2.5, ("a", "b", "c"), 22)
assert m.args_kwonly(z=22, i=4, j=16) == (4, 16, (), 22)
with pytest.raises(TypeError) as excinfo:
assert m.args_kwonly(2, 2.5, 22) # missing z= keyword
assert (
msg(excinfo.value)
== """
args_kwonly(): incompatible function arguments. The following argument types are supported:
1. (i: int, j: float, *args, z: int) -> tuple
Invoked with: 2, 2.5, 22
"""
)
assert m.args_kwonly_kwargs(i=1, k=4, j=10, z=-1, y=9) == (
1,
10,
(),
-1,
{"k": 4, "y": 9},
)
assert m.args_kwonly_kwargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, z=11, y=12) == (
1,
2,
(3, 4, 5, 6, 7, 8, 9, 10),
11,
{"y": 12},
)
assert (
m.args_kwonly_kwargs.__doc__
== "args_kwonly_kwargs(i: int, j: float, *args, z: int, **kwargs) -> tuple\n"
)
assert (
m.args_kwonly_kwargs_defaults.__doc__
== "args_kwonly_kwargs_defaults(i: int = 1, j: float = 3.14159, *args, z: int = 42, **kwargs) -> tuple\n" # noqa: E501 line too long
)
assert m.args_kwonly_kwargs_defaults() == (1, 3.14159, (), 42, {})
assert m.args_kwonly_kwargs_defaults(2) == (2, 3.14159, (), 42, {})
assert m.args_kwonly_kwargs_defaults(z=-99) == (1, 3.14159, (), -99, {})
assert m.args_kwonly_kwargs_defaults(5, 6, 7, 8) == (5, 6, (7, 8), 42, {})
assert m.args_kwonly_kwargs_defaults(5, 6, 7, m=8) == (5, 6, (7,), 42, {"m": 8})
assert m.args_kwonly_kwargs_defaults(5, 6, 7, m=8, z=9) == (5, 6, (7,), 9, {"m": 8})
def test_keyword_only_args(msg):
assert m.kw_only_all(i=1, j=2) == (1, 2)
......@@ -178,10 +225,23 @@ def test_keyword_only_args(msg):
assert (
msg(excinfo.value)
== """
arg(): cannot specify an unnamed argument after an kw_only() annotation
arg(): cannot specify an unnamed argument after a kw_only() annotation or args() argument
"""
)
# https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987
x = m.first_arg_kw_only(i=1)
x.method()
x.method(i=1, j=2)
assert (
m.first_arg_kw_only.__init__.__doc__
== "__init__(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: int = 0) -> None\n" # noqa: E501 line too long
)
assert (
m.first_arg_kw_only.method.__doc__
== "method(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: int = 1, j: int = 2) -> None\n" # noqa: E501 line too long
)
def test_positional_only_args(msg):
assert m.pos_only_all(1, 2) == (1, 2)
......@@ -222,6 +282,55 @@ def test_positional_only_args(msg):
m.pos_only_def_mix(1, j=4)
assert "incompatible function arguments" in str(excinfo.value)
# Mix it with args and kwargs:
assert (
m.args_kwonly_full_monty.__doc__
== "args_kwonly_full_monty(arg0: int = 1, arg1: int = 2, /, j: float = 3.14159, *args, z: int = 42, **kwargs) -> tuple\n" # noqa: E501 line too long
)
assert m.args_kwonly_full_monty() == (1, 2, 3.14159, (), 42, {})
assert m.args_kwonly_full_monty(8) == (8, 2, 3.14159, (), 42, {})
assert m.args_kwonly_full_monty(8, 9) == (8, 9, 3.14159, (), 42, {})
assert m.args_kwonly_full_monty(8, 9, 10) == (8, 9, 10.0, (), 42, {})
assert m.args_kwonly_full_monty(3, 4, 5, 6, 7, m=8, z=9) == (
3,
4,
5.0,
(
6,
7,
),
9,
{"m": 8},
)
assert m.args_kwonly_full_monty(3, 4, 5, 6, 7, m=8, z=9) == (
3,
4,
5.0,
(
6,
7,
),
9,
{"m": 8},
)
assert m.args_kwonly_full_monty(5, j=7, m=8, z=9) == (5, 2, 7.0, (), 9, {"m": 8})
assert m.args_kwonly_full_monty(i=5, j=7, m=8, z=9) == (
1,
2,
7.0,
(),
9,
{"i": 5, "m": 8},
)
# pos_only at the beginning of the argument list was "broken" in how it was displayed (though
# this is fairly useless in practice). Related to:
# https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987
assert (
m.first_arg_kw_only.pos_only.__doc__
== "pos_only(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, /, i: int, j: int) -> None\n" # noqa: E501 line too long
)
def test_signatures():
assert "kw_only_all(*, i: int, j: int) -> tuple\n" == m.kw_only_all.__doc__
......
......@@ -159,6 +159,14 @@ struct RefQualified {
int constRefQualified(int other) const & { return value + other; }
};
// Test rvalue ref param
struct RValueRefParam {
std::size_t func1(std::string&& s) { return s.size(); }
std::size_t func2(std::string&& s) const { return s.size(); }
std::size_t func3(std::string&& s) & { return s.size(); }
std::size_t func4(std::string&& s) const & { return s.size(); }
};
TEST_SUBMODULE(methods_and_attributes, m) {
// test_methods_and_attributes
py::class_<ExampleMandA> emna(m, "ExampleMandA");
......@@ -409,4 +417,11 @@ TEST_SUBMODULE(methods_and_attributes, m) {
.def_readonly("value", &RefQualified::value)
.def("refQualified", &RefQualified::refQualified)
.def("constRefQualified", &RefQualified::constRefQualified);
py::class_<RValueRefParam>(m, "RValueRefParam")
.def(py::init<>())
.def("func1", &RValueRefParam::func1)
.def("func2", &RValueRefParam::func2)
.def("func3", &RValueRefParam::func3)
.def("func4", &RValueRefParam::func4);
}
......@@ -515,3 +515,11 @@ def test_overload_ordering():
assert "2. (arg0: {}) -> int".format(uni_name) in str(err.value)
assert "3. (arg0: {}) -> int".format(uni_name) in str(err.value)
assert "4. (arg0: int) -> int" in str(err.value)
def test_rvalue_ref_param():
r = m.RValueRefParam()
assert r.func1("123") == 3
assert r.func2("1234") == 4
assert r.func3("12345") == 5
assert r.func4("123456") == 6
......@@ -214,6 +214,25 @@ static void test_gil_from_thread() {
t.join();
}
class test_override_cache_helper {
public:
virtual int func() { return 0; }
test_override_cache_helper() = default;
virtual ~test_override_cache_helper() = default;
// Non-copyable
test_override_cache_helper &operator=(test_override_cache_helper const &Right) = delete;
test_override_cache_helper(test_override_cache_helper const &Copy) = delete;
};
class test_override_cache_helper_trampoline : public test_override_cache_helper {
int func() override { PYBIND11_OVERRIDE(int, test_override_cache_helper, func); }
};
inline int test_override_cache(std::shared_ptr<test_override_cache_helper> const &instance) { return instance->func(); }
// Forward declaration (so that we can put the main tests here; the inherited virtual approaches are
// rather long).
......@@ -378,6 +397,12 @@ TEST_SUBMODULE(virtual_functions, m) {
// .def("str_ref", &OverrideTest::str_ref)
.def("A_value", &OverrideTest::A_value)
.def("A_ref", &OverrideTest::A_ref);
py::class_<test_override_cache_helper, test_override_cache_helper_trampoline, std::shared_ptr<test_override_cache_helper>>(m, "test_override_cache_helper")
.def(py::init_alias<>())
.def("func", &test_override_cache_helper::func);
m.def("test_override_cache", test_override_cache);
}
......
......@@ -439,3 +439,22 @@ def test_issue_1454():
# Fix issue #1454 (crash when acquiring/releasing GIL on another thread in Python 2.7)
m.test_gil()
m.test_gil_from_thread()
def test_python_override():
def func():
class Test(m.test_override_cache_helper):
def func(self):
return 42
return Test()
def func2():
class Test(m.test_override_cache_helper):
pass
return Test()
for _ in range(1500):
assert m.test_override_cache(func()) == 42
assert m.test_override_cache(func2()) == 0
......@@ -318,13 +318,21 @@ function(_pybind11_generate_lto target prefer_thin_lto)
set(cxx_append ";-fno-fat-lto-objects")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND prefer_thin_lto)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le" OR CMAKE_SYSTEM_PROCESSOR MATCHES "mips64")
set(NO_FLTO_ARCH TRUE)
else()
set(NO_FLTO_ARCH FALSE)
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang"
AND prefer_thin_lto
AND NOT NO_FLTO_ARCH)
_pybind11_return_if_cxx_and_linker_flags_work(
HAS_FLTO_THIN "-flto=thin${cxx_append}" "-flto=thin${linker_append}"
PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
endif()
if(NOT HAS_FLTO_THIN)
if(NOT HAS_FLTO_THIN AND NOT NO_FLTO_ARCH)
_pybind11_return_if_cxx_and_linker_flags_work(
HAS_FLTO "-flto${cxx_append}" "-flto${linker_append}" PYBIND11_LTO_CXX_FLAGS
PYBIND11_LTO_LINKER_FLAGS)
......
......@@ -13,7 +13,7 @@ This module sets the following variables in your project:
``pybind11_VERSION``
pybind11 version in format Major.Minor.Release
``pybind11_VERSION_TYPE``
pybind11 version type (dev, release)
pybind11 version type (``dev*`` or empty for a release)
``pybind11_INCLUDE_DIRS``
Directories where pybind11 and python headers are located.
``pybind11_INCLUDE_DIR``
......@@ -228,6 +228,6 @@ include("${CMAKE_CURRENT_LIST_DIR}/pybind11Common.cmake")
if(NOT pybind11_FIND_QUIETLY)
message(
STATUS
"Found pybind11: ${pybind11_INCLUDE_DIR} (found version \"${pybind11_VERSION}\" ${pybind11_VERSION_TYPE})"
"Found pybind11: ${pybind11_INCLUDE_DIR} (found version \"${pybind11_VERSION}${pybind11_VERSION_TYPE}\")"
)
endif()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment