mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Fix ambiguous str(handle) constructor for object-derived types (#5949)
* Fix ambiguous `str(handle)` constructor for object-derived types Templatize `str(handle h)` with SFINAE to exclude types derived from `object`, resolving ambiguity with `str(const object&)` when calling `py::str()` on types like `kwargs`, `dict`, etc. The template now only accepts `handle` or `PyObject*`, while all `object`-derived types use the `str(const object&)` overload. * fix(tests): CIBW test fixes from b-pass→vectorcall branch - Install multiple-interpreter test modules into wheel (CMakeLists.txt) The mod_per_interpreter_gil, mod_shared_interpreter_gil, and mod_per_interpreter_gil_with_singleton modules were being built but not installed into the wheel when using scikit-build-core. - Pin numpy 2.4.0 for Python 3.14 CI tests (requirements.txt) NumPy 2.4.0 is the first version with official Python 3.14 wheels. - Add IOS platform constant to tests/env.py - Skip subinterpreter tests on iOS (test_multiple_interpreters.py) Subinterpreters are not supported in the iOS simulator environment. - Enable pytest timeout of 120s for CIBW tests (pyproject.toml) Provides a safety net to catch hanging tests before CI job timeout. - Disable pytest-timeout for Pyodide (no signal.setitimer) Pyodide runs in WebAssembly without POSIX signals. - Add -v flag for verbose pytest output in CIBW tests
This commit is contained in:
committed by
GitHub
parent
fee2527dfa
commit
b93c0f7ed8
@@ -1690,7 +1690,13 @@ public:
|
||||
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 <typename T,
|
||||
detail::enable_if_t<!std::is_base_of<object, detail::remove_cvref_t<T>>::value
|
||||
&& std::is_constructible<handle, T>::value,
|
||||
int>
|
||||
= 0>
|
||||
explicit str(T &&h) : object(raw_str(handle(std::forward<T>(h)).ptr()), stolen_t{}) {
|
||||
if (!m_ptr) {
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -5,6 +5,7 @@ import sys
|
||||
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")
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -9,8 +9,12 @@ import textwrap
|
||||
|
||||
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 = (
|
||||
|
||||
@@ -1211,4 +1211,6 @@ TEST_SUBMODULE(pytypes, m) {
|
||||
m.def("check_type_is", [](const py::object &x) -> py::typing::TypeIs<RealNumber> {
|
||||
return py::isinstance<RealNumber>(x);
|
||||
});
|
||||
|
||||
m.def("const_kwargs_ref_to_str", [](const py::kwargs &kwargs) { return py::str(kwargs); });
|
||||
}
|
||||
|
||||
@@ -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}"
|
||||
|
||||
Reference in New Issue
Block a user