diff --git a/patches/pybind11_abseil.patch b/patches/pybind11_abseil.patch index 69f1608f12..cb95e151af 100644 --- a/patches/pybind11_abseil.patch +++ b/patches/pybind11_abseil.patch @@ -5,6 +5,18 @@ index 0000000..378eac2 +++ b/.bazelignore @@ -0,0 +1 @@ +build +diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml +index 12fe458..b30c028 100644 +--- a/.github/workflows/actions.yml ++++ b/.github/workflows/actions.yml +@@ -18,6 +18,7 @@ jobs: + + unix: + strategy: ++ fail-fast: false + matrix: + runs-on: [ubuntu-latest] + build_tool: [bazel, cmake] diff --git a/.gitignore b/.gitignore index 2a7b42e..c2a37f0 100644 --- a/.gitignore @@ -15,11 +27,12 @@ index 2a7b42e..c2a37f0 100644 tmp_build +.*.swp diff --git a/CMakeLists.txt b/CMakeLists.txt -index ceb65a8..e142837 100644 +index ceb65a8..2a78f8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,11 @@ - cmake_minimum_required(VERSION 3.11) +-cmake_minimum_required(VERSION 3.11) ++cmake_minimum_required(VERSION 3.16) project(pybind11_abseil LANGUAGES CXX) -include(FetchContent) @@ -53,30 +66,184 @@ index ceb65a8..e142837 100644 set(TOP_LEVEL_DIR ${CMAKE_CURRENT_LIST_DIR}) include_directories(${TOP_LEVEL_DIR} ${pybind11_INCLUDE_DIRS}) +diff --git a/MODULE.bazel b/MODULE.bazel +index cb75dd1..bd551a2 100644 +--- a/MODULE.bazel ++++ b/MODULE.bazel +@@ -1,38 +1,18 @@ ++PYBIND11_ABSEIL_VERSION = "20240722.0" ++ + module( + name = "pybind11_abseil", +- version = "head", +-) +- +-bazel_dep( +- name = "bazel_skylib", +- version = "1.5.0", +-) +- +-bazel_dep( +- name = "abseil-cpp", +- version = "20240116.0", +- repo_name = "com_google_absl", +-) +- +-bazel_dep( +- name = "rules_cc", +- version = "0.0.9", +-) +- +-bazel_dep( +- name = "rules_python", +- version = "0.31.0", ++ version = PYBIND11_ABSEIL_VERSION, ++ repo_name = "org_pybind11_abseil", + ) + +-bazel_dep( +- name = "platforms", +- version = "0.0.8" +-) +- +-bazel_dep( +- name = "pybind11_bazel", +- version = "2.11.1.bzl.2" +-) ++# see https://registry.bazel.build/ ++bazel_dep(name = "abseil-cpp", version = "20240722.0", repo_name = "com_google_absl") ++bazel_dep(name = "bazel_skylib", version = "1.7.1") ++bazel_dep(name = "platforms", version = "0.0.10") ++bazel_dep(name = "rules_cc", version = "0.0.16") ++bazel_dep(name = "rules_python", version = "0.40.0") ++bazel_dep(name = "pybind11_bazel", version = "2.13.6") + + #### DEV ONLY DEPENDENCIES BELOW HERE #### + +@@ -49,6 +29,7 @@ DEFAULT_PYTHON = "3.11" + python = use_extension("@rules_python//python/extensions:python.bzl", "python", dev_dependency=True) + [ + python.toolchain( ++ ignore_root_user_error = True, # needed for CI + python_version = version, + is_default = version == DEFAULT_PYTHON, + ) +diff --git a/README.md b/README.md +index 58bbc94..84d5345 100644 +--- a/README.md ++++ b/README.md +@@ -53,15 +53,15 @@ http_archive( + + http_archive( + name = "pybind11", +- build_file = "@pybind11_bazel//:pybind11.BUILD", ++ build_file = "@pybind11_bazel//:pybind11-BUILD.bazel", + strip_prefix = "pybind11-master", + urls = ["https://github.com/pybind/pybind11/archive/refs/heads/master.tar.gz"], + ) + + http_archive( + name = "pybind11_abseil", +- strip_prefix = "pybind11_abseil_master" +- urls = ["https://github.com/pybind/pybind11_abseil/refs/heads/master.tar.gz"], ++ strip_prefix = "pybind11_abseil-master", ++ urls = ["https://github.com/pybind/pybind11_abseil/archive/refs/heads/master.tar.gz"], + ) + + ``` +@@ -83,14 +83,15 @@ http_archive( + + http_archive( + name = "pybind11", +- build_file = "@pybind11_bazel//:pybind11.BUILD", ++ build_file = "@pybind11_bazel//:pybind11-BUILD.bazel", + strip_prefix = "pybind11-master", ++ urls = ["https://github.com/pybind/pybind11/archive/refs/heads/master.tar.gz"], + ) + + http_archive( + name = "pybind11_abseil", +- strip_prefix = "pybind11_abseil_master", +- urls = ["https://github.com/pybind/pybind11_abseil/refs/heads/master.tar.gz"], ++ strip_prefix = "pybind11_abseil-master", ++ urls = ["https://github.com/pybind/pybind11_abseil/archive/refs/heads/master.tar.gz"], + ) + ``` + +diff --git a/WORKSPACE b/WORKSPACE +index 073250c..2d8e524 100644 +--- a/WORKSPACE ++++ b/WORKSPACE +@@ -10,12 +10,13 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + + ################################################################################ + # +-# WORKSPACE is being deprecated in favor of the new Bazelmod dependency system ++# WORKSPACE is being deprecated in favor of the new Bzlmod dependency system. + # It will be removed at some point in the future. + # + ################################################################################ + + ## `bazel_skylib` (PINNED) ++# Needed for Abseil. + http_archive( + name = "bazel_skylib", # 2023-05-31T19:24:07Z + sha256 = "08c0386f45821ce246bbbf77503c973246ed6ee5c3463e41efc197fa9bc3a7f4", +@@ -89,12 +90,13 @@ load("@pypi//:requirements.bzl", "install_deps") + install_deps() + + +-## `pybind11_bazel` (FLOATING) ++## `pybind11_bazel` (PINNED) + # https://github.com/pybind/pybind11_bazel + http_archive( + name = "pybind11_bazel", +- strip_prefix = "pybind11_bazel-master", +- urls = ["https://github.com/pybind/pybind11_bazel/archive/refs/heads/master.tar.gz"], ++ strip_prefix = "pybind11_bazel-2.11.1.bzl.2", ++ sha256 = "e2ba5f81f3bf6a3fc0417448d49389cc7950bebe48c42c33dfeb4dd59859b9a4", ++ urls = ["https://github.com/pybind/pybind11_bazel/releases/download/v2.11.1.bzl.2/pybind11_bazel-2.11.1.bzl.2.tar.gz"], + ) + + ## `pybind11` (FLOATING) diff --git a/cmake/dependencies/CMakeLists.txt b/cmake/dependencies/CMakeLists.txt new file mode 100644 -index 0000000..cb13e7e +index 0000000..b59e6d8 --- /dev/null +++ b/cmake/dependencies/CMakeLists.txt -@@ -0,0 +1,19 @@ +@@ -0,0 +1,33 @@ +include(FetchContent) +set(BUILD_TESTING OFF) + +if(NOT TARGET absl::base) ++ message(CHECK_START "Fetching Abseil-cpp") ++ list(APPEND CMAKE_MESSAGE_INDENT " ") ++ # ensure that abseil also installs itself, since we are using it in our public API ++ set(ABSL_ENABLE_INSTALL ON) ++ set(ABSL_USE_SYSTEM_INCLUDES ON) + set(ABSL_PROPAGATE_CXX_STD ON) ++ set(ABSL_BUILD_TESTING OFF) + FetchContent_Declare( + absl -+ URL https://github.com/abseil/abseil-cpp/archive/refs/tags/20230802.0.tar.gz -+ URL_HASH -+ SHA256=59d2976af9d6ecf001a81a35749a6e551a335b949d34918cfade07737b9d93c5) ++ GIT_REPOSITORY "https://github.com/abseil/abseil-cpp.git" ++ GIT_TAG "20240722.0" ++ GIT_SHALLOW TRUE) + FetchContent_MakeAvailable(absl) ++ list(POP_BACK CMAKE_MESSAGE_INDENT) ++ message(CHECK_PASS "fetched") +endif() + +if(NOT TARGET pybind11::pybind11_headers) ++ message(CHECK_START "Fetching Pybind11") ++ list(APPEND CMAKE_MESSAGE_INDENT " ") + FetchContent_Declare( + pybind11 -+ URL https://github.com/pybind/pybind11/archive/refs/heads/master.tar.gz) ++ GIT_REPOSITORY "https://github.com/pybind/pybind11.git" ++ GIT_TAG "v2.13.6" ++ GIT_SHALLOW TRUE) + FetchContent_MakeAvailable(pybind11) ++ list(POP_BACK CMAKE_MESSAGE_INDENT) ++ message(CHECK_PASS "fetched") +endif() diff --git a/pybind11_abseil/BUILD b/pybind11_abseil/BUILD index 791c245..33e614a 100644 @@ -158,10 +325,10 @@ index 791c245..33e614a 100644 ) diff --git a/pybind11_abseil/CMakeLists.txt b/pybind11_abseil/CMakeLists.txt -index d1b7483..74e3443 100644 +index d1b7483..826fe3a 100644 --- a/pybind11_abseil/CMakeLists.txt +++ b/pybind11_abseil/CMakeLists.txt -@@ -42,14 +42,19 @@ target_link_libraries(ok_status_singleton_pyinit_google3 +@@ -42,14 +42,17 @@ target_link_libraries(ok_status_singleton_pyinit_google3 # ok_status_singleton ======================================================= @@ -172,8 +339,6 @@ index d1b7483..74e3443 100644 +# note: macOS is APPLE and also UNIX ! +if(APPLE) + set_target_properties(ok_status_singleton PROPERTIES SUFFIX ".so") -+ set_property(TARGET ok_status_singleton APPEND PROPERTY -+ LINK_FLAGS "-flat_namespace -undefined suppress") +endif() + target_include_directories(ok_status_singleton @@ -184,43 +349,40 @@ index d1b7483..74e3443 100644 target_link_libraries(ok_status_singleton PUBLIC ok_status_singleton_pyinit_google3) -@@ -150,14 +155,30 @@ target_link_libraries(status_pyinit_google3 PUBLIC register_status_bindings) +@@ -150,14 +153,27 @@ target_link_libraries(status_pyinit_google3 PUBLIC register_status_bindings) # status ==================================================================== -add_library(status SHARED status_py_extension_stub.cc) -add_library(pybind11_abseil::status ALIAS status) +pybind11_add_module(status_py_extension_stub MODULE status_py_extension_stub.cc) ++set_target_properties(status_py_extension_stub PROPERTIES ++ LIBRARY_OUTPUT_NAME "status") + -+set_target_properties(status_py_extension_stub PROPERTIES LIBRARY_OUTPUT_NAME "status") +# note: macOS is APPLE and also UNIX ! +if(APPLE) + set_target_properties(status_py_extension_stub PROPERTIES + SUFFIX ".so" -+ INSTALL_RPATH "@loader_path;@loader_path/../ortools/.libs" -+ ) -+ set_property(TARGET status_py_extension_stub APPEND PROPERTY -+ LINK_FLAGS "-flat_namespace -undefined suppress") ++ INSTALL_RPATH "@loader_path;@loader_path/../ortools/.libs") +elseif(UNIX) + set_target_properties(status_py_extension_stub PROPERTIES -+ INSTALL_RPATH "$ORIGIN:$ORIGIN/../ortools/.libs" -+ ) ++ INSTALL_RPATH "$ORIGIN:$ORIGIN/../ortools/.libs") +endif() ++ ++add_library(pybind11_abseil::status ALIAS status_py_extension_stub) -target_include_directories(status INTERFACE $) -+add_library(pybind11_abseil::status ALIAS status_py_extension_stub) ++target_include_directories(status_py_extension_stub INTERFACE $) -set_target_properties(status PROPERTIES PREFIX "") -+target_include_directories(status_py_extension_stub INTERFACE $) ++set_target_properties(status_py_extension_stub PROPERTIES PREFIX "") -target_link_libraries(status PUBLIC status_pyinit_google3 absl::status) -+set_target_properties(status_py_extension_stub PROPERTIES PREFIX "") -+ +target_link_libraries(status_py_extension_stub PUBLIC status_pyinit_google3 absl::status) # import_status_module ========================================================= -@@ -167,7 +188,7 @@ add_library(pybind11_abseil::import_status_module ALIAS import_status_module) +@@ -167,7 +183,7 @@ add_library(pybind11_abseil::import_status_module ALIAS import_status_module) target_include_directories(import_status_module INTERFACE $) @@ -229,7 +391,7 @@ index d1b7483..74e3443 100644 # status_casters =============================================================== -@@ -175,25 +196,27 @@ add_library(status_casters INTERFACE) +@@ -175,28 +191,29 @@ add_library(status_casters INTERFACE) add_library(pybind11_abseil::status_casters ALIAS status_casters) target_include_directories(status_casters @@ -262,8 +424,124 @@ index d1b7483..74e3443 100644 EXPORT pybind11_abseil_cppTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}) +- + endif() +diff --git a/pybind11_abseil/absl_casters.h b/pybind11_abseil/absl_casters.h +index 7bda30f..a465f4a 100644 +--- a/pybind11_abseil/absl_casters.h ++++ b/pybind11_abseil/absl_casters.h +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -494,7 +495,7 @@ struct type_caster> { + } + + static constexpr auto name = +- const_name("Span[") + make_caster::name + const_name("]"); ++ const_name("Sequence[") + make_caster::name + const_name("]"); + + // We do not allow moving because 1) spans are super lightweight, so there's + // no advantage to moving and 2) the span cannot exist without the caster, +@@ -627,9 +628,22 @@ struct type_caster { + } + + // Conversion part 2 (C++ -> Python) +- static handle cast(const absl::Cord& src, return_value_policy /*policy*/, ++ static handle cast(const absl::Cord& src, return_value_policy policy, + handle /*parent*/) { +- return bytes(std::string(src)).release(); ++#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_CLIF_AUTOMATIC) ++ if (policy == return_value_policy::_clif_automatic) { ++ return str(std::string(src)).release(); ++ } ++#endif ++ bytes data(nullptr, src.size()); ++ // Cord::CopyToArray is not always available so we need to copy ++ // the cord manually. ++ char* ptr = PyBytes_AS_STRING(data.ptr()); ++ for (absl::string_view chunk : src.Chunks()) { ++ std::memcpy(ptr, chunk.data(), chunk.size()); ++ ptr += chunk.size(); ++ } ++ return data.release(); + } + }; + +diff --git a/pybind11_abseil/compat/status_from_py_exc.cc b/pybind11_abseil/compat/status_from_py_exc.cc +index dc38ef1..2bc6bf9 100644 +--- a/pybind11_abseil/compat/status_from_py_exc.cc ++++ b/pybind11_abseil/compat/status_from_py_exc.cc +@@ -56,7 +56,7 @@ PyObject* PyStatusNotOkOrNone() { + static PyObject* kImportedObj = nullptr; + if (kImportedObj == nullptr) { + kImportedObj = py_base_utilities::ImportObjectOrReturnNone( +- "google3.third_party.pybind11_abseil.status", "StatusNotOk"); ++ "pybind11_abseil.status", "StatusNotOk"); + } + return kImportedObj; + } +diff --git a/pybind11_abseil/status_caster.h b/pybind11_abseil/status_caster.h +index eef6aba..00655b1 100644 +--- a/pybind11_abseil/status_caster.h ++++ b/pybind11_abseil/status_caster.h +@@ -120,9 +120,8 @@ struct type_caster : public type_caster_base { + } + }; + +-#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_PACK) ++#if defined(PYBIND11_HAS_TYPE_CASTER_STD_FUNCTION_SPECIALIZATIONS) + +-// This code requires https://github.com/google/pywrapcc + // IMPORTANT: + // KEEP + // type_caster +@@ -140,7 +139,11 @@ struct func_wrapper : func_wrapper_base { + gil_scoped_acquire acq; + try { + object py_result = ++#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_PACK) + hfunc.f.call_with_policies(rvpp, std::forward(args)...); ++#else ++ hfunc.f(std::forward(args)...); ++#endif + try { + return py_result.template cast(); + } catch (cast_error& e) { +diff --git a/pybind11_abseil/statusor_caster.h b/pybind11_abseil/statusor_caster.h +index 80a1507..2dc97ba 100644 +--- a/pybind11_abseil/statusor_caster.h ++++ b/pybind11_abseil/statusor_caster.h +@@ -124,9 +124,8 @@ struct type_caster> { + } + }; + +-#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_PACK) ++#if defined(PYBIND11_HAS_TYPE_CASTER_STD_FUNCTION_SPECIALIZATIONS) + +-// This code requires https://github.com/google/pywrapcc + // IMPORTANT: + // KEEP + // type_caster> +@@ -144,7 +143,11 @@ struct func_wrapper, Args...> : func_wrapper_base { + gil_scoped_acquire acq; + try { + object py_result = ++#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_PACK) + hfunc.f.call_with_policies(rvpp, std::forward(args)...); ++#else ++ hfunc.f(std::forward(args)...); ++#endif + try { + auto cpp_result = + py_result.template cast>(); diff --git a/pybind11_abseil/tests/CMakeLists.txt b/pybind11_abseil/tests/CMakeLists.txt -index a423c30..ae22a48 100644 +index a423c30..f7f390e 100644 --- a/pybind11_abseil/tests/CMakeLists.txt +++ b/pybind11_abseil/tests/CMakeLists.txt @@ -1,6 +1,6 @@ @@ -301,3 +579,170 @@ index a423c30..ae22a48 100644 target_link_libraries(status_example PRIVATE status_casters absl::status absl::statusor) +@@ -95,3 +95,5 @@ add_test( + ${CMAKE_COMMAND} -E env PYTHONPATH=$PYTHONPATH:${CMAKE_BINARY_DIR} + ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/status_example_test.py + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) ++ ++# OMITTED (help appreciated): status_testing_no_cpp_eh_test +diff --git a/pybind11_abseil/tests/absl_example.cc b/pybind11_abseil/tests/absl_example.cc +index 91fdec4..576e5ca 100644 +--- a/pybind11_abseil/tests/absl_example.cc ++++ b/pybind11_abseil/tests/absl_example.cc +@@ -363,6 +363,13 @@ static_assert( + !std::is_const::value); // int is const, pointer is not. + + PYBIND11_MODULE(absl_example, m) { ++ m.attr("PYBIND11_HAS_RETURN_VALUE_POLICY_CLIF_AUTOMATIC") = ++#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_CLIF_AUTOMATIC) ++ true; ++#else ++ false; ++#endif ++ + // absl::Time/Duration bindings. + m.def("make_duration", &MakeDuration, arg("secs")); + m.def("make_infinite_duration", &MakeInfiniteDuration); +@@ -440,6 +447,11 @@ PYBIND11_MODULE(absl_example, m) { + // absl::Cord bindings. + m.def("check_absl_cord", &CheckAbslCord, arg("view"), arg("values")); + m.def("return_absl_cord", &ReturnAbslCord, arg("values")); ++#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_CLIF_AUTOMATIC) ++ m.def("return_absl_cord_clif_automatic", [](const std::string& values) { ++ return cast(ReturnAbslCord(values), return_value_policy::_clif_automatic); ++ }); ++#endif + + // absl::optional bindings. + m.def("check_optional", &CheckOptional, arg("optional") = absl::nullopt, +diff --git a/pybind11_abseil/tests/absl_test.py b/pybind11_abseil/tests/absl_test.py +index 555ad87..49a9ffd 100644 +--- a/pybind11_abseil/tests/absl_test.py ++++ b/pybind11_abseil/tests/absl_test.py +@@ -377,7 +377,7 @@ class AbslNumericSpanTest(parameterized.TestCase): + ('read_only', make_read_only_numpy_array()), + ('strided_skip', make_strided_numpy_array(2)), + ('strided_reverse', make_strided_numpy_array(-1)), +- ('non_supported_type', np.zeros(5, dtype=np.unicode_)), ++ ('non_supported_type', np.zeros(5, dtype=np.str_)), + ('native_list', [0] * 5)) + def test_fill_span_fails_from(self, values): + with self.assertRaises(TypeError): +@@ -487,12 +487,24 @@ class AbslCordTest(absltest.TestCase): + TEST_STRING = 'absl_Cord' + TEST_BYTES = b'absl_Cord' + +- def test_return_absl_cord(self): ++ def test_return_absl_cord_rvp_not_specified(self): + self.assertSequenceEqual( + absl_example.return_absl_cord(self.TEST_STRING), self.TEST_BYTES) + self.assertSequenceEqual( + absl_example.return_absl_cord(self.TEST_BYTES), self.TEST_BYTES) + ++ def test_return_absl_cord_rvp_clif_automatic(self): ++ if not absl_example.PYBIND11_HAS_RETURN_VALUE_POLICY_CLIF_AUTOMATIC: ++ self.skipTest('return_value_policy::_clif_automatic not available') ++ self.assertSequenceEqual( ++ absl_example.return_absl_cord_clif_automatic(self.TEST_STRING), ++ self.TEST_STRING, ++ ) ++ self.assertSequenceEqual( ++ absl_example.return_absl_cord_clif_automatic(self.TEST_BYTES), ++ self.TEST_STRING, ++ ) ++ + def test_pass_absl_cord(self): + self.assertTrue( + absl_example.check_absl_cord(self.TEST_STRING, self.TEST_STRING)) +diff --git a/pybind11_abseil/tests/status_testing_no_cpp_eh_pybind.cc b/pybind11_abseil/tests/status_testing_no_cpp_eh_pybind.cc +index 27be2cf..b441962 100644 +--- a/pybind11_abseil/tests/status_testing_no_cpp_eh_pybind.cc ++++ b/pybind11_abseil/tests/status_testing_no_cpp_eh_pybind.cc +@@ -24,8 +24,8 @@ PYBIND11_MODULE(status_testing_no_cpp_eh_pybind, m) { + pybind11::return_value_policy::take_ownership); + m.def("GenerateErrorStatusNotOk", &GenerateErrorStatusNotOk); + +- m.attr("PYBIND11_HAS_RETURN_VALUE_POLICY_PACK") = +-#if defined(PYBIND11_HAS_RETURN_VALUE_POLICY_PACK) ++ m.attr("defined_PYBIND11_HAS_TYPE_CASTER_STD_FUNCTION_SPECIALIZATIONS") = ++#if defined(PYBIND11_HAS_TYPE_CASTER_STD_FUNCTION_SPECIALIZATIONS) + true; + #else + false; +diff --git a/pybind11_abseil/tests/status_testing_no_cpp_eh_test.py b/pybind11_abseil/tests/status_testing_no_cpp_eh_test.py +index fd78a5c..ed875bf 100644 +--- a/pybind11_abseil/tests/status_testing_no_cpp_eh_test.py ++++ b/pybind11_abseil/tests/status_testing_no_cpp_eh_test.py +@@ -3,6 +3,13 @@ from absl.testing import absltest + from pybind11_abseil.tests import status_testing_no_cpp_eh_pybind + from pybind11_abseil.tests import status_testing_no_cpp_eh_test_lib as test_lib + ++_HAS_FUN_SPEC = ( ++ status_testing_no_cpp_eh_pybind.defined_PYBIND11_HAS_TYPE_CASTER_STD_FUNCTION_SPECIALIZATIONS ++) ++_FUN_SPEC_NDEF = ( ++ 'PYBIND11_HAS_TYPE_CASTER_STD_FUNCTION_SPECIALIZATIONS is not defined.' ++) ++ + + class _TestModuleMixin: + +@@ -10,14 +17,17 @@ class _TestModuleMixin: + return status_testing_no_cpp_eh_pybind + + ++@absltest.skipIf(not _HAS_FUN_SPEC, _FUN_SPEC_NDEF) + class StatusReturnTest(test_lib.StatusReturnTest, _TestModuleMixin): + pass + + ++@absltest.skipIf(not _HAS_FUN_SPEC, _FUN_SPEC_NDEF) + class StatusOrReturnTest(test_lib.StatusOrReturnTest, _TestModuleMixin): + pass + + ++@absltest.skipIf(not _HAS_FUN_SPEC, _FUN_SPEC_NDEF) + class StatusOrPyObjectPtrTest( + test_lib.StatusOrPyObjectPtrTest, _TestModuleMixin + ): +diff --git a/pybind11_abseil/tests/status_testing_no_cpp_eh_test_lib.py b/pybind11_abseil/tests/status_testing_no_cpp_eh_test_lib.py +index 5f9e7cd..5068716 100644 +--- a/pybind11_abseil/tests/status_testing_no_cpp_eh_test_lib.py ++++ b/pybind11_abseil/tests/status_testing_no_cpp_eh_test_lib.py +@@ -53,10 +53,10 @@ class StatusReturnTest(parameterized.TestCase): + expected = 'OK' + else: + expected = ( +- 'INVALID_ARGUMENT: Unable to cast Python instance of type to C++ type 'absl::Status'" ++ r"INVALID_ARGUMENT: Unable to cast Python instance of type to C\+\+ type ('absl::(\w*::)?Status'|'\?')" + ) +- self.assertEqual(self.tm.CallCallbackWithStatusReturn(cb), expected) ++ self.assertRegex(self.tm.CallCallbackWithStatusReturn(cb), expected) + + def testAssertionErrorBare(self): # pylint: disable=invalid-name + +@@ -117,10 +117,10 @@ class StatusOrReturnTest(parameterized.TestCase): + expected = 'INVALID_ARGUMENT: TypeError: expecting int' + else: + expected = ( +- 'INVALID_ARGUMENT: Unable to cast Python instance of type to C++ type 'absl::StatusOr'" ++ r"INVALID_ARGUMENT: Unable to cast Python instance of type to C\+\+ type ('absl::(\w*::)?StatusOr'|'\?')" + ) +- self.assertEqual(self.tm.CallCallbackWithStatusOrIntReturn(cb), expected) ++ self.assertRegex(self.tm.CallCallbackWithStatusOrIntReturn(cb), expected) + + + class StatusOrPyObjectPtrTest(absltest.TestCase): +@@ -185,7 +185,7 @@ class StatusOrPyObjectPtrTest(absltest.TestCase): + + if ( + hasattr(self.tm, '__pyclif_codegen_mode__') +- or self.tm.PYBIND11_HAS_RETURN_VALUE_POLICY_PACK ++ or self.tm.defined_PYBIND11_HAS_TYPE_CASTER_STD_FUNCTION_SPECIALIZATIONS + ): + res = cc_fn(cb, 'exc') + self.assertEqual(res, "!obj.ok()@ValueError: Unknown arg: 'exc'")