Merge branch 'pybind:master' into master

This commit is contained in:
Steve R. Sun 2023-02-13 08:38:07 +08:00 committed by GitHub
commit c1cfc6a5f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 59 additions and 23 deletions

View File

@ -83,6 +83,9 @@ jobs:
- name: Update CMake - name: Update CMake
uses: jwlawson/actions-setup-cmake@v1.13 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 - name: Cache wheels
if: runner.os == 'macOS' if: runner.os == 'macOS'
@ -766,7 +769,7 @@ jobs:
uses: jwlawson/actions-setup-cmake@v1.13 uses: jwlawson/actions-setup-cmake@v1.13
- name: Prepare MSVC - name: Prepare MSVC
uses: ilammy/msvc-dev-cmd@v1.12.0 uses: ilammy/msvc-dev-cmd@v1.12.1
with: with:
arch: x86 arch: x86
@ -819,7 +822,7 @@ jobs:
uses: jwlawson/actions-setup-cmake@v1.13 uses: jwlawson/actions-setup-cmake@v1.13
- name: Prepare MSVC - name: Prepare MSVC
uses: ilammy/msvc-dev-cmd@v1.12.0 uses: ilammy/msvc-dev-cmd@v1.12.1
with: with:
arch: x86 arch: x86
@ -1071,6 +1074,9 @@ jobs:
- name: Update CMake - name: Update CMake
uses: jwlawson/actions-setup-cmake@v1.13 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 - name: Run pip installs
run: | run: |

View File

@ -116,7 +116,7 @@ repos:
# PyLint has native support - not always usable, but works for us # PyLint has native support - not always usable, but works for us
- repo: https://github.com/PyCQA/pylint - repo: https://github.com/PyCQA/pylint
rev: "v2.16.0" rev: "v2.16.1"
hooks: hooks:
- id: pylint - id: pylint
files: ^pybind11 files: ^pybind11

View File

@ -1017,11 +1017,14 @@ type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &ha
"Internal error: type_caster should only be used for C++ types"); "Internal error: type_caster should only be used for C++ types");
if (!conv.load(handle, true)) { if (!conv.load(handle, true)) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) #if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
throw cast_error("Unable to cast Python instance to C++ type (#define " 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)"); "PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
#else #else
throw cast_error("Unable to cast Python instance of type " 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>() + "'"); + type_id<T>() + "'");
#endif #endif
} }
@ -1085,12 +1088,13 @@ detail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) {
if (obj.ref_count() > 1) { if (obj.ref_count() > 1) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) #if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
throw cast_error( throw cast_error(
"Unable to cast Python instance to C++ rvalue: instance has multiple references" "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)"); " (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
#else #else
throw cast_error("Unable to move from Python " + (std::string) str(type::handle_of(obj)) throw cast_error("Unable to move from Python "
+ " instance to C++ " + type_id<T>() + str(type::handle_of(obj)).cast<std::string>() + " instance to C++ "
+ " instance: instance has multiple references"); + type_id<T>() + " instance: instance has multiple references");
#endif #endif
} }
@ -1195,8 +1199,9 @@ PYBIND11_NAMESPACE_END(detail)
// The overloads could coexist, i.e. the #if is not strictly speaking needed, // The overloads could coexist, i.e. the #if is not strictly speaking needed,
// but it is an easy minor optimization. // but it is an easy minor optimization.
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) #if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
inline cast_error cast_error_unable_to_convert_call_arg() { inline cast_error cast_error_unable_to_convert_call_arg(const std::string &name) {
return cast_error("Unable to convert call argument to Python object (#define " return cast_error("Unable to convert call argument '" + name
+ "' to Python object (#define "
"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)"); "PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
} }
#else #else
@ -1220,7 +1225,7 @@ tuple make_tuple(Args &&...args_) {
for (size_t i = 0; i < args.size(); i++) { for (size_t i = 0; i < args.size(); i++) {
if (!args[i]) { if (!args[i]) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) #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 #else
std::array<std::string, size> argtypes{{type_id<Args>()...}}; std::array<std::string, size> argtypes{{type_id<Args>()...}};
throw cast_error_unable_to_convert_call_arg(std::to_string(i), argtypes[i]); throw cast_error_unable_to_convert_call_arg(std::to_string(i), argtypes[i]);
@ -1510,7 +1515,7 @@ private:
detail::make_caster<T>::cast(std::forward<T>(x), policy, {})); detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));
if (!o) { if (!o) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) #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 #else
throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()), throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()),
type_id<T>()); type_id<T>());
@ -1542,7 +1547,7 @@ private:
} }
if (!a.value) { if (!a.value) {
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) #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 #else
throw cast_error_unable_to_convert_call_arg(a.name, a.type); throw cast_error_unable_to_convert_call_arg(a.name, a.type);
#endif #endif

View File

@ -1225,8 +1225,9 @@ constexpr
#endif #endif
// Pybind offers detailed error messages by default for all builts that are debug (through the // 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 // negation of NDEBUG). This can also be manually enabled by users, for any builds, through
// defining PYBIND11_DETAILED_ERROR_MESSAGES. // 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) #if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) && !defined(NDEBUG)
# define PYBIND11_DETAILED_ERROR_MESSAGES # define PYBIND11_DETAILED_ERROR_MESSAGES
#endif #endif

View File

@ -170,7 +170,7 @@ if(PYBIND11_TEST_OVERRIDE)
# This allows the override to be done with extensions, preserving backwards compatibility. # This allows the override to be done with extensions, preserving backwards compatibility.
foreach(test_name ${TEST_FILES_NO_EXT}) foreach(test_name ${TEST_FILES_NO_EXT})
if(NOT ${test_name} IN_LIST TEST_OVERRIDE_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}) list(APPEND PYBIND11_TEST_FILTER ${test_name})
endif() endif()
endforeach() endforeach()

View File

@ -5,6 +5,7 @@ import pytest
import env # noqa: F401 import env # noqa: F401
from pybind11_tests import callbacks as m from pybind11_tests import callbacks as m
from pybind11_tests import detailed_error_messages_enabled
def test_callbacks(): def test_callbacks():
@ -70,11 +71,20 @@ def test_keyword_args_and_generalized_unpacking():
with pytest.raises(RuntimeError) as excinfo: with pytest.raises(RuntimeError) as excinfo:
m.test_arg_conversion_error1(f) 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: with pytest.raises(RuntimeError) as excinfo:
m.test_arg_conversion_error2(f) 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(): def test_lambda_closure_cleanup():

View File

@ -339,4 +339,9 @@ TEST_SUBMODULE(exceptions, m) {
} }
return py::str("UNEXPECTED"); 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 # https://github.com/pybind/pybind11/issues/4075
what = m.test_pypy_oserror_normalization() what = m.test_pypy_oserror_normalization()
assert "this_filename_must_not_exist" in what 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 " + ( assert str(excinfo.value) == "Unable to convert call argument " + (
"'1' of type 'UnregisteredType' to Python object" "'1' of type 'UnregisteredType' to Python object"
if detailed_error_messages_enabled 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)"
) )