From 7e49beb034fd81581fa2dbd5d9b4b0a67dd5ef2c Mon Sep 17 00:00:00 2001 From: Amidwestnoob Date: Sat, 12 Sep 2026 03:38:42 +0000 Subject: [PATCH] fix(ntcore): register bool put/set overloads before double Under pybind11 3.1, Python bool subclasses int and can bind the double overload when it is registered first. Put bool first with noconvert so True/False stay boolean NT values. Closes #318 --- .../pyntcore/ntcore/src/NetworkTable.cpp.inl | 18 ++++++++++-------- .../ntcore/src/NetworkTableEntry.cpp.inl | 18 ++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/subprojects/pyntcore/ntcore/src/NetworkTable.cpp.inl b/subprojects/pyntcore/ntcore/src/NetworkTable.cpp.inl index fd2b31343..014a05609 100644 --- a/subprojects/pyntcore/ntcore/src/NetworkTable.cpp.inl +++ b/subprojects/pyntcore/ntcore/src/NetworkTable.cpp.inl @@ -14,12 +14,13 @@ cls_NetworkTable return pyntcore::GetValueEntry(entry, defaultValue); }, py::arg("key"), py::arg("value")) - // double overload must come before boolean version - .def("put_value", [](wpi::nt::NetworkTable *self, std::string_view key, double value) { - return self->PutValue(key, wpi::nt::Value::MakeDouble(value)); - }, py::arg("key"), py::arg("value"), release_gil()) + // bool before double: under pybind11 3.1, bool subclasses int and would + // otherwise bind the double overload (see robotpy/mostrobotpy#318). .def("put_value", [](wpi::nt::NetworkTable *self, std::string_view key, bool value) { return self->PutValue(key, wpi::nt::Value::MakeBoolean(value)); + }, py::arg("key"), py::arg("value").noconvert(), release_gil()) + .def("put_value", [](wpi::nt::NetworkTable *self, std::string_view key, double value) { + return self->PutValue(key, wpi::nt::Value::MakeDouble(value)); }, py::arg("key"), py::arg("value"), release_gil()) .def("put_value", [](wpi::nt::NetworkTable *self, std::string_view key, py::bytes value) { auto v = wpi::nt::Value::MakeRaw(value.cast>()); @@ -35,12 +36,13 @@ cls_NetworkTable return self->PutValue(key, v); }, py::arg("key"), py::arg("value")) - // double overload must come before boolean version - .def("set_default_value", [](wpi::nt::NetworkTable *self, std::string_view key, double value) { - return self->SetDefaultValue(key, wpi::nt::Value::MakeDouble(value)); - }, py::arg("key"), py::arg("value"), release_gil()) + // bool before double: under pybind11 3.1, bool subclasses int and would + // otherwise bind the double overload (see robotpy/mostrobotpy#318). .def("set_default_value", [](wpi::nt::NetworkTable *self, std::string_view key, bool value) { return self->SetDefaultValue(key, wpi::nt::Value::MakeBoolean(value)); + }, py::arg("key"), py::arg("value").noconvert(), release_gil()) + .def("set_default_value", [](wpi::nt::NetworkTable *self, std::string_view key, double value) { + return self->SetDefaultValue(key, wpi::nt::Value::MakeDouble(value)); }, py::arg("key"), py::arg("value"), release_gil()) .def("set_default_value", [](wpi::nt::NetworkTable *self, std::string_view key, py::bytes value) { auto v = wpi::nt::Value::MakeRaw(value.cast>()); diff --git a/subprojects/pyntcore/ntcore/src/NetworkTableEntry.cpp.inl b/subprojects/pyntcore/ntcore/src/NetworkTableEntry.cpp.inl index eab376456..dadb4f625 100644 --- a/subprojects/pyntcore/ntcore/src/NetworkTableEntry.cpp.inl +++ b/subprojects/pyntcore/ntcore/src/NetworkTableEntry.cpp.inl @@ -13,12 +13,13 @@ cls_NetworkTableEntry return pyntcore::ntvalue2py(v); }) - // double overload must come before boolean version - .def("set_value", [](wpi::nt::NetworkTableEntry *self, double value) { - return self->SetValue(wpi::nt::Value::MakeDouble(value)); - }, py::arg("value"), release_gil()) + // bool before double: under pybind11 3.1, bool subclasses int and would + // otherwise bind the double overload (see robotpy/mostrobotpy#318). .def("set_value", [](wpi::nt::NetworkTableEntry *self, bool value) { return self->SetValue(wpi::nt::Value::MakeBoolean(value)); + }, py::arg("value").noconvert(), release_gil()) + .def("set_value", [](wpi::nt::NetworkTableEntry *self, double value) { + return self->SetValue(wpi::nt::Value::MakeDouble(value)); }, py::arg("value"), release_gil()) .def("set_value", [](wpi::nt::NetworkTableEntry *self, py::bytes value) { auto v = wpi::nt::Value::MakeRaw(value.cast>()); @@ -32,12 +33,13 @@ cls_NetworkTableEntry return self->SetValue(pyntcore::py2ntvalue(value)); }, py::arg("value")) - // double overload must come before boolean version - .def("set_default_value", [](wpi::nt::NetworkTableEntry *self, double value) { - return self->SetDefaultValue(wpi::nt::Value::MakeDouble(value)); - }, py::arg("value"), release_gil()) + // bool before double: under pybind11 3.1, bool subclasses int and would + // otherwise bind the double overload (see robotpy/mostrobotpy#318). .def("set_default_value", [](wpi::nt::NetworkTableEntry *self, bool value) { return self->SetDefaultValue(wpi::nt::Value::MakeBoolean(value)); + }, py::arg("value").noconvert(), release_gil()) + .def("set_default_value", [](wpi::nt::NetworkTableEntry *self, double value) { + return self->SetDefaultValue(wpi::nt::Value::MakeDouble(value)); }, py::arg("value"), release_gil()) .def("set_default_value", [](wpi::nt::NetworkTableEntry *self, py::bytes value) { auto v = wpi::nt::Value::MakeRaw(value.cast>());