Compare commits

...

8 Commits

Author SHA1 Message Date
Tim Ohliger 341138d604
Merge 7d16bad5a9 into 1f8b4a7f1a 2024-09-20 23:41:38 -07:00
Hintay 1f8b4a7f1a
fix(cmake): `NO_EXTRAS` in `pybind11_add_module` function partially working (#5378) 2024-09-19 11:24:35 -04:00
Tim Ohliger 7d16bad5a9 Added unit test for list/vector of paths. 2024-09-06 18:06:54 +02:00
pre-commit-ci[bot] 23ceaba974 style: pre-commit fixes 2024-09-06 13:55:24 +00:00
Tim Ohliger 85052afe65 Using `std::enable_if` instead of `std::enable_if_t` for C++ support. 2024-09-06 15:50:12 +02:00
Tim Ohliger e8aa81bd9a Applied pre-commit formatting. 2024-09-06 15:24:25 +02:00
Tim Ohliger 7e7f9ce67b Applied `return_name` to `type_caster` for `std::fileystem::path`.
The `type_caster` previously named `os.PathLike` as both argument and
return type. This is inaccurate since it also takes `str` and `byte` as
argument and actually returns `Path`. This commit uses the new
`return_name` feature to define argument type as
`Union[os.PathLike, str, bytes]` and return type as `Path`.
An assert was added to the unit test for this.
2024-09-06 14:30:41 +02:00
Tim Ohliger dd829c5994 Added option to add `return_name` to custom `type_caster`.
This allows to define different python type hints for arguments and
return value. This is implemented using template class `as_return_type`
in order to check if `return_name` is available in the `type_caster` at
compile time. If `return_name` is not available, it falls back to the
previous usage of `name` for both args and return value.
2024-09-06 14:25:42 +02:00
5 changed files with 45 additions and 8 deletions

View File

@ -101,6 +101,30 @@ inline std::string replace_newlines_and_squash(const char *text) {
# define PYBIND11_COMPAT_STRDUP strdup
#endif
/// Type trait checker for `descr`.
template <typename>
struct is_descr : std::false_type {};
template <size_t N, typename... Ts>
struct is_descr<descr<N, Ts...>> : std::true_type {};
template <size_t N, typename... Ts>
struct is_descr<const descr<N, Ts...>> : std::true_type {};
/// Checks for `return_name` in `type_caster` to replace `name` for return type hints.
/// this is useful for having a different python type hint for args vs return value,
/// e.g., `std::filesystem::path` -> Arg: `Union[os.PathLike, str, bytes]`, return: `Path`.
template <typename T, typename Enable = void>
struct as_return_type {
static constexpr auto name = T::name;
};
template <typename T>
struct as_return_type<T,
typename std::enable_if<is_descr<decltype(T::return_name)>::value>::type> {
static constexpr auto name = T::return_name;
};
PYBIND11_NAMESPACE_END(detail)
/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object
@ -319,8 +343,8 @@ protected:
/* Generate a readable signature describing the function's arguments and return
value types */
static constexpr auto signature
= const_name("(") + cast_in::arg_names + const_name(") -> ") + cast_out::name;
static constexpr auto signature = const_name("(") + cast_in::arg_names
+ const_name(") -> ") + as_return_type<cast_out>::name;
PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types();
/* Register the function with Python from generic (non-templated) code */

View File

@ -106,7 +106,8 @@ public:
return true;
}
PYBIND11_TYPE_CASTER(T, const_name("os.PathLike"));
PYBIND11_TYPE_CASTER(T, const_name("Union[os.PathLike, str, bytes]"));
static constexpr auto return_name = const_name("Path");
};
#endif // PYBIND11_HAS_FILESYSTEM || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)

View File

@ -454,6 +454,13 @@ TEST_SUBMODULE(stl, m) {
// test_fs_path
m.attr("has_filesystem") = true;
m.def("parent_path", [](const std::filesystem::path &p) { return p.parent_path(); });
m.def("parent_paths", [](const std::vector<std::filesystem::path> &p) {
std::vector<std::filesystem::path> result;
for (const auto &i : p) {
result.push_back(i.parent_path());
}
return result;
});
#endif
#ifdef PYBIND11_TEST_VARIANT

View File

@ -245,7 +245,7 @@ def test_reference_sensitive_optional():
@pytest.mark.skipif(not hasattr(m, "has_filesystem"), reason="no <filesystem>")
def test_fs_path():
def test_fs_path(doc):
from pathlib import Path
class PseudoStrPath:
@ -261,6 +261,15 @@ def test_fs_path():
assert m.parent_path(b"foo/bar") == Path("foo")
assert m.parent_path(PseudoStrPath()) == Path("foo")
assert m.parent_path(PseudoBytesPath()) == Path("foo")
assert (
doc(m.parent_path)
== "parent_path(arg0: Union[os.PathLike, str, bytes]) -> Path"
)
assert m.parent_paths(["foo/bar", "foo/baz"]) == [Path("foo"), Path("foo")]
assert (
doc(m.parent_paths)
== "parent_paths(arg0: list[Union[os.PathLike, str, bytes]]) -> list[Path]"
)
@pytest.mark.skipif(not hasattr(m, "load_variant"), reason="no <variant>")

View File

@ -274,10 +274,6 @@ function(pybind11_add_module target_name)
target_link_libraries(${target_name} PRIVATE pybind11::embed)
endif()
if(MSVC)
target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
endif()
# -fvisibility=hidden is required to allow multiple modules compiled against
# different pybind versions to work properly, and for some features (e.g.
# py::module_local). We force it on everything inside the `pybind11`