Add test_cases_for_stubgen

Material to inform https://github.com/python/mypy/issues/16306
This commit is contained in:
Ralf W. Grosse-Kunstleve 2023-11-14 13:01:42 -08:00
parent 0b984334d9
commit 781304e431
3 changed files with 141 additions and 0 deletions

View File

@ -117,6 +117,7 @@ set(PYBIND11_TEST_FILES
test_builtin_casters
test_call_policies
test_callbacks
test_cases_for_stubgen
test_chrono
test_class
test_const_name

View File

@ -0,0 +1,72 @@
#include "pybind11/stl_bind.h"
#include "pybind11_tests.h"
#include <map>
namespace test_cases_for_stubgen {
struct user_type {
bool operator<(const user_type &) const { return false; }
};
struct minimal_caster {
static constexpr auto name = py::detail::const_name<user_type>();
static py::handle
cast(user_type const & /*src*/, py::return_value_policy /*policy*/, py::handle /*parent*/) {
return py::none().release();
}
// Maximizing simplicity. This will go terribly wrong for other arg types.
template <typename>
using cast_op_type = const user_type &;
// NOLINTNEXTLINE(google-explicit-constructor)
operator user_type const &() {
static user_type obj;
return obj;
}
bool load(py::handle /*src*/, bool /*convert*/) { return false; }
};
} // namespace test_cases_for_stubgen
namespace pybind11 {
namespace detail {
template <>
struct type_caster<test_cases_for_stubgen::user_type> : test_cases_for_stubgen::minimal_caster {};
} // namespace detail
} // namespace pybind11
TEST_SUBMODULE(cases_for_stubgen, m) {
using namespace test_cases_for_stubgen;
m.def("pass_user_type", [](const user_type &) {});
m.def("return_user_type", []() { return user_type(); });
py::bind_map<std::map<int, user_type>>(m, "MapIntUserType");
py::bind_map<std::map<user_type, int>>(m, "MapUserTypeInt");
#define MAP_TYPE(MapTypePythonName, ...) \
py::class_<__VA_ARGS__>(m, MapTypePythonName) \
.def( \
"keys", \
[](const __VA_ARGS__ &v) { return py::make_key_iterator(v); }, \
py::keep_alive<0, 1>()) \
.def( \
"values", \
[](const __VA_ARGS__ &v) { return py::make_value_iterator(v); }, \
py::keep_alive<0, 1>()) \
.def( \
"__iter__", \
[](const __VA_ARGS__ &v) { return py::make_iterator(v.begin(), v.end()); }, \
py::keep_alive<0, 1>())
MAP_TYPE("MapFloatUserType", std::map<float, user_type>);
MAP_TYPE("MapUserTypeFloat", std::map<user_type, float>);
#undef MAP_TYPE
}

View File

@ -0,0 +1,68 @@
import pytest
from pybind11_tests import cases_for_stubgen as m
@pytest.mark.parametrize(
("docstring", "expected"),
[
(
m.pass_user_type.__doc__,
'pass_user_type(arg0: Annotated[Any, "test_cases_for_stubgen::user_type"]) -> None\n',
),
(
m.return_user_type.__doc__,
'return_user_type() -> Annotated[Any, "test_cases_for_stubgen::user_type"]\n',
),
(
m.MapIntUserType.keys.__doc__,
"keys(self: pybind11_tests.cases_for_stubgen.MapIntUserType) -> pybind11_tests.cases_for_stubgen.KeysView[int]\n",
),
(
m.MapIntUserType.values.__doc__,
"values(self: pybind11_tests.cases_for_stubgen.MapIntUserType) -> pybind11_tests.cases_for_stubgen.ValuesView[test_cases_for_stubgen::user_type]\n",
),
(
m.MapIntUserType.items.__doc__,
"items(self: pybind11_tests.cases_for_stubgen.MapIntUserType) -> pybind11_tests.cases_for_stubgen.ItemsView[int, test_cases_for_stubgen::user_type]\n",
),
(
m.MapUserTypeInt.keys.__doc__,
"keys(self: pybind11_tests.cases_for_stubgen.MapUserTypeInt) -> pybind11_tests.cases_for_stubgen.KeysView[test_cases_for_stubgen::user_type]\n",
),
(
m.MapUserTypeInt.values.__doc__,
"values(self: pybind11_tests.cases_for_stubgen.MapUserTypeInt) -> pybind11_tests.cases_for_stubgen.ValuesView[int]\n",
),
(
m.MapUserTypeInt.items.__doc__,
"items(self: pybind11_tests.cases_for_stubgen.MapUserTypeInt) -> pybind11_tests.cases_for_stubgen.ItemsView[test_cases_for_stubgen::user_type, int]\n",
),
(
m.MapFloatUserType.keys.__doc__,
"keys(self: pybind11_tests.cases_for_stubgen.MapFloatUserType) -> Iterator[float]\n",
),
(
m.MapFloatUserType.values.__doc__,
'values(self: pybind11_tests.cases_for_stubgen.MapFloatUserType) -> Iterator[Annotated[Any, "test_cases_for_stubgen::user_type"]]\n',
),
(
m.MapFloatUserType.__iter__.__doc__,
'__iter__(self: pybind11_tests.cases_for_stubgen.MapFloatUserType) -> Iterator[tuple[float, Annotated[Any, "test_cases_for_stubgen::user_type"]]]\n',
),
(
m.MapUserTypeFloat.keys.__doc__,
'keys(self: pybind11_tests.cases_for_stubgen.MapUserTypeFloat) -> Iterator[Annotated[Any, "test_cases_for_stubgen::user_type"]]\n',
),
(
m.MapUserTypeFloat.values.__doc__,
"values(self: pybind11_tests.cases_for_stubgen.MapUserTypeFloat) -> Iterator[float]\n",
),
(
m.MapUserTypeFloat.__iter__.__doc__,
'__iter__(self: pybind11_tests.cases_for_stubgen.MapUserTypeFloat) -> Iterator[tuple[Annotated[Any, "test_cases_for_stubgen::user_type"], float]]\n',
),
],
)
def test_docstring(docstring, expected):
assert docstring == expected