From 3ab8f5b75344fcd588d3bcd259cd83476c75abd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 11 Oct 2025 19:48:12 +0200 Subject: [PATCH 01/12] modules: silence warnings about unused params _unused_ is used for 'self' wherever the function does not use self. assert(!args) is added in the places where METH_NOARGS is used. assert(self) is added in a few places where self _is_ used. --- src/systemd/_daemon.c | 22 +++++++------ src/systemd/_journal.c | 4 +-- src/systemd/_reader.c | 73 +++++++++++++++++++++++++++++++++++++++--- src/systemd/id128.c | 30 ++++++++--------- src/systemd/login.c | 23 +++++++++++-- src/systemd/macro.h | 1 + 6 files changed, 118 insertions(+), 35 deletions(-) diff --git a/src/systemd/_daemon.c b/src/systemd/_daemon.c index 177d568..426c61c 100644 --- a/src/systemd/_daemon.c +++ b/src/systemd/_daemon.c @@ -35,8 +35,9 @@ PyDoc_STRVAR(booted__doc__, "Wraps sd_booted(3)." ); -static PyObject* booted(PyObject *self, PyObject *args) { +static PyObject* booted(PyObject *self _unused_, PyObject *args) { int r; + assert(!args); r = sd_booted(); @@ -55,7 +56,7 @@ PyDoc_STRVAR(notify__doc__, "Send a message to the init system about a status change.\n" "Wraps sd_notify(3)."); -static PyObject* notify(PyObject *self, PyObject *args, PyObject *keywds) { +static PyObject* notify(PyObject *self _unused_, PyObject *args, PyObject *keywds) { int r; const char* msg; int unset = false, n_fds; @@ -142,7 +143,7 @@ PyDoc_STRVAR(listen_fds__doc__, "Wraps sd_listen_fds(3)." ); -static PyObject* listen_fds(PyObject *self, PyObject *args, PyObject *keywds) { +static PyObject* listen_fds(PyObject *self _unused_, PyObject *args, PyObject *keywds) { int r; int unset = true; @@ -176,7 +177,8 @@ static void free_names(char **names) { free(*n); free(names); } -static PyObject* listen_fds_with_names(PyObject *self, PyObject *args, PyObject *keywds) { + +static PyObject* listen_fds_with_names(PyObject *self _unused_, PyObject *args, PyObject *keywds) { int r; int unset = false; char **names = NULL; @@ -228,7 +230,7 @@ PyDoc_STRVAR(is_fifo__doc__, ); -static PyObject* is_fifo(PyObject *self, PyObject *args) { +static PyObject* is_fifo(PyObject *self _unused_, PyObject *args) { int r; int fd; const char *path = NULL; @@ -254,7 +256,7 @@ PyDoc_STRVAR(is_mq__doc__, "Wraps sd_is_mq(3)." ); -static PyObject* is_mq(PyObject *self, PyObject *args) { +static PyObject* is_mq(PyObject *self _unused_, PyObject *args) { int r; int fd; const char *path = NULL; @@ -282,7 +284,7 @@ PyDoc_STRVAR(is_socket__doc__, "Constants for `family` are defined in the socket module." ); -static PyObject* is_socket(PyObject *self, PyObject *args) { +static PyObject* is_socket(PyObject *self _unused_, PyObject *args) { int r; int fd, family = AF_UNSPEC, type = 0, listening = -1; @@ -304,7 +306,7 @@ PyDoc_STRVAR(is_socket_inet__doc__, "Constants for `family` are defined in the socket module." ); -static PyObject* is_socket_inet(PyObject *self, PyObject *args) { +static PyObject* is_socket_inet(PyObject *self _unused_, PyObject *args) { int r; int fd, family = AF_UNSPEC, type = 0, listening = -1, port = 0; @@ -337,7 +339,7 @@ PyDoc_STRVAR(is_socket_sockaddr__doc__, #endif ); -static PyObject* is_socket_sockaddr(PyObject *self, PyObject *args) { +static PyObject* is_socket_sockaddr(PyObject *self _unused_, PyObject *args) { int r; int fd, type = 0, flowinfo = 0, listening = -1; const char *address; @@ -384,7 +386,7 @@ PyDoc_STRVAR(is_socket_unix__doc__, "Wraps sd_is_socket_unix(3)." ); -static PyObject* is_socket_unix(PyObject *self, PyObject *args) { +static PyObject* is_socket_unix(PyObject *self _unused_, PyObject *args) { int r; int fd, type = 0, listening = -1; char* path = NULL; diff --git a/src/systemd/_journal.c b/src/systemd/_journal.c index b3871ec..1a2f0ad 100644 --- a/src/systemd/_journal.c +++ b/src/systemd/_journal.c @@ -14,7 +14,7 @@ PyDoc_STRVAR(journal_sendv__doc__, "Send an entry to the journal." ); -static PyObject *journal_sendv(PyObject *self, PyObject *args) { +static PyObject* journal_sendv(PyObject *self _unused_, PyObject *args) { struct iovec *iov = NULL; int argc; int i, r; @@ -71,7 +71,7 @@ PyDoc_STRVAR(journal_stream_fd__doc__, "Open a stream to journal by calling sd_journal_stream_fd(3)." ); -static PyObject* journal_stream_fd(PyObject *self, PyObject *args) { +static PyObject* journal_stream_fd(PyObject *self _unused_, PyObject *args) { const char* identifier; int priority, level_prefix; int fd; diff --git a/src/systemd/_reader.c b/src/systemd/_reader.c index 184c288..ed83877 100644 --- a/src/systemd/_reader.c +++ b/src/systemd/_reader.c @@ -337,6 +337,9 @@ PyDoc_STRVAR(Reader_fileno__doc__, static PyObject* Reader_fileno(Reader *self, PyObject *args) { int fd; + assert(self); + assert(!args); + fd = sd_journal_get_fd(self->j); set_error(fd, NULL, NULL); if (fd < 0) @@ -352,6 +355,9 @@ PyDoc_STRVAR(Reader_reliable_fd__doc__, static PyObject* Reader_reliable_fd(Reader *self, PyObject *args) { int r; + assert(self); + assert(!args); + r = sd_journal_reliable_fd(self->j); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -366,6 +372,9 @@ PyDoc_STRVAR(Reader_get_events__doc__, static PyObject* Reader_get_events(Reader *self, PyObject *args) { int r; + assert(self); + assert(!args); + r = sd_journal_get_events(self->j); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -384,6 +393,9 @@ static PyObject* Reader_get_timeout(Reader *self, PyObject *args) { int r; uint64_t t; + assert(self); + assert(!args); + r = sd_journal_get_timeout(self->j, &t); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -404,6 +416,9 @@ static PyObject* Reader_get_timeout_ms(Reader *self, PyObject *args) { int r; uint64_t t; + assert(self); + assert(!args); + r = sd_journal_get_timeout(self->j, &t); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -438,6 +453,9 @@ static PyObject* Reader_get_usage(Reader *self, PyObject *args) { int r; uint64_t bytes; + assert(self); + assert(!args); + r = sd_journal_get_usage(self->j, &bytes); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -462,7 +480,9 @@ PyDoc_STRVAR(Reader___exit____doc__, "__exit__(type, value, traceback) -> None\n\n" "Part of the context manager protocol.\n" "Closes the journal.\n"); -static PyObject* Reader___exit__(Reader *self, PyObject *args) { +static PyObject* Reader___exit__(Reader *self, PyObject *args _unused_) { + assert(self); + return Reader_close(self, NULL); } @@ -475,6 +495,8 @@ static PyObject* Reader_next(Reader *self, PyObject *args) { int64_t skip = 1LL; int r = -EUCLEAN; + assert(self); + if (!PyArg_ParseTuple(args, "|L:next", &skip)) return NULL; @@ -590,6 +612,9 @@ static PyObject* Reader_get_all(Reader *self, PyObject *args) { size_t msg_len; int r; + assert(self); + assert(!args); + dict = PyDict_New(); if (!dict) return NULL; @@ -706,6 +731,7 @@ static PyObject* Reader_add_match(Reader *self, PyObject *args, PyObject *keywds char *match; Py_ssize_t match_len; int r; + if (!PyArg_ParseTuple(args, "s#:add_match", &match, &match_len)) return NULL; @@ -729,6 +755,10 @@ PyDoc_STRVAR(Reader_add_disjunction__doc__, "See :manpage:`sd_journal_add_disjunction(3)` for explanation."); static PyObject* Reader_add_disjunction(Reader *self, PyObject *args) { int r; + + assert(self); + assert(!args); + r = sd_journal_add_disjunction(self->j); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -743,6 +773,10 @@ PyDoc_STRVAR(Reader_add_conjunction__doc__, "See :manpage:`sd_journal_add_disjunction(3)` for explanation."); static PyObject* Reader_add_conjunction(Reader *self, PyObject *args) { int r; + + assert(self); + assert(!args); + r = sd_journal_add_conjunction(self->j); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -753,6 +787,9 @@ PyDoc_STRVAR(Reader_flush_matches__doc__, "flush_matches() -> None\n\n" "Clear all current match filters."); static PyObject* Reader_flush_matches(Reader *self, PyObject *args) { + assert(self); + assert(!args); + sd_journal_flush_matches(self->j); Py_RETURN_NONE; } @@ -764,6 +801,10 @@ PyDoc_STRVAR(Reader_seek_head__doc__, "See :manpage:`sd_journal_seek_head(3)`."); static PyObject* Reader_seek_head(Reader *self, PyObject *args) { int r; + + assert(self); + assert(!args); + Py_BEGIN_ALLOW_THREADS r = sd_journal_seek_head(self->j); Py_END_ALLOW_THREADS @@ -782,6 +823,9 @@ PyDoc_STRVAR(Reader_seek_tail__doc__, static PyObject* Reader_seek_tail(Reader *self, PyObject *args) { int r; + assert(self); + assert(!args); + Py_BEGIN_ALLOW_THREADS r = sd_journal_seek_tail(self->j); Py_END_ALLOW_THREADS @@ -799,6 +843,8 @@ static PyObject* Reader_seek_realtime(Reader *self, PyObject *args) { uint64_t timestamp; int r; + assert(self); + if (!PyArg_ParseTuple(args, "K:seek_realtime", ×tamp)) return NULL; @@ -824,6 +870,8 @@ static PyObject* Reader_seek_monotonic(Reader *self, PyObject *args) { sd_id128_t id; int r; + assert(self); + if (!PyArg_ParseTuple(args, "K|z:seek_monotonic", ×tamp, &bootid)) return NULL; @@ -1061,6 +1109,9 @@ PyDoc_STRVAR(Reader_enumerate_fields__doc__, "Return a set of field names appearing in the journal.\n" "See sd_journal_enumerate_fields(3)."); static PyObject* Reader_enumerate_fields(Reader *self, PyObject *args) { + assert(self); + assert(!args); + #if HAVE_ENUMERATE_FIELDS _cleanup_Py_DECREF_ PyObject *_value_set = NULL; PyObject *value_set; @@ -1103,6 +1154,9 @@ PyDoc_STRVAR(Reader_has_runtime_files__doc__, "Returns true if runtime journal files have been found.\n\n" "See :manpage:`sd_journal_test_cursor(3)`."); static PyObject* Reader_has_runtime_files(Reader *self, PyObject *args) { + assert(self); + assert(!args); + #if HAVE_ENUMERATE_FIELDS int r; @@ -1124,6 +1178,9 @@ PyDoc_STRVAR(Reader_has_persistent_files__doc__, "Returns true if persistent journal files have been found.\n\n" "See :manpage:`sd_journal_test_cursor(3)`."); static PyObject* Reader_has_persistent_files(Reader *self, PyObject *args) { + assert(self); + assert(!args); + #if HAVE_ENUMERATE_FIELDS int r; @@ -1185,7 +1242,7 @@ PyDoc_STRVAR(get_catalog__doc__, "get_catalog(id128) -> str\n\n" "Retrieve a message catalog entry for the given id.\n" "Wraps :manpage:`sd_journal_get_catalog_for_message_id(3)`."); -static PyObject* get_catalog(PyObject *self, PyObject *args) { +static PyObject* get_catalog(PyObject *self _unused_, PyObject *args) { int r; char *id_ = NULL; sd_id128_t id; @@ -1215,10 +1272,12 @@ PyDoc_STRVAR(data_threshold__doc__, "Fields longer than this will be truncated to the threshold size.\n" "Defaults to 64Kb."); -static PyObject* Reader_get_data_threshold(Reader *self, void *closure) { +static PyObject* Reader_get_data_threshold(Reader *self, void *closure _unused_) { size_t cvalue; int r; + assert(self); + r = sd_journal_get_data_threshold(self->j, &cvalue); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -1226,9 +1285,11 @@ static PyObject* Reader_get_data_threshold(Reader *self, void *closure) { return long_FromSize_t(cvalue); } -static int Reader_set_data_threshold(Reader *self, PyObject *value, void *closure) { +static int Reader_set_data_threshold(Reader *self, PyObject *value, void *closure _unused_) { int r; + assert(self); + if (!value) { PyErr_SetString(PyExc_AttributeError, "Cannot delete data threshold"); return -1; @@ -1245,7 +1306,9 @@ static int Reader_set_data_threshold(Reader *self, PyObject *value, void *closur PyDoc_STRVAR(closed__doc__, "True iff journal is closed"); -static PyObject* Reader_get_closed(Reader *self, void *closure) { +static PyObject* Reader_get_closed(Reader *self, void *closure _unused_) { + assert(self); + return PyBool_FromLong(!self->j); } diff --git a/src/systemd/id128.c b/src/systemd/id128.c index ca2e10e..867dfd3 100644 --- a/src/systemd/id128.c +++ b/src/systemd/id128.c @@ -69,27 +69,27 @@ static PyObject* make_uuid(sd_id128_t id) { return PyObject_Call(UUID, args, kwargs); } -#define helper(name) \ - static PyObject *name(PyObject *self, PyObject *args) { \ - sd_id128_t id; \ - int r; \ - \ - assert(!args); \ - \ - r = sd_id128_##name(&id); \ - if (r < 0) { \ - errno = -r; \ - return PyErr_SetFromErrno(PyExc_IOError); \ - } \ - \ - return make_uuid(id); \ +#define helper(name) \ + static PyObject *name(PyObject *self _unused_, PyObject *args) { \ + sd_id128_t id; \ + int r; \ + \ + assert(!args); \ + \ + r = sd_id128_##name(&id); \ + if (r < 0) { \ + errno = -r; \ + return PyErr_SetFromErrno(PyExc_IOError); \ + } \ + \ + return make_uuid(id); \ } helper(randomize) helper(get_machine) helper(get_boot) -static PyObject *get_machine_app_specific(PyObject *self, PyObject *args) { +static PyObject *get_machine_app_specific(PyObject *self _unused_, PyObject *args) { _cleanup_Py_DECREF_ PyObject *uuid_bytes = NULL; uuid_bytes = PyObject_GetAttrString(args, "bytes"); diff --git a/src/systemd/login.c b/src/systemd/login.c index d2420c3..5eaa6e3 100644 --- a/src/systemd/login.c +++ b/src/systemd/login.c @@ -15,7 +15,7 @@ PyDoc_STRVAR(module__doc__, ); #define helper(name) \ -static PyObject* name(PyObject *self, PyObject *args) { \ +static PyObject* name(PyObject *self _unused_, PyObject *args) { \ _cleanup_strv_free_ char **list = NULL; \ int r; \ PyObject *ans; \ @@ -50,7 +50,7 @@ helper(sessions) helper(machine_names) #undef helper -static PyObject* uids(PyObject *self, PyObject *args) { +static PyObject* uids(PyObject *self _unused_, PyObject *args) { _cleanup_free_ uid_t *list = NULL; int r; PyObject *ans; @@ -153,6 +153,9 @@ PyDoc_STRVAR(Monitor_fileno__doc__, "Get a file descriptor to poll for events.\n" "This method wraps sd_login_monitor_get_fd(3)."); static PyObject* Monitor_fileno(Monitor *self, PyObject *args) { + assert(self); + assert(!args); + int fd = sd_login_monitor_get_fd(self->monitor); set_error(fd, NULL, NULL); if (fd < 0) @@ -167,7 +170,12 @@ PyDoc_STRVAR(Monitor_get_events__doc__, "by .fileno().\n\n" "See :manpage:`sd_login_monitor_get_events(3)` for further discussion."); static PyObject* Monitor_get_events(Monitor *self, PyObject *args) { - int r = sd_login_monitor_get_events(self->monitor); + int r; + + assert(self); + assert(!args); + + r = sd_login_monitor_get_events(self->monitor); set_error(r, NULL, NULL); if (r < 0) return NULL; @@ -187,6 +195,9 @@ static PyObject* Monitor_get_timeout(Monitor *self, PyObject *args) { int r; uint64_t t; + assert(self); + assert(!args); + r = sd_login_monitor_get_timeout(self->monitor, &t); set_error(r, NULL, NULL); if (r < 0) @@ -209,6 +220,9 @@ static PyObject* Monitor_get_timeout_ms(Monitor *self, PyObject *args) { int r; uint64_t t; + assert(self); + assert(!args); + r = sd_login_monitor_get_timeout(self->monitor, &t); set_error(r, NULL, NULL); if (r < 0) @@ -267,6 +281,9 @@ PyDoc_STRVAR(Monitor___exit____doc__, "Part of the context manager protocol.\n" "Closes the monitor..\n"); static PyObject* Monitor___exit__(Monitor *self, PyObject *args) { + assert(self); + assert(!args); + return Monitor_close(self, args); } diff --git a/src/systemd/macro.h b/src/systemd/macro.h index d4e1796..f21eaea 100644 --- a/src/systemd/macro.h +++ b/src/systemd/macro.h @@ -25,6 +25,7 @@ (void *) memset(_new_, 0, _len_); \ }) +#define _unused_ __attribute__((__unused__)) #define _cleanup_(x) __attribute__((cleanup(x))) static inline void freep(void *p) { From 87e9eda858b72a5ef45c7662474db640da285787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 11 Oct 2025 19:49:23 +0200 Subject: [PATCH 02/12] reader: drop pointless type suffixes In C, a narrow type is automatically extended, so those verbose suffixes are not needed for anything. --- src/systemd/_reader.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/systemd/_reader.c b/src/systemd/_reader.c index ed83877..ffe2a7f 100644 --- a/src/systemd/_reader.c +++ b/src/systemd/_reader.c @@ -492,7 +492,7 @@ PyDoc_STRVAR(Reader_next__doc__, "the `skip`\\-th log entry.\n" "Returns False if at end of file, True otherwise."); static PyObject* Reader_next(Reader *self, PyObject *args) { - int64_t skip = 1LL; + int64_t skip = 1; int r = -EUCLEAN; assert(self); @@ -500,19 +500,19 @@ static PyObject* Reader_next(Reader *self, PyObject *args) { if (!PyArg_ParseTuple(args, "|L:next", &skip)) return NULL; - if (skip == 0LL) { + if (skip == 0) { PyErr_SetString(PyExc_ValueError, "skip must be nonzero"); return NULL; } Py_BEGIN_ALLOW_THREADS - if (skip == 1LL) + if (skip == 1) r = sd_journal_next(self->j); - else if (skip == -1LL) + else if (skip == -1) r = sd_journal_previous(self->j); - else if (skip > 1LL) + else if (skip > 1) r = sd_journal_next_skip(self->j, skip); - else if (skip < -1LL) + else if (skip < -1) r = sd_journal_previous_skip(self->j, -skip); else assert(!"should be here"); From 56e2adccc5a3e43e33b574a21598dd22f6e86357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 11 Oct 2025 19:57:29 +0200 Subject: [PATCH 03/12] reader: drop kwargs declaration in the _reader.Journal.add_match registration Drop specification of kwargs in the _reader.Journal.add_match registration. The handling was never implemented, so any any kwargs would be summarilly ignored. The handling of kwargs is done in the python wrapper, so no kwargs are passed to the native C function (and would be ignored if they were). IIRC, the plan was initially to do this in the C extension, but then we realized that this is very much not a hot path and doing in the the wrapper is just fine. --- src/systemd/_reader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/systemd/_reader.c b/src/systemd/_reader.c index ffe2a7f..1a6cce5 100644 --- a/src/systemd/_reader.c +++ b/src/systemd/_reader.c @@ -727,7 +727,7 @@ PyDoc_STRVAR(Reader_add_match__doc__, "fields are combined with logical AND, and matches of the same field\n" "are automatically combined with logical OR.\n" "Match is a string of the form \"FIELD=value\"."); -static PyObject* Reader_add_match(Reader *self, PyObject *args, PyObject *keywds) { +static PyObject* Reader_add_match(Reader *self, PyObject *args) { char *match; Py_ssize_t match_len; int r; @@ -1342,7 +1342,7 @@ static PyMethodDef Reader_methods[] = { {"_get_all", (PyCFunction) Reader_get_all, METH_NOARGS, Reader_get_all__doc__}, {"_get_realtime", (PyCFunction) Reader_get_realtime, METH_NOARGS, Reader_get_realtime__doc__}, {"_get_monotonic", (PyCFunction) Reader_get_monotonic, METH_NOARGS, Reader_get_monotonic__doc__}, - {"add_match", (PyCFunction) Reader_add_match, METH_VARARGS|METH_KEYWORDS, Reader_add_match__doc__}, + {"add_match", (PyCFunction) Reader_add_match, METH_VARARGS, Reader_add_match__doc__}, {"add_disjunction", (PyCFunction) Reader_add_disjunction, METH_NOARGS, Reader_add_disjunction__doc__}, {"add_conjunction", (PyCFunction) Reader_add_conjunction, METH_NOARGS, Reader_add_conjunction__doc__}, {"flush_matches", (PyCFunction) Reader_flush_matches, METH_NOARGS, Reader_flush_matches__doc__}, From 764a1311108b54d44a46d165e5a8bb17016cdc30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 11 Oct 2025 20:09:04 +0200 Subject: [PATCH 04/12] modules: indent tables Only whitespace changes. --- src/systemd/_daemon.c | 20 ++++++------ src/systemd/_journal.c | 2 +- src/systemd/_reader.c | 72 +++++++++++++++++++++--------------------- src/systemd/id128.c | 8 ++--- src/systemd/login.c | 24 +++++++------- 5 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/systemd/_daemon.c b/src/systemd/_daemon.c index 426c61c..fb9b826 100644 --- a/src/systemd/_daemon.c +++ b/src/systemd/_daemon.c @@ -411,17 +411,17 @@ static PyObject* is_socket_unix(PyObject *self _unused_, PyObject *args) { static PyMethodDef methods[] = { - { "booted", booted, METH_NOARGS, booted__doc__}, - { "notify", (PyCFunction) notify, METH_VARARGS | METH_KEYWORDS, notify__doc__}, - { "_listen_fds", (PyCFunction) listen_fds, METH_VARARGS | METH_KEYWORDS, listen_fds__doc__}, + { "booted", booted, METH_NOARGS, booted__doc__ }, + { "notify", (PyCFunction) notify, METH_VARARGS | METH_KEYWORDS, notify__doc__ }, + { "_listen_fds", (PyCFunction) listen_fds, METH_VARARGS | METH_KEYWORDS, listen_fds__doc__ }, { "_listen_fds_with_names", (PyCFunction) listen_fds_with_names, - METH_VARARGS | METH_KEYWORDS, listen_fds_with_names__doc__}, - { "_is_fifo", is_fifo, METH_VARARGS, is_fifo__doc__}, - { "_is_mq", is_mq, METH_VARARGS, is_mq__doc__}, - { "_is_socket", is_socket, METH_VARARGS, is_socket__doc__}, - { "_is_socket_inet", is_socket_inet, METH_VARARGS, is_socket_inet__doc__}, - { "_is_socket_sockaddr", is_socket_sockaddr, METH_VARARGS, is_socket_sockaddr__doc__}, - { "_is_socket_unix", is_socket_unix, METH_VARARGS, is_socket_unix__doc__}, + METH_VARARGS | METH_KEYWORDS, listen_fds_with_names__doc__ }, + { "_is_fifo", is_fifo, METH_VARARGS, is_fifo__doc__ }, + { "_is_mq", is_mq, METH_VARARGS, is_mq__doc__ }, + { "_is_socket", is_socket, METH_VARARGS, is_socket__doc__ }, + { "_is_socket_inet", is_socket_inet, METH_VARARGS, is_socket_inet__doc__ }, + { "_is_socket_sockaddr", is_socket_sockaddr, METH_VARARGS, is_socket_sockaddr__doc__ }, + { "_is_socket_unix", is_socket_unix, METH_VARARGS, is_socket_unix__doc__ }, {} /* Sentinel */ }; diff --git a/src/systemd/_journal.c b/src/systemd/_journal.c index 1a2f0ad..5fc74d5 100644 --- a/src/systemd/_journal.c +++ b/src/systemd/_journal.c @@ -90,7 +90,7 @@ static PyObject* journal_stream_fd(PyObject *self _unused_, PyObject *args) { } static PyMethodDef methods[] = { - { "sendv", journal_sendv, METH_VARARGS, journal_sendv__doc__ }, + { "sendv", journal_sendv, METH_VARARGS, journal_sendv__doc__ }, { "stream_fd", journal_stream_fd, METH_VARARGS, journal_stream_fd__doc__ }, {} /* Sentinel */ }; diff --git a/src/systemd/_reader.c b/src/systemd/_reader.c index 1a6cce5..179e21e 100644 --- a/src/systemd/_reader.c +++ b/src/systemd/_reader.c @@ -1327,41 +1327,41 @@ static PyGetSetDef Reader_getsetters[] = { }; static PyMethodDef Reader_methods[] = { - {"fileno", (PyCFunction) Reader_fileno, METH_NOARGS, Reader_fileno__doc__}, - {"reliable_fd", (PyCFunction) Reader_reliable_fd, METH_NOARGS, Reader_reliable_fd__doc__}, - {"get_events", (PyCFunction) Reader_get_events, METH_NOARGS, Reader_get_events__doc__}, - {"get_timeout", (PyCFunction) Reader_get_timeout, METH_NOARGS, Reader_get_timeout__doc__}, - {"get_timeout_ms", (PyCFunction) Reader_get_timeout_ms, METH_NOARGS, Reader_get_timeout_ms__doc__}, - {"close", (PyCFunction) Reader_close, METH_NOARGS, Reader_close__doc__}, - {"get_usage", (PyCFunction) Reader_get_usage, METH_NOARGS, Reader_get_usage__doc__}, - {"__enter__", (PyCFunction) Reader___enter__, METH_NOARGS, Reader___enter____doc__}, - {"__exit__", (PyCFunction) Reader___exit__, METH_VARARGS, Reader___exit____doc__}, - {"_next", (PyCFunction) Reader_next, METH_VARARGS, Reader_next__doc__}, - {"_previous", (PyCFunction) Reader_previous, METH_VARARGS, Reader_previous__doc__}, - {"_get", (PyCFunction) Reader_get, METH_VARARGS, Reader_get__doc__}, - {"_get_all", (PyCFunction) Reader_get_all, METH_NOARGS, Reader_get_all__doc__}, - {"_get_realtime", (PyCFunction) Reader_get_realtime, METH_NOARGS, Reader_get_realtime__doc__}, - {"_get_monotonic", (PyCFunction) Reader_get_monotonic, METH_NOARGS, Reader_get_monotonic__doc__}, - {"add_match", (PyCFunction) Reader_add_match, METH_VARARGS, Reader_add_match__doc__}, - {"add_disjunction", (PyCFunction) Reader_add_disjunction, METH_NOARGS, Reader_add_disjunction__doc__}, - {"add_conjunction", (PyCFunction) Reader_add_conjunction, METH_NOARGS, Reader_add_conjunction__doc__}, - {"flush_matches", (PyCFunction) Reader_flush_matches, METH_NOARGS, Reader_flush_matches__doc__}, - {"seek_head", (PyCFunction) Reader_seek_head, METH_NOARGS, Reader_seek_head__doc__}, - {"seek_tail", (PyCFunction) Reader_seek_tail, METH_NOARGS, Reader_seek_tail__doc__}, - {"seek_realtime", (PyCFunction) Reader_seek_realtime, METH_VARARGS, Reader_seek_realtime__doc__}, - {"seek_monotonic", (PyCFunction) Reader_seek_monotonic, METH_VARARGS, Reader_seek_monotonic__doc__}, - {"_get_start", (PyCFunction) Reader_get_start, METH_NOARGS, Reader_get_start__doc__}, - {"_get_end", (PyCFunction) Reader_get_end, METH_NOARGS, Reader_get_end__doc__}, - {"process", (PyCFunction) Reader_process, METH_NOARGS, Reader_process__doc__}, - {"wait", (PyCFunction) Reader_wait, METH_VARARGS, Reader_wait__doc__}, - {"seek_cursor", (PyCFunction) Reader_seek_cursor, METH_VARARGS, Reader_seek_cursor__doc__}, - {"_get_cursor", (PyCFunction) Reader_get_cursor, METH_NOARGS, Reader_get_cursor__doc__}, - {"test_cursor", (PyCFunction) Reader_test_cursor, METH_VARARGS, Reader_test_cursor__doc__}, - {"query_unique", (PyCFunction) Reader_query_unique, METH_VARARGS, Reader_query_unique__doc__}, - {"enumerate_fields", (PyCFunction) Reader_enumerate_fields, METH_NOARGS, Reader_enumerate_fields__doc__}, - {"has_runtime_files", (PyCFunction) Reader_has_runtime_files, METH_NOARGS, Reader_has_runtime_files__doc__}, - {"has_persistent_files", (PyCFunction) Reader_has_persistent_files, METH_NOARGS, Reader_has_persistent_files__doc__}, - {"get_catalog", (PyCFunction) Reader_get_catalog, METH_NOARGS, Reader_get_catalog__doc__}, + { "fileno", (PyCFunction) Reader_fileno, METH_NOARGS, Reader_fileno__doc__ }, + { "reliable_fd", (PyCFunction) Reader_reliable_fd, METH_NOARGS, Reader_reliable_fd__doc__ }, + { "get_events", (PyCFunction) Reader_get_events, METH_NOARGS, Reader_get_events__doc__ }, + { "get_timeout", (PyCFunction) Reader_get_timeout, METH_NOARGS, Reader_get_timeout__doc__ }, + { "get_timeout_ms", (PyCFunction) Reader_get_timeout_ms, METH_NOARGS, Reader_get_timeout_ms__doc__ }, + { "close", (PyCFunction) Reader_close, METH_NOARGS, Reader_close__doc__ }, + { "get_usage", (PyCFunction) Reader_get_usage, METH_NOARGS, Reader_get_usage__doc__ }, + { "__enter__", (PyCFunction) Reader___enter__, METH_NOARGS, Reader___enter____doc__ }, + { "__exit__", (PyCFunction) Reader___exit__, METH_VARARGS, Reader___exit____doc__ }, + { "_next", (PyCFunction) Reader_next, METH_VARARGS, Reader_next__doc__ }, + { "_previous", (PyCFunction) Reader_previous, METH_VARARGS, Reader_previous__doc__ }, + { "_get", (PyCFunction) Reader_get, METH_VARARGS, Reader_get__doc__ }, + { "_get_all", (PyCFunction) Reader_get_all, METH_NOARGS, Reader_get_all__doc__ }, + { "_get_realtime", (PyCFunction) Reader_get_realtime, METH_NOARGS, Reader_get_realtime__doc__ }, + { "_get_monotonic", (PyCFunction) Reader_get_monotonic, METH_NOARGS, Reader_get_monotonic__doc__ }, + { "add_match", (PyCFunction) Reader_add_match, METH_VARARGS, Reader_add_match__doc__ }, + { "add_disjunction", (PyCFunction) Reader_add_disjunction, METH_NOARGS, Reader_add_disjunction__doc__ }, + { "add_conjunction", (PyCFunction) Reader_add_conjunction, METH_NOARGS, Reader_add_conjunction__doc__ }, + { "flush_matches", (PyCFunction) Reader_flush_matches, METH_NOARGS, Reader_flush_matches__doc__ }, + { "seek_head", (PyCFunction) Reader_seek_head, METH_NOARGS, Reader_seek_head__doc__ }, + { "seek_tail", (PyCFunction) Reader_seek_tail, METH_NOARGS, Reader_seek_tail__doc__ }, + { "seek_realtime", (PyCFunction) Reader_seek_realtime, METH_VARARGS, Reader_seek_realtime__doc__ }, + { "seek_monotonic", (PyCFunction) Reader_seek_monotonic, METH_VARARGS, Reader_seek_monotonic__doc__ }, + { "_get_start", (PyCFunction) Reader_get_start, METH_NOARGS, Reader_get_start__doc__ }, + { "_get_end", (PyCFunction) Reader_get_end, METH_NOARGS, Reader_get_end__doc__ }, + { "process", (PyCFunction) Reader_process, METH_NOARGS, Reader_process__doc__ }, + { "wait", (PyCFunction) Reader_wait, METH_VARARGS, Reader_wait__doc__ }, + { "seek_cursor", (PyCFunction) Reader_seek_cursor, METH_VARARGS, Reader_seek_cursor__doc__ }, + { "_get_cursor", (PyCFunction) Reader_get_cursor, METH_NOARGS, Reader_get_cursor__doc__ }, + { "test_cursor", (PyCFunction) Reader_test_cursor, METH_VARARGS, Reader_test_cursor__doc__ }, + { "query_unique", (PyCFunction) Reader_query_unique, METH_VARARGS, Reader_query_unique__doc__ }, + { "enumerate_fields", (PyCFunction) Reader_enumerate_fields, METH_NOARGS, Reader_enumerate_fields__doc__ }, + { "has_runtime_files", (PyCFunction) Reader_has_runtime_files, METH_NOARGS, Reader_has_runtime_files__doc__ }, + { "has_persistent_files", (PyCFunction) Reader_has_persistent_files, METH_NOARGS, Reader_has_persistent_files__doc__ }, + { "get_catalog", (PyCFunction) Reader_get_catalog, METH_NOARGS, Reader_get_catalog__doc__ }, {} /* Sentinel */ }; @@ -1379,7 +1379,7 @@ static PyTypeObject ReaderType = { }; static PyMethodDef methods[] = { - { "_get_catalog", get_catalog, METH_VARARGS, get_catalog__doc__}, + { "_get_catalog", get_catalog, METH_VARARGS, get_catalog__doc__ }, {} /* Sentinel */ }; diff --git a/src/systemd/id128.c b/src/systemd/id128.c index 867dfd3..ca788ab 100644 --- a/src/systemd/id128.c +++ b/src/systemd/id128.c @@ -126,10 +126,10 @@ static PyObject *get_machine_app_specific(PyObject *self _unused_, PyObject *arg } static PyMethodDef methods[] = { - { "randomize", randomize, METH_NOARGS, randomize__doc__}, - { "get_machine", get_machine, METH_NOARGS, get_machine__doc__}, - { "get_machine_app_specific", get_machine_app_specific, METH_O, get_machine_app_specific__doc__}, - { "get_boot", get_boot, METH_NOARGS, get_boot__doc__}, + { "randomize", randomize, METH_NOARGS, randomize__doc__ }, + { "get_machine", get_machine, METH_NOARGS, get_machine__doc__ }, + { "get_machine_app_specific", get_machine_app_specific, METH_O, get_machine_app_specific__doc__ }, + { "get_boot", get_boot, METH_NOARGS, get_boot__doc__ }, {} /* Sentinel */ }; diff --git a/src/systemd/login.c b/src/systemd/login.c index 5eaa6e3..6252caa 100644 --- a/src/systemd/login.c +++ b/src/systemd/login.c @@ -106,10 +106,10 @@ PyDoc_STRVAR(uids__doc__, ); static PyMethodDef methods[] = { - { "seats", seats, METH_NOARGS, seats__doc__}, - { "sessions", sessions, METH_NOARGS, sessions__doc__}, - { "machine_names", machine_names, METH_NOARGS, machine_names__doc__}, - { "uids", uids, METH_NOARGS, uids__doc__}, + { "seats", seats, METH_NOARGS, seats__doc__ }, + { "sessions", sessions, METH_NOARGS, sessions__doc__ }, + { "machine_names", machine_names, METH_NOARGS, machine_names__doc__ }, + { "uids", uids, METH_NOARGS, uids__doc__ }, {} /* Sentinel */ }; @@ -289,14 +289,14 @@ static PyObject* Monitor___exit__(Monitor *self, PyObject *args) { static PyMethodDef Monitor_methods[] = { - {"fileno", (PyCFunction) Monitor_fileno, METH_NOARGS, Monitor_fileno__doc__}, - {"get_events", (PyCFunction) Monitor_get_events, METH_NOARGS, Monitor_get_events__doc__}, - {"get_timeout", (PyCFunction) Monitor_get_timeout, METH_NOARGS, Monitor_get_timeout__doc__}, - {"get_timeout_ms", (PyCFunction) Monitor_get_timeout_ms, METH_NOARGS, Monitor_get_timeout_ms__doc__}, - {"close", (PyCFunction) Monitor_close, METH_NOARGS, Monitor_close__doc__}, - {"flush", (PyCFunction) Monitor_flush, METH_NOARGS, Monitor_flush__doc__}, - {"__enter__", (PyCFunction) Monitor___enter__, METH_NOARGS, Monitor___enter____doc__}, - {"__exit__", (PyCFunction) Monitor___exit__, METH_VARARGS, Monitor___exit____doc__}, + { "fileno", (PyCFunction) Monitor_fileno, METH_NOARGS, Monitor_fileno__doc__ }, + { "get_events", (PyCFunction) Monitor_get_events, METH_NOARGS, Monitor_get_events__doc__ }, + { "get_timeout", (PyCFunction) Monitor_get_timeout, METH_NOARGS, Monitor_get_timeout__doc__ }, + { "get_timeout_ms", (PyCFunction) Monitor_get_timeout_ms, METH_NOARGS, Monitor_get_timeout_ms__doc__ }, + { "close", (PyCFunction) Monitor_close, METH_NOARGS, Monitor_close__doc__ }, + { "flush", (PyCFunction) Monitor_flush, METH_NOARGS, Monitor_flush__doc__ }, + { "__enter__", (PyCFunction) Monitor___enter__, METH_NOARGS, Monitor___enter____doc__ }, + { "__exit__", (PyCFunction) Monitor___exit__, METH_VARARGS, Monitor___exit____doc__ }, {} /* Sentinel */ }; From 35f146f2e6cbe75db18b3cbc32a738bae203f7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 11 Oct 2025 20:16:35 +0200 Subject: [PATCH 05/12] login: silence warning about missing initializer for slots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [5/10] Compiling C object src/systemd/login.cpython-313-x86_64-linux-gnu.so.p/login.c.o ../src/systemd/login.c:321:1: warning: missing initializer for field ‘m_slots’ of ‘struct PyModuleDef’ [-Wmissing-field-initializers] 321 | }; | ^ In file included from /usr/include/python3.13/Python.h:95, from ../src/systemd/login.c:6: /usr/include/python3.13/moduleobject.h:113:21: note: ‘m_slots’ declared here 113 | PyModuleDef_Slot *m_slots; | ^~~~~~~ --- src/systemd/login.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/systemd/login.c b/src/systemd/login.c index 6252caa..f946ee1 100644 --- a/src/systemd/login.c +++ b/src/systemd/login.c @@ -314,10 +314,11 @@ static PyTypeObject MonitorType = { static struct PyModuleDef module = { PyModuleDef_HEAD_INIT, - "login", /* name of module */ - module__doc__, /* module documentation, may be NULL */ - -1, /* size of per-interpreter state of the module */ - methods + .m_name = "login", /* name of module */ + .m_doc = module__doc__, /* module documentation, may be NULL */ + .m_size = -1, /* size of per-interpreter state of the module */ + .m_methods = methods, + .m_slots = NULL, }; DISABLE_WARNING_MISSING_PROTOTYPES; From 329e71a18dc99c6d20c0e96bc5a69a37eee3d34b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 11 Oct 2025 20:19:55 +0200 Subject: [PATCH 06/12] daemon: silence warning about casts for kwargs functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [6/18] Compiling C object src/systemd/_daemon.cpython-313-x86_64-linux-gnu.so.p/_daemon.c.o ../src/systemd/_daemon.c:415:37: warning: cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type] 415 | { "notify", (PyCFunction) notify, METH_VARARGS | METH_KEYWORDS, notify__doc__ }, | ^ ../src/systemd/_daemon.c:416:37: warning: cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type] 416 | { "_listen_fds", (PyCFunction) listen_fds, METH_VARARGS | METH_KEYWORDS, listen_fds__doc__ }, | ^ ../src/systemd/_daemon.c:417:37: warning: cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type] 417 | { "_listen_fds_with_names", (PyCFunction) listen_fds_with_names, | ^ This is a problem in the Python C API… They should have used a union type. --- src/systemd/_daemon.c | 2 ++ src/systemd/macro.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/systemd/_daemon.c b/src/systemd/_daemon.c index fb9b826..b552280 100644 --- a/src/systemd/_daemon.c +++ b/src/systemd/_daemon.c @@ -410,6 +410,7 @@ static PyObject* is_socket_unix(PyObject *self _unused_, PyObject *args) { } +DISABLE_WARNING_CAST_FUNCTION_TYPE; static PyMethodDef methods[] = { { "booted", booted, METH_NOARGS, booted__doc__ }, { "notify", (PyCFunction) notify, METH_VARARGS | METH_KEYWORDS, notify__doc__ }, @@ -424,6 +425,7 @@ static PyMethodDef methods[] = { { "_is_socket_unix", is_socket_unix, METH_VARARGS, is_socket_unix__doc__ }, {} /* Sentinel */ }; +REENABLE_WARNING; static struct PyModuleDef module = { PyModuleDef_HEAD_INIT, diff --git a/src/systemd/macro.h b/src/systemd/macro.h index f21eaea..0744413 100644 --- a/src/systemd/macro.h +++ b/src/systemd/macro.h @@ -6,6 +6,10 @@ _Pragma("GCC diagnostic push"); \ _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") +#define DISABLE_WARNING_CAST_FUNCTION_TYPE \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wcast-function-type\"") + #define REENABLE_WARNING \ _Pragma("GCC diagnostic pop") From 549e3cb6149e90c1bdefc35119fa35ce94e7d6a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 11 Oct 2025 21:22:55 +0200 Subject: [PATCH 07/12] reader: rename .j to .journal One-letter name is fine for a local variable, but it seems iffy to name a structure field like this. --- src/systemd/_reader.c | 100 +++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/src/systemd/_reader.c b/src/systemd/_reader.c index 179e21e..c3f1be3 100644 --- a/src/systemd/_reader.c +++ b/src/systemd/_reader.c @@ -45,7 +45,7 @@ typedef struct { PyObject_HEAD - sd_journal *j; + sd_journal *journal; } Reader; static PyTypeObject ReaderType; @@ -202,7 +202,7 @@ static int intlist_converter(PyObject* obj, int **_result, size_t *_len) { } static void Reader_dealloc(Reader* self) { - sd_journal_close(self->j); + sd_journal_close(self->journal); Py_TYPE(self)->tp_free((PyObject*)self); } @@ -254,7 +254,7 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) { #if HAVE_JOURNAL_OPEN_DIRECTORY_FD Py_BEGIN_ALLOW_THREADS - r = sd_journal_open_directory_fd(&self->j, (int) fd, flags); + r = sd_journal_open_directory_fd(&self->journal, (int) fd, flags); Py_END_ALLOW_THREADS #else r = -ENOSYS; @@ -268,7 +268,7 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) { return -1; Py_BEGIN_ALLOW_THREADS - r = sd_journal_open_directory(&self->j, path, flags); + r = sd_journal_open_directory(&self->journal, path, flags); Py_END_ALLOW_THREADS } } else if (_files) { @@ -283,7 +283,7 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) { #if HAVE_JOURNAL_OPEN_FILES Py_BEGIN_ALLOW_THREADS - r = sd_journal_open_files(&self->j, (const char**) files, flags); + r = sd_journal_open_files(&self->journal, (const char**) files, flags); Py_END_ALLOW_THREADS #else r = -ENOSYS; @@ -297,7 +297,7 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) { #if HAVE_JOURNAL_OPEN_DIRECTORY_FD Py_BEGIN_ALLOW_THREADS - r = sd_journal_open_files_fd(&self->j, fds, n_fds, flags); + r = sd_journal_open_files_fd(&self->journal, fds, n_fds, flags); Py_END_ALLOW_THREADS #else r = -ENOSYS; @@ -312,14 +312,14 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) { return -1; Py_BEGIN_ALLOW_THREADS - r = sd_journal_open_namespace(&self->j, namespace, flags); + r = sd_journal_open_namespace(&self->journal, namespace, flags); Py_END_ALLOW_THREADS #else r = -ENOSYS; #endif } else { Py_BEGIN_ALLOW_THREADS - r = sd_journal_open(&self->j, flags); + r = sd_journal_open(&self->journal, flags); Py_END_ALLOW_THREADS } @@ -340,7 +340,7 @@ static PyObject* Reader_fileno(Reader *self, PyObject *args) { assert(self); assert(!args); - fd = sd_journal_get_fd(self->j); + fd = sd_journal_get_fd(self->journal); set_error(fd, NULL, NULL); if (fd < 0) return NULL; @@ -358,7 +358,7 @@ static PyObject* Reader_reliable_fd(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_reliable_fd(self->j); + r = sd_journal_reliable_fd(self->journal); if (set_error(r, NULL, NULL) < 0) return NULL; return PyBool_FromLong(r); @@ -375,7 +375,7 @@ static PyObject* Reader_get_events(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_get_events(self->j); + r = sd_journal_get_events(self->journal); if (set_error(r, NULL, NULL) < 0) return NULL; return long_FromLong(r); @@ -396,7 +396,7 @@ static PyObject* Reader_get_timeout(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_get_timeout(self->j, &t); + r = sd_journal_get_timeout(self->journal, &t); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -419,7 +419,7 @@ static PyObject* Reader_get_timeout_ms(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_get_timeout(self->j, &t); + r = sd_journal_get_timeout(self->journal, &t); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -435,8 +435,8 @@ static PyObject* Reader_close(Reader *self, PyObject *args) { assert(self); assert(!args); - sd_journal_close(self->j); - self->j = NULL; + sd_journal_close(self->journal); + self->journal = NULL; Py_RETURN_NONE; } @@ -456,7 +456,7 @@ static PyObject* Reader_get_usage(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_get_usage(self->j, &bytes); + r = sd_journal_get_usage(self->journal, &bytes); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -507,13 +507,13 @@ static PyObject* Reader_next(Reader *self, PyObject *args) { Py_BEGIN_ALLOW_THREADS if (skip == 1) - r = sd_journal_next(self->j); + r = sd_journal_next(self->journal); else if (skip == -1) - r = sd_journal_previous(self->j); + r = sd_journal_previous(self->journal); else if (skip > 1) - r = sd_journal_next_skip(self->j, skip); + r = sd_journal_next_skip(self->journal, skip); else if (skip < -1) - r = sd_journal_previous_skip(self->j, -skip); + r = sd_journal_previous_skip(self->journal, -skip); else assert(!"should be here"); Py_END_ALLOW_THREADS @@ -589,7 +589,7 @@ static PyObject* Reader_get(Reader *self, PyObject *args) { if (!PyArg_ParseTuple(args, "s:get", &field)) return NULL; - r = sd_journal_get_data(self->j, field, &msg, &msg_len); + r = sd_journal_get_data(self->journal, field, &msg, &msg_len); if (r == -ENOENT) { PyErr_SetString(PyExc_KeyError, field); return NULL; @@ -619,7 +619,7 @@ static PyObject* Reader_get_all(Reader *self, PyObject *args) { if (!dict) return NULL; - SD_JOURNAL_FOREACH_DATA(self->j, msg, msg_len) { + SD_JOURNAL_FOREACH_DATA(self->journal, msg, msg_len) { _cleanup_Py_DECREF_ PyObject *key = NULL, *value = NULL; r = extract(msg, msg_len, &key, &value); @@ -677,7 +677,7 @@ static PyObject* Reader_get_realtime(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_get_realtime_usec(self->j, ×tamp); + r = sd_journal_get_realtime_usec(self->journal, ×tamp); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -700,7 +700,7 @@ static PyObject* Reader_get_monotonic(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_get_monotonic_usec(self->j, ×tamp, &id); + r = sd_journal_get_monotonic_usec(self->journal, ×tamp, &id); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -740,7 +740,7 @@ static PyObject* Reader_add_match(Reader *self, PyObject *args) { return NULL; } - r = sd_journal_add_match(self->j, match, (int) match_len); + r = sd_journal_add_match(self->journal, match, (int) match_len); if (set_error(r, NULL, "Invalid match") < 0) return NULL; @@ -759,7 +759,7 @@ static PyObject* Reader_add_disjunction(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_add_disjunction(self->j); + r = sd_journal_add_disjunction(self->journal); if (set_error(r, NULL, NULL) < 0) return NULL; Py_RETURN_NONE; @@ -777,7 +777,7 @@ static PyObject* Reader_add_conjunction(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_add_conjunction(self->j); + r = sd_journal_add_conjunction(self->journal); if (set_error(r, NULL, NULL) < 0) return NULL; Py_RETURN_NONE; @@ -790,7 +790,7 @@ static PyObject* Reader_flush_matches(Reader *self, PyObject *args) { assert(self); assert(!args); - sd_journal_flush_matches(self->j); + sd_journal_flush_matches(self->journal); Py_RETURN_NONE; } @@ -806,7 +806,7 @@ static PyObject* Reader_seek_head(Reader *self, PyObject *args) { assert(!args); Py_BEGIN_ALLOW_THREADS - r = sd_journal_seek_head(self->j); + r = sd_journal_seek_head(self->journal); Py_END_ALLOW_THREADS if (set_error(r, NULL, NULL) < 0) @@ -827,7 +827,7 @@ static PyObject* Reader_seek_tail(Reader *self, PyObject *args) { assert(!args); Py_BEGIN_ALLOW_THREADS - r = sd_journal_seek_tail(self->j); + r = sd_journal_seek_tail(self->journal); Py_END_ALLOW_THREADS if (set_error(r, NULL, NULL) < 0) @@ -849,7 +849,7 @@ static PyObject* Reader_seek_realtime(Reader *self, PyObject *args) { return NULL; Py_BEGIN_ALLOW_THREADS - r = sd_journal_seek_realtime_usec(self->j, timestamp); + r = sd_journal_seek_realtime_usec(self->journal, timestamp); Py_END_ALLOW_THREADS if (set_error(r, NULL, NULL) < 0) @@ -889,7 +889,7 @@ static PyObject* Reader_seek_monotonic(Reader *self, PyObject *args) { } Py_BEGIN_ALLOW_THREADS - r = sd_journal_seek_monotonic_usec(self->j, id, timestamp); + r = sd_journal_seek_monotonic_usec(self->journal, id, timestamp); Py_END_ALLOW_THREADS if (set_error(r, NULL, NULL) < 0) @@ -911,7 +911,7 @@ static PyObject* Reader_get_start(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_get_cutoff_realtime_usec(self->j, &start, NULL); + r = sd_journal_get_cutoff_realtime_usec(self->journal, &start, NULL); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -932,7 +932,7 @@ static PyObject* Reader_get_end(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_get_cutoff_realtime_usec(self->j, NULL, &end); + r = sd_journal_get_cutoff_realtime_usec(self->journal, NULL, &end); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -955,7 +955,7 @@ static PyObject* Reader_process(Reader *self, PyObject *args) { assert(!args); Py_BEGIN_ALLOW_THREADS - r = sd_journal_process(self->j); + r = sd_journal_process(self->journal); Py_END_ALLOW_THREADS if (set_error(r, NULL, NULL) < 0) return NULL; @@ -981,7 +981,7 @@ static PyObject* Reader_wait(Reader *self, PyObject *args) { return NULL; Py_BEGIN_ALLOW_THREADS - r = sd_journal_wait(self->j, timeout); + r = sd_journal_wait(self->journal, timeout); Py_END_ALLOW_THREADS if (set_error(r, NULL, NULL) < 0) @@ -1001,7 +1001,7 @@ static PyObject* Reader_seek_cursor(Reader *self, PyObject *args) { return NULL; Py_BEGIN_ALLOW_THREADS - r = sd_journal_seek_cursor(self->j, cursor); + r = sd_journal_seek_cursor(self->journal, cursor); Py_END_ALLOW_THREADS if (set_error(r, NULL, "Invalid cursor") < 0) @@ -1021,7 +1021,7 @@ static PyObject* Reader_get_cursor(Reader *self, PyObject *args) { assert(self); assert(!args); - r = sd_journal_get_cursor(self->j, &cursor); + r = sd_journal_get_cursor(self->journal, &cursor); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -1042,7 +1042,7 @@ static PyObject* Reader_test_cursor(Reader *self, PyObject *args) { if (!PyArg_ParseTuple(args, "s:test_cursor", &cursor)) return NULL; - r = sd_journal_test_cursor(self->j, cursor); + r = sd_journal_test_cursor(self->journal, cursor); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -1066,7 +1066,7 @@ static PyObject* Reader_query_unique(Reader *self, PyObject *args) { return NULL; Py_BEGIN_ALLOW_THREADS - r = sd_journal_query_unique(self->j, query); + r = sd_journal_query_unique(self->journal, query); Py_END_ALLOW_THREADS if (set_error(r, NULL, "Invalid field name") < 0) @@ -1080,7 +1080,7 @@ static PyObject* Reader_query_unique(Reader *self, PyObject *args) { if (!key) return NULL; - SD_JOURNAL_FOREACH_UNIQUE(self->j, uniq, uniq_len) { + SD_JOURNAL_FOREACH_UNIQUE(self->journal, uniq, uniq_len) { const char *delim_ptr; _cleanup_Py_DECREF_ PyObject *value = NULL; @@ -1121,13 +1121,13 @@ static PyObject* Reader_enumerate_fields(Reader *self, PyObject *args) { if (!value_set) return NULL; - sd_journal_restart_fields(self->j); + sd_journal_restart_fields(self->journal); while (true) { const char *field; _cleanup_Py_DECREF_ PyObject *value = NULL; - r = sd_journal_enumerate_fields(self->j, &field); + r = sd_journal_enumerate_fields(self->journal, &field); if (r == 0) break; if (set_error(r, NULL, "Field enumeration failed") < 0) @@ -1162,7 +1162,7 @@ static PyObject* Reader_has_runtime_files(Reader *self, PyObject *args) { assert(self); - r = sd_journal_has_runtime_files(self->j); + r = sd_journal_has_runtime_files(self->journal); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -1186,7 +1186,7 @@ static PyObject* Reader_has_persistent_files(Reader *self, PyObject *args) { assert(self); - r = sd_journal_has_persistent_files(self->j); + r = sd_journal_has_persistent_files(self->journal); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -1212,14 +1212,14 @@ static PyObject* Reader_get_catalog(Reader *self, PyObject *args) { assert(!args); Py_BEGIN_ALLOW_THREADS - r = sd_journal_get_catalog(self->j, &msg); + r = sd_journal_get_catalog(self->journal, &msg); Py_END_ALLOW_THREADS if (r == -ENOENT) { const void* mid; size_t mid_len; - r = sd_journal_get_data(self->j, "MESSAGE_ID", &mid, &mid_len); + r = sd_journal_get_data(self->journal, "MESSAGE_ID", &mid, &mid_len); if (r == 0) { const size_t l = sizeof("MESSAGE_ID"); assert(mid_len > l); @@ -1278,7 +1278,7 @@ static PyObject* Reader_get_data_threshold(Reader *self, void *closure _unused_) assert(self); - r = sd_journal_get_data_threshold(self->j, &cvalue); + r = sd_journal_get_data_threshold(self->journal, &cvalue); if (set_error(r, NULL, NULL) < 0) return NULL; @@ -1300,7 +1300,7 @@ static int Reader_set_data_threshold(Reader *self, PyObject *value, void *closur return -1; } - r = sd_journal_set_data_threshold(self->j, (size_t) long_AsLong(value)); + r = sd_journal_set_data_threshold(self->journal, (size_t) long_AsLong(value)); return set_error(r, NULL, NULL); } @@ -1309,7 +1309,7 @@ PyDoc_STRVAR(closed__doc__, static PyObject* Reader_get_closed(Reader *self, void *closure _unused_) { assert(self); - return PyBool_FromLong(!self->j); + return PyBool_FromLong(!self->journal); } static PyGetSetDef Reader_getsetters[] = { From f54b50c82e1c69e89af9a99f8e9519a6a36b9214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 11 Oct 2025 21:28:51 +0200 Subject: [PATCH 08/12] modules: modernize variable declarations --- src/systemd/_journal.c | 15 ++++++--------- src/systemd/_reader.c | 15 ++++++--------- src/systemd/login.c | 11 ++++------- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/systemd/_journal.c b/src/systemd/_journal.c index 5fc74d5..7ff23ee 100644 --- a/src/systemd/_journal.c +++ b/src/systemd/_journal.c @@ -15,21 +15,18 @@ PyDoc_STRVAR(journal_sendv__doc__, ); static PyObject* journal_sendv(PyObject *self _unused_, PyObject *args) { - struct iovec *iov = NULL; - int argc; - int i, r; PyObject *ret = NULL; - PyObject **encoded; + int r; /* Allocate an array for the argument strings */ - argc = PyTuple_Size(args); - encoded = alloca0(argc * sizeof(PyObject*)); + int argc = PyTuple_Size(args); + PyObject **encoded = alloca0(argc * sizeof(PyObject*)); /* Allocate sufficient iovector space for the arguments. */ - iov = alloca(argc * sizeof(struct iovec)); + struct iovec *iov = alloca(argc * sizeof(struct iovec)); /* Iterate through the Python arguments and fill the iovector. */ - for (i = 0; i < argc; ++i) { + for (int i = 0; i < argc; ++i) { PyObject *item = PyTuple_GetItem(args, i); char *stritem; Py_ssize_t length; @@ -60,7 +57,7 @@ static PyObject* journal_sendv(PyObject *self _unused_, PyObject *args) { ret = Py_None; out: - for (i = 0; i < argc; ++i) + for (int i = 0; i < argc; i++) Py_XDECREF(encoded[i]); return ret; diff --git a/src/systemd/_reader.c b/src/systemd/_reader.c index c3f1be3..76607f0 100644 --- a/src/systemd/_reader.c +++ b/src/systemd/_reader.c @@ -108,21 +108,20 @@ static int null_converter(PyObject* obj, void *_result) { */ static int strv_converter(PyObject* obj, void *_result) { char ***result = _result; - Py_ssize_t i, len; assert(result); if (!PySequence_Check(obj)) return 0; - len = PySequence_Length(obj); + Py_ssize_t len = PySequence_Length(obj); *result = new0(char*, len + 1); if (!*result) { set_error(-ENOMEM, NULL, NULL); return 0; } - for (i = 0; i < len; i++) { + for (Py_ssize_t i = 0; i < len; i++) { PyObject *item; _cleanup_Py_DECREF_ PyObject *bytes = NULL; char *s; @@ -168,23 +167,21 @@ static int long_as_fd(PyObject *obj, int *fd) { * Convert a Python sequence object into an int array. */ static int intlist_converter(PyObject* obj, int **_result, size_t *_len) { - _cleanup_free_ int *result = NULL; - Py_ssize_t i, len; - assert(_result); assert(_len); if (!PySequence_Check(obj)) return 0; - len = PySequence_Length(obj); - result = new0(int, len); + Py_ssize_t len = PySequence_Length(obj); + _cleanup_free_ int *result = new0(int, len); + if (!result) { set_error(-ENOMEM, NULL, NULL); return 0; } - for (i = 0; i < len; i++) { + for (Py_ssize_t i = 0; i < len; i++) { PyObject *item; int fd; diff --git a/src/systemd/login.c b/src/systemd/login.c index f946ee1..b09f3ba 100644 --- a/src/systemd/login.c +++ b/src/systemd/login.c @@ -18,7 +18,6 @@ PyDoc_STRVAR(module__doc__, static PyObject* name(PyObject *self _unused_, PyObject *args) { \ _cleanup_strv_free_ char **list = NULL; \ int r; \ - PyObject *ans; \ \ assert(!args); \ \ @@ -28,7 +27,7 @@ static PyObject* name(PyObject *self _unused_, PyObject *args) { \ return PyErr_SetFromErrno(PyExc_IOError); \ } \ \ - ans = PyList_New(r); \ + PyObject *ans = PyList_New(r); \ if (!ans) \ return NULL; \ \ @@ -53,7 +52,6 @@ helper(machine_names) static PyObject* uids(PyObject *self _unused_, PyObject *args) { _cleanup_free_ uid_t *list = NULL; int r; - PyObject *ans; assert(!args); @@ -63,7 +61,7 @@ static PyObject* uids(PyObject *self _unused_, PyObject *args) { return PyErr_SetFromErrno(PyExc_IOError); } - ans = PyList_New(r); + PyObject *ans = PyList_New(r); if (!ans) return NULL; @@ -121,7 +119,7 @@ typedef struct { static PyTypeObject MonitorType; static void Monitor_dealloc(Monitor* self) { - sd_login_monitor_unref(self->monitor); + self->monitor = sd_login_monitor_unref(self->monitor); Py_TYPE(self)->tp_free((PyObject*)self); } @@ -241,8 +239,7 @@ static PyObject* Monitor_close(Monitor *self, PyObject *args) { assert(self); assert(!args); - sd_login_monitor_unref(self->monitor); - self->monitor = NULL; + self->monitor = sd_login_monitor_unref(self->monitor); Py_RETURN_NONE; } From 92db8b9cd40869ee87f2eae4b77299235f109c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 11 Oct 2025 21:41:25 +0200 Subject: [PATCH 09/12] modules: drop references to IOError Since Python 3.0 it is an alias for OSError. --- src/systemd/_journal.c | 4 ++-- src/systemd/id128.c | 4 ++-- src/systemd/login.c | 4 ++-- src/systemd/test/test_id128.py | 2 +- src/systemd/test/test_journal.py | 2 +- src/systemd/test/test_login.py | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/systemd/_journal.c b/src/systemd/_journal.c index 7ff23ee..72d7f48 100644 --- a/src/systemd/_journal.c +++ b/src/systemd/_journal.c @@ -48,7 +48,7 @@ static PyObject* journal_sendv(PyObject *self _unused_, PyObject *args) { r = sd_journal_sendv(iov, argc); if (r < 0) { errno = -r; - PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_OSError); goto out; } @@ -80,7 +80,7 @@ static PyObject* journal_stream_fd(PyObject *self _unused_, PyObject *args) { fd = sd_journal_stream_fd(identifier, priority, level_prefix); if (fd < 0) { errno = -fd; - return PyErr_SetFromErrno(PyExc_IOError); + return PyErr_SetFromErrno(PyExc_OSError); } return PyLong_FromLong(fd); diff --git a/src/systemd/id128.c b/src/systemd/id128.c index ca788ab..51a76be 100644 --- a/src/systemd/id128.c +++ b/src/systemd/id128.c @@ -79,7 +79,7 @@ static PyObject* make_uuid(sd_id128_t id) { r = sd_id128_##name(&id); \ if (r < 0) { \ errno = -r; \ - return PyErr_SetFromErrno(PyExc_IOError); \ + return PyErr_SetFromErrno(PyExc_OSError); \ } \ \ return make_uuid(id); \ @@ -114,7 +114,7 @@ static PyObject *get_machine_app_specific(PyObject *self _unused_, PyObject *arg PyBuffer_Release(&buffer); if (r < 0) { errno = -r; - return PyErr_SetFromErrno(PyExc_IOError); + return PyErr_SetFromErrno(PyExc_OSError); } return make_uuid(app_id); diff --git a/src/systemd/login.c b/src/systemd/login.c index b09f3ba..5d59028 100644 --- a/src/systemd/login.c +++ b/src/systemd/login.c @@ -24,7 +24,7 @@ static PyObject* name(PyObject *self _unused_, PyObject *args) { \ r = sd_get_##name(&list); \ if (r < 0) { \ errno = -r; \ - return PyErr_SetFromErrno(PyExc_IOError); \ + return PyErr_SetFromErrno(PyExc_OSError); \ } \ \ PyObject *ans = PyList_New(r); \ @@ -58,7 +58,7 @@ static PyObject* uids(PyObject *self _unused_, PyObject *args) { r = sd_get_uids(&list); if (r < 0) { errno = -r; - return PyErr_SetFromErrno(PyExc_IOError); + return PyErr_SetFromErrno(PyExc_OSError); } PyObject *ans = PyList_New(r); diff --git a/src/systemd/test/test_id128.py b/src/systemd/test/test_id128.py index 24da776..ffab469 100644 --- a/src/systemd/test/test_id128.py +++ b/src/systemd/test/test_id128.py @@ -11,7 +11,7 @@ def skip_oserror(*errnos): try: yield - except (OSError, IOError) as e: + except OSError as e: if e.errno in errnos: pytest.skip() raise diff --git a/src/systemd/test/test_journal.py b/src/systemd/test/test_journal.py index 8b47990..709fb0b 100644 --- a/src/systemd/test/test_journal.py +++ b/src/systemd/test/test_journal.py @@ -47,7 +47,7 @@ def send(self, MESSAGE, MESSAGE_ID=None, def skip_oserror(code): try: yield - except (OSError, IOError) as e: + except OSError as e: if e.errno == code: pytest.skip() raise diff --git a/src/systemd/test/test_login.py b/src/systemd/test/test_login.py index 1e92a25..5e51b02 100644 --- a/src/systemd/test/test_login.py +++ b/src/systemd/test/test_login.py @@ -12,7 +12,7 @@ def skip_oserror(code): try: yield - except (OSError, IOError) as e: + except OSError as e: if e.errno == code: pytest.skip() raise From 6e9b86eb1d97a6aee499d2bcf96f70234e6f3780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 12 Oct 2025 12:52:58 +0200 Subject: [PATCH 10/12] modules: get rid of python2-era compat ifdefs They were a 1:1 mapping anyway. --- src/systemd/_daemon.c | 6 +++--- src/systemd/_reader.c | 28 ++++++++++++++-------------- src/systemd/login.c | 8 ++++---- src/systemd/pyutil.h | 7 ------- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/systemd/_daemon.c b/src/systemd/_daemon.c index b552280..d5214e8 100644 --- a/src/systemd/_daemon.c +++ b/src/systemd/_daemon.c @@ -156,7 +156,7 @@ static PyObject* listen_fds(PyObject *self _unused_, PyObject *args, PyObject *k if (set_error(r, NULL, NULL) < 0) return NULL; - return long_FromLong(r); + return PyLong_FromLong(r); } PyDoc_STRVAR(listen_fds_with_names__doc__, @@ -198,7 +198,7 @@ static PyObject* listen_fds_with_names(PyObject *self _unused_, PyObject *args, if (tpl == NULL) return NULL; - item = long_FromLong(r); + item = PyLong_FromLong(r); if (item == NULL) { Py_DECREF(tpl); return NULL; @@ -208,7 +208,7 @@ static PyObject* listen_fds_with_names(PyObject *self _unused_, PyObject *args, return NULL; } for (int i = 0; i < r && names[i] != NULL; i++) { - item = unicode_FromString(names[i]); + item = PyUnicode_FromString(names[i]); if (PyTuple_SetItem(tpl, 1+i, item) < 0) { Py_DECREF(tpl); free_names(names); diff --git a/src/systemd/_reader.c b/src/systemd/_reader.c index 76607f0..61c1972 100644 --- a/src/systemd/_reader.c +++ b/src/systemd/_reader.c @@ -150,7 +150,7 @@ static int strv_converter(PyObject* obj, void *_result) { } static int long_as_fd(PyObject *obj, int *fd) { - long num = long_AsLong(obj); + long num = PyLong_AsLong(obj); if (PyErr_Occurred()) return -1; @@ -243,7 +243,7 @@ static int Reader_init(Reader *self, PyObject *args, PyObject *keywds) { } if (_path) { - if (long_Check(_path)) { + if (PyLong_Check(_path)) { int fd; if (long_as_fd(_path, &fd) < 0) @@ -341,7 +341,7 @@ static PyObject* Reader_fileno(Reader *self, PyObject *args) { set_error(fd, NULL, NULL); if (fd < 0) return NULL; - return long_FromLong(fd); + return PyLong_FromLong(fd); } PyDoc_STRVAR(Reader_reliable_fd__doc__, @@ -375,7 +375,7 @@ static PyObject* Reader_get_events(Reader *self, PyObject *args) { r = sd_journal_get_events(self->journal); if (set_error(r, NULL, NULL) < 0) return NULL; - return long_FromLong(r); + return PyLong_FromLong(r); } PyDoc_STRVAR(Reader_get_timeout__doc__, @@ -547,7 +547,7 @@ static int extract(const char* msg, size_t msg_len, } if (key) { - k = unicode_FromStringAndSize(msg, delim_ptr - (const char*) msg); + k = PyUnicode_FromStringAndSize(msg, delim_ptr - (const char*) msg); if (!k) return -1; } @@ -957,7 +957,7 @@ static PyObject* Reader_process(Reader *self, PyObject *args) { if (set_error(r, NULL, NULL) < 0) return NULL; - return long_FromLong(r); + return PyLong_FromLong(r); } PyDoc_STRVAR(Reader_wait__doc__, @@ -984,7 +984,7 @@ static PyObject* Reader_wait(Reader *self, PyObject *args) { if (set_error(r, NULL, NULL) < 0) return NULL; - return long_FromLong(r); + return PyLong_FromLong(r); } PyDoc_STRVAR(Reader_seek_cursor__doc__, @@ -1022,7 +1022,7 @@ static PyObject* Reader_get_cursor(Reader *self, PyObject *args) { if (set_error(r, NULL, NULL) < 0) return NULL; - return unicode_FromString(cursor); + return PyUnicode_FromString(cursor); } PyDoc_STRVAR(Reader_test_cursor__doc__, @@ -1073,7 +1073,7 @@ static PyObject* Reader_query_unique(Reader *self, PyObject *args) { if (!value_set) return NULL; - key = unicode_FromString(query); + key = PyUnicode_FromString(query); if (!key) return NULL; @@ -1232,7 +1232,7 @@ static PyObject* Reader_get_catalog(Reader *self, PyObject *args) { if (set_error(r, NULL, NULL) < 0) return NULL; - return unicode_FromString(msg); + return PyUnicode_FromString(msg); } PyDoc_STRVAR(get_catalog__doc__, @@ -1261,7 +1261,7 @@ static PyObject* get_catalog(PyObject *self _unused_, PyObject *args) { if (set_error(r, NULL, NULL) < 0) return NULL; - return unicode_FromString(msg); + return PyUnicode_FromString(msg); } PyDoc_STRVAR(data_threshold__doc__, @@ -1279,7 +1279,7 @@ static PyObject* Reader_get_data_threshold(Reader *self, void *closure _unused_) if (set_error(r, NULL, NULL) < 0) return NULL; - return long_FromSize_t(cvalue); + return PyLong_FromSize_t(cvalue); } static int Reader_set_data_threshold(Reader *self, PyObject *value, void *closure _unused_) { @@ -1292,12 +1292,12 @@ static int Reader_set_data_threshold(Reader *self, PyObject *value, void *closur return -1; } - if (!long_Check(value)){ + if (!PyLong_Check(value)){ PyErr_SetString(PyExc_TypeError, "Data threshold must be an int"); return -1; } - r = sd_journal_set_data_threshold(self->journal, (size_t) long_AsLong(value)); + r = sd_journal_set_data_threshold(self->journal, (size_t) PyLong_AsLong(value)); return set_error(r, NULL, NULL); } diff --git a/src/systemd/login.c b/src/systemd/login.c index 5d59028..d4e6ade 100644 --- a/src/systemd/login.c +++ b/src/systemd/login.c @@ -32,7 +32,7 @@ static PyObject* name(PyObject *self _unused_, PyObject *args) { \ return NULL; \ \ for (r--; r >= 0; r--) { \ - PyObject *s = unicode_FromString(list[r]); \ + PyObject *s = PyUnicode_FromString(list[r]); \ if (!s) { \ Py_DECREF(ans); \ return NULL; \ @@ -66,7 +66,7 @@ static PyObject* uids(PyObject *self _unused_, PyObject *args) { return NULL; for (r--; r >= 0; r--) { - PyObject *s = long_FromLong(list[r]); + PyObject *s = PyLong_FromLong(list[r]); if (!s) { Py_DECREF(ans); return NULL; @@ -158,7 +158,7 @@ static PyObject* Monitor_fileno(Monitor *self, PyObject *args) { set_error(fd, NULL, NULL); if (fd < 0) return NULL; - return long_FromLong(fd); + return PyLong_FromLong(fd); } @@ -177,7 +177,7 @@ static PyObject* Monitor_get_events(Monitor *self, PyObject *args) { set_error(r, NULL, NULL); if (r < 0) return NULL; - return long_FromLong(r); + return PyLong_FromLong(r); } diff --git a/src/systemd/pyutil.h b/src/systemd/pyutil.h index 66bbdf9..01fdf84 100644 --- a/src/systemd/pyutil.h +++ b/src/systemd/pyutil.h @@ -14,10 +14,3 @@ int set_error(int r, const char* path, const char* invalid_message); int Unicode_FSConverter(PyObject* obj, void *_result); #define _cleanup_Py_DECREF_ _cleanup_(cleanup_Py_DECREFp) - -# define unicode_FromStringAndSize PyUnicode_FromStringAndSize -# define unicode_FromString PyUnicode_FromString -# define long_FromLong PyLong_FromLong -# define long_FromSize_t PyLong_FromSize_t -# define long_Check PyLong_Check -# define long_AsLong PyLong_AsLong From 5906f045a404206050e67884e0a0ac97ca0e4462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 12 Oct 2025 13:09:52 +0200 Subject: [PATCH 11/12] meson: add global defines using add_project_arguments() We're not going to be compiling any other C code, so let's simplify this. --- meson.build | 5 +++-- src/systemd/meson.build | 5 ----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/meson.build b/meson.build index 590f929..3c8c71b 100644 --- a/meson.build +++ b/meson.build @@ -15,9 +15,10 @@ python_dep = python.dependency() libsystemd_dep = dependency('libsystemd') -common_c_args = [ +add_project_arguments( '-DPACKAGE_VERSION="@0@"'.format(meson.project_version()), '-DLIBSYSTEMD_VERSION=@0@'.format(libsystemd_dep.version()), -] + language : 'c', +) subdir('src/systemd') diff --git a/src/systemd/meson.build b/src/systemd/meson.build index 6a10428..d8da0b7 100644 --- a/src/systemd/meson.build +++ b/src/systemd/meson.build @@ -5,7 +5,6 @@ python.extension_module( '_journal', ['_journal.c', 'pyutil.c'], dependencies: [libsystemd_dep], - c_args: common_c_args, install: true, subdir: 'systemd', ) @@ -15,7 +14,6 @@ python.extension_module( '_reader', ['_reader.c', 'pyutil.c', 'strv.c'], dependencies: [libsystemd_dep], - c_args: common_c_args, install: true, subdir: 'systemd', ) @@ -25,7 +23,6 @@ python.extension_module( '_daemon', ['_daemon.c', 'pyutil.c', 'util.c'], dependencies: [libsystemd_dep], - c_args: common_c_args, install: true, subdir: 'systemd', ) @@ -35,7 +32,6 @@ python.extension_module( 'id128', ['id128.c', 'pyutil.c'], dependencies: [libsystemd_dep], - c_args: common_c_args, install: true, subdir: 'systemd', ) @@ -45,7 +41,6 @@ python.extension_module( 'login', ['login.c', 'pyutil.c', 'strv.c'], dependencies: [libsystemd_dep], - c_args: common_c_args, install: true, subdir: 'systemd', ) From 163a99aa2582770a5000950850d7b87ed7d91a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 12 Oct 2025 13:11:54 +0200 Subject: [PATCH 12/12] modules: include Python.h from one place only, clean up includes systemd headers should be included using <>. And use a single include of Python.h and define PY_SSIZE_T_CLEAN before it, so that we're using a consistent API everywhere. --- meson.build | 1 + src/systemd/_journal.c | 3 +-- src/systemd/_reader.c | 19 +++++++------------ src/systemd/id128.c | 4 +--- src/systemd/login.c | 7 +------ src/systemd/macro.h | 2 ++ src/systemd/pyutil.c | 1 - src/systemd/pyutil.h | 6 ++---- 8 files changed, 15 insertions(+), 28 deletions(-) diff --git a/meson.build b/meson.build index 3c8c71b..80e3564 100644 --- a/meson.build +++ b/meson.build @@ -16,6 +16,7 @@ python_dep = python.dependency() libsystemd_dep = dependency('libsystemd') add_project_arguments( + '-D_GNU_SOURCE=1', '-DPACKAGE_VERSION="@0@"'.format(meson.project_version()), '-DLIBSYSTEMD_VERSION=@0@'.format(libsystemd_dep.version()), language : 'c', diff --git a/src/systemd/_journal.c b/src/systemd/_journal.c index 72d7f48..185cd79 100644 --- a/src/systemd/_journal.c +++ b/src/systemd/_journal.c @@ -1,13 +1,12 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include - #include #define SD_JOURNAL_SUPPRESS_LOCATION #include "systemd/sd-journal.h" #include "macro.h" +#include "pyutil.h" PyDoc_STRVAR(journal_sendv__doc__, "sendv('FIELD=value', 'FIELD=value', ...) -> None\n\n" diff --git a/src/systemd/_reader.c b/src/systemd/_reader.c index 61c1972..f3db0a1 100644 --- a/src/systemd/_reader.c +++ b/src/systemd/_reader.c @@ -1,23 +1,18 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#define PY_SSIZE_T_CLEAN -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wredundant-decls" -#include -#pragma GCC diagnostic pop - -#include -#include -#include -#include #include - -#include "systemd/sd-journal.h" +#include +#include +#include +#include #include "pyutil.h" #include "macro.h" #include "strv.h" +/* This needs to be below Python.h include for some reason */ +#include + #if defined(LIBSYSTEMD_VERSION) || LIBSYSTEMD_JOURNAL_VERSION > 204 # define HAVE_JOURNAL_OPEN_FILES 1 #else diff --git a/src/systemd/id128.c b/src/systemd/id128.c index 51a76be..8d128f6 100644 --- a/src/systemd/id128.c +++ b/src/systemd/id128.c @@ -1,7 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include - /* Our include is first, so that our defines are replaced by the ones * from the system header. If the system header has the same definitions * (or does not have them at all), this replacement is silent. If the @@ -12,8 +10,8 @@ #include "id128-defines.h" #include -#include "pyutil.h" #include "macro.h" +#include "pyutil.h" #define HAVE_SD_ID128_GET_MACHINE_APP_SPECIFIC (LIBSYSTEMD_VERSION >= 240) diff --git a/src/systemd/login.c b/src/systemd/login.c index d4e6ade..4bc2aab 100644 --- a/src/systemd/login.c +++ b/src/systemd/login.c @@ -1,12 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#define PY_SSIZE_T_CLEAN -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wredundant-decls" -#include -#pragma GCC diagnostic pop +#include -#include "systemd/sd-login.h" #include "pyutil.h" #include "strv.h" diff --git a/src/systemd/macro.h b/src/systemd/macro.h index 0744413..d6e3197 100644 --- a/src/systemd/macro.h +++ b/src/systemd/macro.h @@ -2,6 +2,8 @@ #pragma once +#include + #define DISABLE_WARNING_MISSING_PROTOTYPES \ _Pragma("GCC diagnostic push"); \ _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") diff --git a/src/systemd/pyutil.c b/src/systemd/pyutil.c index 7b9ed6d..df2f2e9 100644 --- a/src/systemd/pyutil.c +++ b/src/systemd/pyutil.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include #include "pyutil.h" void cleanup_Py_DECREFp(PyObject **p) { diff --git a/src/systemd/pyutil.h b/src/systemd/pyutil.h index 01fdf84..72e44ff 100644 --- a/src/systemd/pyutil.h +++ b/src/systemd/pyutil.h @@ -2,10 +2,8 @@ #pragma once -#ifndef Py_TYPE -/* avoid duplication warnings from errors in Python 2.7 headers */ -# include -#endif +#define PY_SSIZE_T_CLEAN +#include void cleanup_Py_DECREFp(PyObject **p); PyObject* absolute_timeout(uint64_t t);