Merge branch 'master' into sh_merge_master

This commit is contained in:
Ralf W. Grosse-Kunstleve 2023-02-16 15:02:47 -08:00
commit 550d4b7490
10 changed files with 57 additions and 28 deletions

View File

@ -84,9 +84,6 @@ jobs:
- name: Update CMake
uses: jwlawson/actions-setup-cmake@v1.13
# TEMPORARILY pin version because 3.26.0-rc1 is failing under macOS:
with:
cmake-version: '3.25.2'
- name: Cache wheels
if: runner.os == 'macOS'
@ -1075,9 +1072,6 @@ jobs:
- name: Update CMake
uses: jwlawson/actions-setup-cmake@v1.13
# TEMPORARILY pin version because 3.26.0-rc1 is failing under macOS:
with:
cmake-version: '3.25.2'
- name: Run pip installs
run: |

View File

@ -1,3 +1,4 @@
prune tests
prune ubench
include README_smart_holder.rst
recursive-include pybind11/include/pybind11 *.h

View File

@ -1059,11 +1059,14 @@ make_caster_for_intrinsic<T> &load_type(make_caster_for_intrinsic<T> &conv, cons
"Internal error: type_caster should only be used for C++ types");
if (!conv.load(handle, true)) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
throw cast_error("Unable to cast Python instance to C++ type (#define "
"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
throw cast_error(
"Unable to cast Python instance of type "
+ str(type::handle_of(handle)).cast<std::string>()
+ " to C++ type '?' (#define "
"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
#else
throw cast_error("Unable to cast Python instance of type "
+ (std::string) str(type::handle_of(handle)) + " to C++ type '"
+ str(type::handle_of(handle)).cast<std::string>() + " to C++ type '"
+ type_id<T>() + "'");
#endif
}
@ -1127,12 +1130,13 @@ detail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) {
if (obj.ref_count() > 1) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
throw cast_error(
"Unable to cast Python instance to C++ rvalue: instance has multiple references"
" (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
"Unable to cast Python " + str(type::handle_of(obj)).cast<std::string>()
+ " instance to C++ rvalue: instance has multiple references"
" (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
#else
throw cast_error("Unable to move from Python " + (std::string) str(type::handle_of(obj))
+ " instance to C++ " + type_id<T>()
+ " instance: instance has multiple references");
throw cast_error("Unable to move from Python "
+ str(type::handle_of(obj)).cast<std::string>() + " instance to C++ "
+ type_id<T>() + " instance: instance has multiple references");
#endif
}
@ -1237,9 +1241,10 @@ PYBIND11_NAMESPACE_END(detail)
// The overloads could coexist, i.e. the #if is not strictly speaking needed,
// but it is an easy minor optimization.
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
inline cast_error cast_error_unable_to_convert_call_arg() {
return cast_error("Unable to convert call argument to Python object (#define "
"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
inline cast_error cast_error_unable_to_convert_call_arg(const std::string &name) {
return cast_error("Unable to convert call argument '" + name
+ "' to Python object (#define "
"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
}
#else
inline cast_error cast_error_unable_to_convert_call_arg(const std::string &name,
@ -1262,7 +1267,7 @@ tuple make_tuple(Args &&...args_) {
for (size_t i = 0; i < args.size(); i++) {
if (!args[i]) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
throw cast_error_unable_to_convert_call_arg();
throw cast_error_unable_to_convert_call_arg(std::to_string(i));
#else
std::array<std::string, size> argtypes{{type_id<Args>()...}};
throw cast_error_unable_to_convert_call_arg(std::to_string(i), argtypes[i]);
@ -1552,7 +1557,7 @@ private:
detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));
if (!o) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
throw cast_error_unable_to_convert_call_arg();
throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()));
#else
throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()),
type_id<T>());
@ -1584,7 +1589,7 @@ private:
}
if (!a.value) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
throw cast_error_unable_to_convert_call_arg();
throw cast_error_unable_to_convert_call_arg(a.name);
#else
throw cast_error_unable_to_convert_call_arg(a.name, a.type);
#endif

View File

@ -1249,8 +1249,9 @@ constexpr
#endif
// Pybind offers detailed error messages by default for all builts that are debug (through the
// negation of ndebug). This can also be manually enabled by users, for any builds, through
// defining PYBIND11_DETAILED_ERROR_MESSAGES.
// negation of NDEBUG). This can also be manually enabled by users, for any builds, through
// defining PYBIND11_DETAILED_ERROR_MESSAGES. This information is primarily useful for those
// who are writing (as opposed to merely using) libraries that use pybind11.
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) && !defined(NDEBUG)
# define PYBIND11_DETAILED_ERROR_MESSAGES
#endif

View File

@ -191,7 +191,7 @@ if(PYBIND11_TEST_OVERRIDE)
# This allows the override to be done with extensions, preserving backwards compatibility.
foreach(test_name ${TEST_FILES_NO_EXT})
if(NOT ${test_name} IN_LIST TEST_OVERRIDE_NO_EXT
)# If not in the whitelist, add to be filtered out.
)# If not in the allowlist, add to be filtered out.
list(APPEND PYBIND11_TEST_FILTER ${test_name})
endif()
endforeach()

View File

@ -5,6 +5,7 @@ import pytest
import env # noqa: F401
from pybind11_tests import callbacks as m
from pybind11_tests import detailed_error_messages_enabled
def test_callbacks():
@ -70,11 +71,20 @@ def test_keyword_args_and_generalized_unpacking():
with pytest.raises(RuntimeError) as excinfo:
m.test_arg_conversion_error1(f)
assert "Unable to convert call argument" in str(excinfo.value)
assert str(excinfo.value) == "Unable to convert call argument " + (
"'1' of type 'UnregisteredType' to Python object"
if detailed_error_messages_enabled
else "'1' to Python object (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)"
)
with pytest.raises(RuntimeError) as excinfo:
m.test_arg_conversion_error2(f)
assert "Unable to convert call argument" in str(excinfo.value)
assert str(excinfo.value) == "Unable to convert call argument " + (
"'expected_name' of type 'UnregisteredType' to Python object"
if detailed_error_messages_enabled
else "'expected_name' to Python object "
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)"
)
def test_lambda_closure_cleanup():

View File

@ -339,4 +339,9 @@ TEST_SUBMODULE(exceptions, m) {
}
return py::str("UNEXPECTED");
});
m.def("test_fn_cast_int", [](const py::function &fn) {
// function returns None instead of int, should give a useful error message
fn().cast<int>();
});
}

View File

@ -381,3 +381,12 @@ def test_pypy_oserror_normalization():
# https://github.com/pybind/pybind11/issues/4075
what = m.test_pypy_oserror_normalization()
assert "this_filename_must_not_exist" in what
def test_fn_cast_int_exception():
with pytest.raises(RuntimeError) as excinfo:
m.test_fn_cast_int(lambda: None)
assert str(excinfo.value).startswith(
"Unable to cast Python instance of type <class 'NoneType'> to C++ type"
)

View File

@ -536,7 +536,7 @@ def test_print(capture):
assert str(excinfo.value) == "Unable to convert call argument " + (
"'1' of type 'UnregisteredType' to Python object"
if detailed_error_messages_enabled
else "to Python object (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)"
else "'1' to Python object (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)"
)

View File

@ -36,10 +36,14 @@ endfunction()
function(_download_catch version destination_dir)
message(STATUS "Downloading catch v${version}...")
set(url https://github.com/philsquared/Catch/releases/download/v${version}/catch.hpp)
file(DOWNLOAD ${url} "${destination_dir}/catch.hpp" STATUS status)
file(
DOWNLOAD ${url} "${destination_dir}/catch.hpp"
STATUS status
LOG log)
list(GET status 0 error)
if(error)
message(FATAL_ERROR "Could not download ${url}")
string(REPLACE "\n" "\n " log " ${log}")
message(FATAL_ERROR "Could not download URL:\n" " ${url}\n" "Log:\n" "${log}")
endif()
set(CATCH_INCLUDE_DIR
"${destination_dir}"