Re: [PATCH v7 01/16] perf python: Add more exceptions on error paths

From: Namhyung Kim
Date: Wed Jul 23 2025 - 14:13:32 EST


On Mon, Jul 14, 2025 at 09:43:49AM -0700, Ian Rogers wrote:
> Returning NULL will cause the python interpreter to fail but not
> report an error. If none wants to be returned then Py_None needs
> returning. Set the error for the cases returning NULL so that more
> meaningful interpreter behavior is had.

It looks like you are adding error messages for the failure cases, not
adding new exceptions, right? IIUC returning NULL in pyrf_event__new()
ends up having PyErr_NoMemory(). Then now it has different messages?

>
> Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
> ---
> tools/perf/util/python.c | 14 +++++++++++---
> 1 file changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
> index 2f28f71325a8..02544387f39d 100644
> --- a/tools/perf/util/python.c
> +++ b/tools/perf/util/python.c
> @@ -475,13 +475,19 @@ static PyObject *pyrf_event__new(const union perf_event *event)
> if ((event->header.type < PERF_RECORD_MMAP ||
> event->header.type > PERF_RECORD_SAMPLE) &&
> !(event->header.type == PERF_RECORD_SWITCH ||
> - event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))
> + event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)){
> + PyErr_Format(PyExc_TypeError, "Unexpected header type %u",
> + event->header.type);
> return NULL;
> + }
>
> // FIXME this better be dynamic or we need to parse everything
> // before calling perf_mmap__consume(), including tracepoint fields.
> - if (sizeof(pevent->event) < event->header.size)
> + if (sizeof(pevent->event) < event->header.size) {
> + PyErr_Format(PyExc_TypeError, "Unexpected event version: %zd < %u",

Maybe "Unexpected event size" instead?

Thanks,
Namhyung


> + sizeof(pevent->event), event->header.size);
> return NULL;
> + }
>
> ptype = pyrf_event__type[event->header.type];
> pevent = PyObject_New(struct pyrf_event, ptype);
> @@ -1199,8 +1205,10 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
> return NULL;
>
> md = get_md(evlist, cpu);
> - if (!md)
> + if (!md) {
> + PyErr_Format(PyExc_TypeError, "Unknown CPU '%d'", cpu);
> return NULL;
> + }
>
> if (perf_mmap__read_init(&md->core) < 0)
> goto end;
> --
> 2.50.0.727.gbf7dc18ff4-goog
>