• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

llnl-asr / dftracer-utils / 36502607218

29 Sep 2026 12:20AM UTC coverage: 57.996% (+5.4%) from 52.58%
36502607218

push

github

rayandrew
Merge branch 'feat/view-as-lazyframe' into 'develop'

feat: view as lazyframe

See merge request dftracer/dftracer-utils!25

74077 of 162805 branches covered (45.5%)

Branch coverage included in aggregate %.

3652 of 3978 new or added lines in 49 files covered. (91.8%)

3464 existing lines in 85 files now uncovered.

65902 of 78556 relevant lines covered (83.89%)

179668.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

6.59
/src/dftracer/utils/python/task_handle.cpp
1
#define PY_SSIZE_T_CLEAN
2
#include <Python.h>
3
#include <dftracer/utils/python/py_errors.h>
4
#include <dftracer/utils/python/py_method.h>
5
#include <dftracer/utils/python/py_runtime_mixin.h>
6
#include <dftracer/utils/python/py_type_helpers.h>
7
#include <dftracer/utils/python/task_handle.h>
8

9
#include <any>
10
#include <chrono>
11
#include <future>
12
#include <string>
13

14
static void TaskHandle_dealloc(TaskHandleObject *self) {
×
15
    self->future.~shared_future();
×
16
    self->typed_future.~shared_future();
×
17
    self->name.~basic_string();
×
18
    Py_TYPE(self)->tp_free((PyObject *)self);
×
UNCOV
19
}
×
20

UNCOV
21
static PyObject *TaskHandle_new(PyTypeObject *type, PyObject * /*args*/,
×
22
                                PyObject * /*kwds*/) {
23
    TaskHandleObject *self = (TaskHandleObject *)type->tp_alloc(type, 0);
×
24
    if (self) {
×
25
        new (&self->future) std::shared_future<void>();
×
26
        new (&self->typed_future) std::shared_future<std::any>();
×
27
        new (&self->name) std::string();
×
28
        self->has_typed_future = false;
×
UNCOV
29
        self->task_id = -1;
×
30
    }
UNCOV
31
    return (PyObject *)self;
×
32
}
33

UNCOV
34
static PyObject *TaskHandle_get(TaskHandleObject *self,
×
35
                                PyObject *Py_UNUSED(ignored)) {
36
    if (!self->future.valid()) {
×
UNCOV
37
        Py_RETURN_NONE;
×
38
    }
39
    if (self->has_typed_future) {
×
40
        std::any result;
×
41
        if (!run_blocking_r([&] { return self->typed_future.get(); }, result))
×
42
            return NULL;
×
UNCOV
43
        if (result.has_value()) {
×
44
            try {
45
                PyObject *obj = std::any_cast<PyObject *>(result);
×
UNCOV
46
                if (obj) {
×
47
                    Py_INCREF(obj);
×
UNCOV
48
                    return obj;
×
49
                }
UNCOV
50
            } catch (const std::bad_any_cast &) {
×
51
                // Not a PyObject* — fall through to None
UNCOV
52
            }
×
53
        }
54
        Py_RETURN_NONE;
×
UNCOV
55
    }
×
56

57
    // Void task: .get() returns void and rethrows stored exceptions.
58
    if (!run_blocking([&] { self->future.get(); })) return NULL;
×
UNCOV
59
    Py_RETURN_NONE;
×
60
}
61

UNCOV
62
static PyObject *TaskHandle_wait(TaskHandleObject *self,
×
63
                                 PyObject *Py_UNUSED(ignored)) {
64
    if (!self->future.valid()) {
×
UNCOV
65
        Py_RETURN_NONE;
×
66
    }
67
    // Use .get() (not .wait()) so stored exceptions are rethrown.
68
    if (!run_blocking([&] { self->future.get(); })) return NULL;
×
UNCOV
69
    Py_RETURN_NONE;
×
70
}
71

UNCOV
72
static PyObject *TaskHandle_done(TaskHandleObject *self,
×
73
                                 PyObject *Py_UNUSED(ignored)) {
74
    if (!self->future.valid()) {
×
UNCOV
75
        Py_RETURN_FALSE;
×
76
    }
UNCOV
77
    bool is_done = self->future.wait_for(std::chrono::seconds(0)) ==
×
78
                   std::future_status::ready;
UNCOV
79
    return PyBool_FromLong(is_done ? 1 : 0);
×
80
}
81

82
static PyObject *TaskHandle_get_name(TaskHandleObject *self, void *) {
×
83
    return PyUnicode_FromStringAndSize(
×
UNCOV
84
        self->name.data(), static_cast<Py_ssize_t>(self->name.size()));
×
85
}
86

87
static PyObject *TaskHandle_get_task_id(TaskHandleObject *self, void *) {
×
UNCOV
88
    return PyLong_FromLongLong(static_cast<long long>(self->task_id));
×
89
}
90

91
static PyMethodDef TaskHandle_methods[] = {
92
    {"get", DFTU_PYCFUNCTION(TaskHandle_get), METH_NOARGS,
93
     "Block until task completes and return result.\n"
94
     "Raises RuntimeError if the task failed."},
95
    {"wait", DFTU_PYCFUNCTION(TaskHandle_wait), METH_NOARGS,
96
     "Block until task completes.\n"
97
     "Raises RuntimeError if the task failed."},
98
    {"done", DFTU_PYCFUNCTION(TaskHandle_done), METH_NOARGS,
99
     "Return True if task has completed."},
100
    {NULL}};
101

102
static PyGetSetDef TaskHandle_getsetters[] = {
103
    {"name", (getter)TaskHandle_get_name, NULL, "Task name", NULL},
104
    {"task_id", (getter)TaskHandle_get_task_id, NULL, "Task identifier", NULL},
105
    {NULL}};
106

107
PyTypeObject TaskHandleType = {
108
    PyVarObject_HEAD_INIT(NULL, 0) "dftracer_utils_ext.TaskHandle",
109
    sizeof(TaskHandleObject),                       /* tp_basicsize */
110
    0,                                              /* tp_itemsize */
111
    (destructor)TaskHandle_dealloc,                 /* tp_dealloc */
112
    0,                                              /* tp_vectorcall_offset */
113
    0,                                              /* tp_getattr */
114
    0,                                              /* tp_setattr */
115
    0,                                              /* tp_as_async */
116
    0,                                              /* tp_repr */
117
    0,                                              /* tp_as_number */
118
    0,                                              /* tp_as_sequence */
119
    0,                                              /* tp_as_mapping */
120
    0,                                              /* tp_hash */
121
    0,                                              /* tp_call */
122
    0,                                              /* tp_str */
123
    0,                                              /* tp_getattro */
124
    0,                                              /* tp_setattro */
125
    0,                                              /* tp_as_buffer */
126
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,       /* tp_flags */
127
    "Handle to an async task submitted to Runtime", /* tp_doc */
128
    0,                                              /* tp_traverse */
129
    0,                                              /* tp_clear */
130
    0,                                              /* tp_richcompare */
131
    0,                                              /* tp_weaklistoffset */
132
    0,                                              /* tp_iter */
133
    0,                                              /* tp_iternext */
134
    TaskHandle_methods,                             /* tp_methods */
135
    0,                                              /* tp_members */
136
    TaskHandle_getsetters,                          /* tp_getset */
137
    0,                                              /* tp_base */
138
    0,                                              /* tp_dict */
139
    0,                                              /* tp_descr_get */
140
    0,                                              /* tp_descr_set */
141
    0,                                              /* tp_dictoffset */
142
    0,                                              /* tp_init */
143
    0,                                              /* tp_alloc */
144
    TaskHandle_new,                                 /* tp_new */
145
};
146

147
int dftracer::utils::python::init_task_handle(PyObject *m) {
2 ✔
148
    if (register_type(m, &TaskHandleType, "TaskHandle") < 0) return -1;
2 ✔
149
    return 0;
2 ✔
150
}
1 ✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc