Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(types): add support for typing.Literal type #5192

Merged
merged 77 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
d872367
typevar prototype
InvincibleRMC Jun 14, 2024
1012f10
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
fbd168a
change to NameT
InvincibleRMC Jun 14, 2024
34bf41b
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
63acf62
make string const
InvincibleRMC Jun 14, 2024
38fd357
add missing closing bracket
InvincibleRMC Jun 14, 2024
614d03e
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
d354512
clean up handle_type_name
InvincibleRMC Jun 14, 2024
7b8c860
Merge branch 'typevars' of github.com:InvincibleRMC/pybind11 into typ…
InvincibleRMC Jun 14, 2024
a198152
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
ee00f70
add back missing <
InvincibleRMC Jun 14, 2024
e19ee22
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
98f836e
add back NameT
InvincibleRMC Jun 14, 2024
e1dc7a5
try fixed_string
InvincibleRMC Jun 14, 2024
14ea23d
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
5e5066c
std::basic_fixed_string
InvincibleRMC Jun 14, 2024
534dd65
test c++20
InvincibleRMC Jun 14, 2024
651227f
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
0f8864c
cleanup
InvincibleRMC Jun 14, 2024
b549902
fix object to typevar conversion
InvincibleRMC Jun 14, 2024
a858638
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
0380dc1
And CPP20 checks
InvincibleRMC Jun 14, 2024
3cc5a14
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
34ecc43
add missing cpp20++ check
InvincibleRMC Jun 14, 2024
dd8d648
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
e98b6a0
Add C++20 check to python
InvincibleRMC Jun 14, 2024
4122505
Fix python if {
InvincibleRMC Jun 14, 2024
c66ebd7
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
9954c18
update test name
InvincibleRMC Jun 14, 2024
7e07f5e
Merge
InvincibleRMC Jun 14, 2024
bd954e6
style: pre-commit fixes
pre-commit-ci[bot] Jun 14, 2024
8675c5c
remove call on cpp_std
InvincibleRMC Jun 14, 2024
9cd1b16
make field const
InvincibleRMC Jun 14, 2024
4e3821d
test nontype_template
InvincibleRMC Jun 14, 2024
dd3d0cc
update feature check
InvincibleRMC Jun 14, 2024
0a34ddb
update name of guard
InvincibleRMC Jun 14, 2024
c572871
fix try except in test
InvincibleRMC Jun 14, 2024
676e3bd
fix pre commit
InvincibleRMC Jun 14, 2024
5dd1d3b
remove extra semi colon
InvincibleRMC Jun 14, 2024
98c115d
except AttributeError
InvincibleRMC Jun 14, 2024
1dab40f
fix try except in test
InvincibleRMC Jun 14, 2024
39516fd
remove const
InvincibleRMC Jun 14, 2024
237136a
Clean up tests
InvincibleRMC Jun 15, 2024
d13e3d5
style: pre-commit fixes
pre-commit-ci[bot] Jun 15, 2024
10739e6
start string literal
InvincibleRMC Jun 15, 2024
6dae701
Merge branch 'typevars' into Literal-type
InvincibleRMC Jun 15, 2024
311fa83
start int literal
InvincibleRMC Jun 15, 2024
7c3c09e
func declare
InvincibleRMC Jun 15, 2024
905638a
commit clean
InvincibleRMC Jun 15, 2024
a6c5676
use contextlib.suppres
InvincibleRMC Jun 15, 2024
6266705
Merge branch 'typevars' into Literal-type
InvincibleRMC Jun 15, 2024
c045695
resolve stash
InvincibleRMC Jun 15, 2024
519e32b
more literal type
InvincibleRMC Jun 15, 2024
ba3259b
fix annotation name
InvincibleRMC Jun 15, 2024
f087d74
stash
InvincibleRMC Jun 15, 2024
2542b79
Merge remote-tracking branch 'origin/master' into typevars
InvincibleRMC Jun 15, 2024
ca868f8
request changes
InvincibleRMC Jun 15, 2024
0789290
Merge branch 'master' into typevars
InvincibleRMC Jun 15, 2024
32fde8e
lint
InvincibleRMC Jun 15, 2024
318ec6d
Add comments
InvincibleRMC Jun 15, 2024
e9f7889
style: pre-commit fixes
pre-commit-ci[bot] Jun 15, 2024
648c5a0
Add support for unions and optionals to be compatible with object
InvincibleRMC Jun 15, 2024
c452d2f
lint
InvincibleRMC Jun 15, 2024
7b83557
remove comment
InvincibleRMC Jun 15, 2024
2351814
Merge remote-tracking branch 'origin/master' into Literal-type
InvincibleRMC Jun 24, 2024
652197e
Merge branch 'typevars' into Literal-type
InvincibleRMC Jun 24, 2024
4bd4351
Create Literal Type implementation
InvincibleRMC Jun 24, 2024
30c790e
clean up
InvincibleRMC Jun 24, 2024
b65b945
Update comment
InvincibleRMC Jun 24, 2024
00ba9fa
remove incorrect comment
InvincibleRMC Jun 25, 2024
2cb5b03
rerun CI
InvincibleRMC Jun 25, 2024
3d20c57
rerun CI
InvincibleRMC Jun 25, 2024
224335d
Merge remote-tracking branch 'origin/master' into Literal-type
InvincibleRMC Jun 25, 2024
0223244
fix extra line
InvincibleRMC Jun 25, 2024
0f302d9
lint
InvincibleRMC Jun 25, 2024
befcb78
move if defined block
InvincibleRMC Jun 25, 2024
dcf8e49
style: pre-commit fixes
pre-commit-ci[bot] Jun 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions include/pybind11/typing.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,13 @@ class Optional : public object {
#if defined(__cpp_nontype_template_parameter_class)
template <size_t N>
struct StringLiteral {
constexpr StringLiteral(const char (&str)[N]) { std::copy_n(str, N, value); }
char value[N];
constexpr StringLiteral(const char (&str)[N]) { std::copy_n(str, N, name); }
char name[N];
};

template <StringLiteral... StrLits>
class Literal : public object {
PYBIND11_OBJECT_DEFAULT(Literal, object, PyObject_Type)
};

// Example syntax for creating a TypeVar.
Expand Down Expand Up @@ -172,9 +177,15 @@ struct handle_type_name<typing::Optional<T>> {
};

#if defined(__cpp_nontype_template_parameter_class)
template <typing::StringLiteral... Literals>
struct handle_type_name<typing::Literal<Literals...>> {
static constexpr auto name = const_name("Literal[")
+ pybind11::detail::concat(const_name(Literals.name)...)
+ const_name("]");
};
template <typing::StringLiteral StrLit>
struct handle_type_name<typing::TypeVar<StrLit>> {
static constexpr auto name = const_name(StrLit.value);
static constexpr auto name = const_name(StrLit.name);
};
#endif

Expand Down
19 changes: 19 additions & 0 deletions tests/test_pytypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ void m_defs(py::module_ &m) {
} // namespace handle_from_move_only_type_with_operator_PyObject

#if defined(__cpp_nontype_template_parameter_class)
namespace literals {
enum Color { RED = 0, BLUE = 1 };

typedef py::typing::Literal<"26",
"0x1A",
"\"hello world\"",
"b\"hello world\"",
"u\"hello world\"",
"True",
"Color.RED",
"None">
LiteralFoo;
} // namespace literals
namespace typevar {
typedef py::typing::TypeVar<"T"> TypeVarT;
typedef py::typing::TypeVar<"V"> TypeVarV;
Expand Down Expand Up @@ -851,6 +864,7 @@ TEST_SUBMODULE(pytypes, m) {
m.def("annotate_iterator_int", [](const py::typing::Iterator<int> &) {});
m.def("annotate_fn",
[](const py::typing::Callable<int(py::typing::List<py::str>, py::str)> &) {});

m.def("annotate_type", [](const py::typing::Type<int> &t) -> py::type { return t; });

m.def("annotate_union",
Expand Down Expand Up @@ -881,6 +895,11 @@ TEST_SUBMODULE(pytypes, m) {
[](py::typing::Optional<int> &o) -> py::object { return o; });

#if defined(__cpp_nontype_template_parameter_class)
py::enum_<literals::Color>(m, "Color")
.value("RED", literals::Color::RED)
.value("BLUE", literals::Color::BLUE);

m.def("annotate_literal", [](literals::LiteralFoo &o) -> py::object { return o; });
m.def("annotate_generic_containers",
[](const py::typing::List<typevar::TypeVarT> &l) -> py::typing::List<typevar::TypeVarV> {
return l;
Expand Down
11 changes: 11 additions & 0 deletions tests/test_pytypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,17 @@ def test_optional_object_annotations(doc):
)


@pytest.mark.skipif(
not m.if_defined__cpp_nontype_template_parameter_class,
reason="C++20 feature not available.",
)
def test_literal(doc):
assert (
doc(m.annotate_literal)
== 'annotate_literal(arg0: Literal[26, 0x1A, "hello world", b"hello world", u"hello world", True, Color.RED, None]) -> object'
)


@pytest.mark.skipif(
not m.if_defined__cpp_nontype_template_parameter_class,
reason="C++20 feature not available.",
Expand Down
Loading