diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index eb02946a86..30eae090f5 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -1690,7 +1690,13 @@ class str : public object { Return a string representation of the object. This is analogous to the ``str()`` function in Python. \endrst */ - explicit str(handle h) : object(raw_str(h.ptr()), stolen_t{}) { + // Templatized to avoid ambiguity with str(const object&) for object-derived types. + template >::value + && std::is_constructible::value, + int> + = 0> + explicit str(T &&h) : object(raw_str(handle(std::forward(h)).ptr()), stolen_t{}) { if (!m_ptr) { throw error_already_set(); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 15e18705be..fdf33628aa 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -602,6 +602,12 @@ if(NOT PYBIND11_CUDA_TESTS) endif() endforeach() + if(SKBUILD) + foreach(mod IN LISTS PYBIND11_MULTIPLE_INTERPRETERS_TEST_MODULES) + install(TARGETS "${mod}" LIBRARY DESTINATION .) + endforeach() + endif() + if(PYBIND11_TEST_SMART_HOLDER) foreach(mod IN LISTS PYBIND11_MULTIPLE_INTERPRETERS_TEST_MODULES) target_compile_definitions( diff --git a/tests/env.py b/tests/env.py index 4b48e91930..ee932ad77a 100644 --- a/tests/env.py +++ b/tests/env.py @@ -5,6 +5,7 @@ import sysconfig ANDROID = sys.platform.startswith("android") +IOS = sys.platform.startswith("ios") LINUX = sys.platform.startswith("linux") MACOS = sys.platform.startswith("darwin") WIN = sys.platform.startswith("win32") or sys.platform.startswith("cygwin") diff --git a/tests/pyproject.toml b/tests/pyproject.toml index fa478122d3..8821ea3f34 100644 --- a/tests/pyproject.toml +++ b/tests/pyproject.toml @@ -27,7 +27,9 @@ PYBIND11_FINDPYTHON = true [tool.cibuildwheel] test-sources = ["tests", "pyproject.toml"] -test-command = "python -m pytest -o timeout=0 -p no:cacheprovider tests" +test-command = "python -m pytest -v -o timeout=120 -p no:cacheprovider tests" +# Pyodide doesn't have signal.setitimer, so pytest-timeout can't work with timeout > 0 +pyodide.test-command = "python -m pytest -v -o timeout=0 -p no:cacheprovider tests" environment.PIP_ONLY_BINARY = "numpy" environment.PIP_PREFER_BINARY = "1" diff --git a/tests/requirements.txt b/tests/requirements.txt index 41fc9f1439..3d61669234 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -10,6 +10,7 @@ numpy~=1.22.2; platform_python_implementation=="CPython" and python_version=="3. numpy~=1.26.0; platform_python_implementation=="CPython" and python_version>="3.11" and python_version<"3.13" and platform_machine!="ARM64" numpy~=2.3.0; platform_python_implementation=="CPython" and python_version>="3.11" and platform_machine=="ARM64" numpy~=2.2.0; platform_python_implementation=="CPython" and python_version=="3.13" and platform_machine!="ARM64" +numpy==2.4.0; platform_python_implementation=="CPython" and python_version>="3.14" pytest>=6 pytest-timeout scipy~=1.5.4; platform_python_implementation=="CPython" and python_version<"3.10" diff --git a/tests/test_multiple_interpreters.py b/tests/test_multiple_interpreters.py index aadf3d96bb..44877e772a 100644 --- a/tests/test_multiple_interpreters.py +++ b/tests/test_multiple_interpreters.py @@ -9,8 +9,12 @@ import pytest +import env import pybind11_tests +if env.IOS: + pytest.skip("Subinterpreters not supported on iOS", allow_module_level=True) + # 3.14.0b3+, though sys.implementation.supports_isolated_interpreters is being added in b4 # Can be simplified when we drop support for the first three betas CONCURRENT_INTERPRETERS_SUPPORT = ( diff --git a/tests/test_pytypes.cpp b/tests/test_pytypes.cpp index 7d5423e549..e214350015 100644 --- a/tests/test_pytypes.cpp +++ b/tests/test_pytypes.cpp @@ -1211,4 +1211,6 @@ TEST_SUBMODULE(pytypes, m) { m.def("check_type_is", [](const py::object &x) -> py::typing::TypeIs { return py::isinstance(x); }); + + m.def("const_kwargs_ref_to_str", [](const py::kwargs &kwargs) { return py::str(kwargs); }); } diff --git a/tests/test_pytypes.py b/tests/test_pytypes.py index 09fc5f37ee..580371f02d 100644 --- a/tests/test_pytypes.py +++ b/tests/test_pytypes.py @@ -1367,3 +1367,8 @@ def test_arg_return_type_hints(doc, backport_typehints): backport_typehints(doc(m.check_type_guard)) == "check_type_guard(arg0: list[object]) -> typing.TypeGuard[list[float]]" ) + + +def test_const_kwargs_ref_to_str(): + assert m.const_kwargs_ref_to_str() == "{}" + assert m.const_kwargs_ref_to_str(a=1) == "{'a': 1}"