[robotpy] Add wrapper for timestamp functions, like SetNowImpl (#8889)

`SetNowImpl` is used somewhat often in unit tests. It is a little bit
goofier to wrap because it takes a C function, so a little bit more work
has to be done to get that wrapped in pybind.

Claude helped.
This commit is contained in:
PJ Reiniger
2026-05-15 00:53:26 -04:00
committed by GitHub
parent 68d24bb29e
commit 6ba5734a94
7 changed files with 120 additions and 0 deletions

View File

@@ -75,6 +75,7 @@ Synchronization = "wpi/util/Synchronization.hpp"
PixelFormat = "wpi/util/PixelFormat.hpp"
RawFrame_c = "wpi/util/RawFrame.h"
RawFrame = "wpi/util/RawFrame.hpp"
Timestamp = "wpi/util/timestamp.hpp"
# wpi/sendable
Sendable = "wpi/util/sendable/Sendable.hpp"

View File

@@ -0,0 +1,6 @@
functions:
NowDefault:
SetNowImpl:
ignore: true # This is more complicated, so it is handled by src/timestmap.cpp
Now:
GetSystemTime:

View File

@@ -4,10 +4,14 @@ from . import _init__wpiutil
from ._wpiutil import (
Color,
Color8Bit,
getSystemTime,
now,
nowDefault,
PixelFormat,
Sendable,
SendableBuilder,
SendableRegistry,
SetNowImpl,
TimestampSource,
getStackTrace,
getStackTraceDefault,
@@ -16,10 +20,14 @@ from ._wpiutil import (
__all__ = [
"Color",
"Color8Bit",
"getSystemTime",
"now",
"nowDefault",
"PixelFormat",
"Sendable",
"SendableBuilder",
"SendableRegistry",
"SetNowImpl",
"TimestampSource",
"getStackTrace",
"getStackTraceDefault",

View File

@@ -7,6 +7,9 @@ void cleanup_stack_trace_hook();
void setup_safethread_gil();
void cleanup_safethread_gil();
void set_now_impl(py::object fn);
void cleanup_now_impl();
#ifndef __FIRST_SYSTEMCORE__
namespace wpi::util::impl {
@@ -32,10 +35,12 @@ SEMIWRAP_PYBIND11_MODULE(m) {
cleanup_sendable_registry();
cleanup_stack_trace_hook();
cleanup_safethread_gil();
cleanup_now_impl();
});
setup_safethread_gil();
m.def("_setup_stack_trace_hook", &setup_stack_trace_hook);
m.def("SetNowImpl", &set_now_impl);
m.add_object("_st_cleanup", cleanup);
}

View File

@@ -0,0 +1,46 @@
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include "wpi/util/timestamp.hpp"
namespace py = pybind11;
py::object &get_now_impl_ref() {
static py::object get_now_impl_ref;
return get_now_impl_ref;
}
// Helper function to massage the python callback into a C api
uint64_t now_impl_trampoline() {
py::gil_scoped_acquire acquire;
try {
auto &hook = get_now_impl_ref();
if (hook) {
return hook().cast<uint64_t>();
}
} catch (py::error_already_set &e) {
e.discard_as_unraisable("wpiutil.now_impl_trampoline");
}
return wpi::util::NowDefault();
}
void set_now_impl(py::object func) {
get_now_impl_ref() = func;
if (func.is_none()) {
wpi::util::SetNowImpl(nullptr);
} else {
wpi::util::SetNowImpl(&now_impl_trampoline);
}
}
void cleanup_now_impl() {
wpi::util::SetNowImpl(nullptr);
// release the function during interpreter shutdown
auto &hook = get_now_impl_ref();
if (hook) {
hook.dec_ref();
hook.release();
}
}