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

llnl / dftracer-utils / 28982597416

08 Jul 2026 11:22PM UTC coverage: 50.709% (-1.9%) from 52.577%
28982597416

Pull #87

github

web-flow
Merge fdf73a826 into 4908d9921
Pull Request #87: fix(comparator): fix wrong counting files

16259 of 43579 branches covered (37.31%)

Branch coverage included in aggregate %.

37 of 38 new or added lines in 4 files covered. (97.37%)

616 existing lines in 111 files now uncovered.

21634 of 31148 relevant lines covered (69.46%)

13117.41 hits per line

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

29.61
/src/dftracer/utils/python/py_runtime_mixin.h
1
#ifndef DFTRACER_UTILS_PYTHON_PY_RUNTIME_MIXIN_H
2
#define DFTRACER_UTILS_PYTHON_PY_RUNTIME_MIXIN_H
3

4
#include <Python.h>
5
#include <dftracer/utils/core/common/error.h>
6
#include <dftracer/utils/python/py_errors.h>
7
#include <dftracer/utils/python/runtime.h>
8

9
#include <exception>
10
#include <stdexcept>
11
#include <string>
12

13
// Shared implementation for utility objects whose layout is exactly:
14
//     typedef struct { PyObject_HEAD PyObject *runtime_obj; } XObject;
15
// Each binding kept re-rolling an identical runtime-resolution / tp_new /
16
// tp_dealloc / tp_init quartet; these templates single-source it.
17

18
// Resolve the backing Runtime: the explicitly-bound one, else the default.
19
template <typename T>
20
dftracer::utils::Runtime *resolve_runtime(T *self) {
60✔
21
    if (self->runtime_obj)
60!
22
        return ((RuntimeObject *)self->runtime_obj)->runtime.get();
×
23
    return get_default_runtime();
60✔
24
}
25

26
template <typename T>
27
PyObject *runtime_backed_new(PyTypeObject *type, PyObject *, PyObject *) {
60✔
28
    T *self = (T *)type->tp_alloc(type, 0);
60✔
29
    if (self) self->runtime_obj = NULL;
60!
30
    return (PyObject *)self;
60✔
31
}
32

33
template <typename T>
34
void runtime_backed_dealloc(T *self) {
60✔
35
    Py_XDECREF(self->runtime_obj);
60✔
36
    Py_TYPE(self)->tp_free((PyObject *)self);
60✔
37
}
60✔
38

39
// Parse an optional `runtime=` kwarg (a Runtime instance, an object exposing a
40
// `_native` Runtime, or None) and bind it into self->runtime_obj.
41
template <typename T>
42
int runtime_backed_init(T *self, PyObject *args, PyObject *kwds) {
60✔
43
    static const char *kwlist[] = {"runtime", NULL};
44
    PyObject *runtime_arg = NULL;
60✔
45
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", (char **)kwlist,
60!
46
                                     &runtime_arg)) {
47
        return -1;
×
48
    }
49
    if (runtime_arg && runtime_arg != Py_None) {
60!
50
        if (PyObject_TypeCheck(runtime_arg, &RuntimeType)) {
×
51
            Py_INCREF(runtime_arg);
×
52
            self->runtime_obj = runtime_arg;
×
53
        } else {
54
            PyObject *native = PyObject_GetAttrString(runtime_arg, "_native");
×
55
            if (native && PyObject_TypeCheck(native, &RuntimeType)) {
×
56
                self->runtime_obj = native;
×
57
            } else {
58
                Py_XDECREF(native);
×
59
                PyErr_SetString(PyExc_TypeError,
×
60
                                "runtime must be a Runtime instance or None");
61
                return -1;
×
62
            }
63
        }
64
    }
65
    return 0;
60✔
66
}
67

68
// Run a blocking C++ body with the GIL released
69
template <typename F>
70
bool run_blocking(F &&body) {
303✔
71
    bool failed = false;
303✔
72
    std::string error_msg;
303✔
73
    PyObject *exc_type = nullptr;  // pointer read only; no Python API off-GIL
303✔
74
    Py_BEGIN_ALLOW_THREADS try {
303!
75
        body();
303!
UNCOV
76
    } catch (const dftracer::utils::DFTUtilsException &e) {
×
77
        failed = true;
×
78
        error_msg = e.what();
×
79
        exc_type = py_error_type_for(e.code());
×
80
    } catch (const std::invalid_argument &e) {
×
81
        failed = true;
×
82
        error_msg = e.what();
×
83
        exc_type = g_dft_value_error;
×
84
    } catch (const std::exception &e) {
×
85
        failed = true;
×
86
        error_msg = e.what();
×
87
    } catch (...) {
×
88
        failed = true;
×
89
        error_msg = "unknown C++ exception";
×
90
    }
91
    Py_END_ALLOW_THREADS if (failed) {
303!
92
        if (exc_type == nullptr) exc_type = g_dft_error;
×
93
        PyErr_SetString(exc_type ? exc_type : PyExc_RuntimeError,
×
94
                        error_msg.c_str());
95
        return false;
×
96
    }
97
    return true;
303✔
98
}
303✔
99

100
// Like run_blocking, but for a body that produces a value. Runs `body` with
101
// the GIL released, assigning its result into `out`. On a thrown exception the
102
// exception is captured off-GIL, the GIL is re-acquired, the typed Python error
103
// is raised, and false is returned. `out` is only modified on success.
104
template <typename F, typename T>
105
bool run_blocking_r(F &&body, T &out) {
36✔
106
    std::exception_ptr eptr;
36✔
107
    Py_BEGIN_ALLOW_THREADS try { out = body(); } catch (...) {
36!
108
        eptr = std::current_exception();
×
109
    }
110
    Py_END_ALLOW_THREADS if (eptr) {
36!
111
        try {
112
            std::rethrow_exception(eptr);
×
113
        } catch (const std::exception &e) {
×
114
            set_typed_py_error(e);
×
115
        } catch (...) {
×
116
            PyErr_SetString(g_dft_error ? g_dft_error : PyExc_RuntimeError,
×
117
                            "unknown C++ exception");
118
        }
119
        return false;
×
120
    }
121
    return true;
36✔
122
}
36✔
123

124
// Generate the tp_dealloc / tp_new / tp_init shims for a utility object whose
125
// layout is `struct { PyObject_HEAD PyObject *runtime_obj; }`. PREFIX is the
126
// type's function-name prefix (e.g. Aggregator); OBJ is its object struct.
127
#define DFTRACER_UTILS_RUNTIME_BACKED_SLOTS(PREFIX, OBJ)                      \
128
    static void PREFIX##_dealloc(OBJ *self) { runtime_backed_dealloc(self); } \
129
    static PyObject *PREFIX##_new(PyTypeObject *type, PyObject *args,         \
130
                                  PyObject *kwds) {                           \
131
        return runtime_backed_new<OBJ>(type, args, kwds);                     \
132
    }                                                                         \
133
    static int PREFIX##_init(OBJ *self, PyObject *args, PyObject *kwds) {     \
134
        return runtime_backed_init(self, args, kwds);                         \
135
    }
136

137
#endif  // DFTRACER_UTILS_PYTHON_PY_RUNTIME_MIXIN_H
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