Skip to content

Commit 4d2f81b

Browse files
committed
cqe: cqe.res will auto check and raise exception. No need to
manually check with `trap_error(cqe.res)` at python side anymore.
1 parent b7f144f commit 4d2f81b

13 files changed

Lines changed: 81 additions & 65 deletions

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,10 @@ def _submit_and_wait(ring, cqe):
116116
io_uring_submit(ring) # submit entry
117117
io_uring_wait_cqe(ring, cqe) # wait for entry to finish
118118
entry = cqe[0]
119-
result = trap_error(entry.res) # auto raise appropriate exception if failed
120-
# note `entry.res` returns results, if ``< 0`` its an error, if ``>= 0`` its the value
121-
119+
try:
120+
result = entry.res # auto raises appropriate exception if failed
121+
except Exception as e:
122+
raise e # do stuff with error
122123
# done with current entry so clear it from completion queue.
123124
io_uring_cqe_seen(ring, entry)
124125
return result # type: int
@@ -130,22 +131,22 @@ def main():
130131
try:
131132
io_uring_queue_init(8, ring)
132133

133-
fd = open(ring, cqe, '/tmp/liburing-test-file.txt', O_CREAT | O_RDWR)
134-
print('fd:', fd)
134+
fd = open(ring, cqe, "/tmp/liburing-test-file.txt", O_CREAT | O_RDWR)
135+
print("fd:", fd)
135136

136-
length = write(ring, cqe, fd, b'hi... bye!')
137-
print('wrote:', length)
137+
length = write(ring, cqe, fd, b"hi... bye!")
138+
print("wrote:", length)
138139

139140
content = read(ring, cqe, fd, length)
140-
print('read:', content)
141+
print("read:", content)
141142

142143
close(ring, cqe, fd)
143-
print('closed.')
144+
print("closed.")
144145
finally:
145146
io_uring_queue_exit(ring)
146147

147148

148-
if __name__ == '__main__':
149+
if __name__ == "__main__":
149150
main()
150151

151152
```

build.zig.zon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.{
22
.name = .liburing,
3-
.version = "2026.3.25",
3+
.version = "2026.3.26",
44
.fingerprint = 0x26de882ff0030dfe,
55
.dependencies = .{
66
.PyOZ = .{

example/open_write_read_close.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1-
from liburing import O_CREAT, O_RDWR, Ring, Cqe, io_uring_get_sqe, \
2-
io_uring_prep_open, io_uring_prep_write, io_uring_prep_read, \
3-
io_uring_prep_close, io_uring_submit, io_uring_wait_cqe, \
4-
io_uring_cqe_seen, io_uring_queue_init, io_uring_queue_exit, trap_error
1+
from liburing import (
2+
O_CREAT,
3+
O_RDWR,
4+
Ring,
5+
Cqe,
6+
io_uring_get_sqe,
7+
io_uring_prep_open,
8+
io_uring_prep_write,
9+
io_uring_prep_read,
10+
io_uring_prep_close,
11+
io_uring_submit,
12+
io_uring_wait_cqe,
13+
io_uring_cqe_seen,
14+
io_uring_queue_init,
15+
io_uring_queue_exit,
16+
)
517

618

719
def open(ring, cqe, path, flags):
@@ -40,9 +52,10 @@ def _submit_and_wait(ring, cqe):
4052
io_uring_submit(ring) # submit entry
4153
io_uring_wait_cqe(ring, cqe) # wait for entry to finish
4254
entry = cqe[0]
43-
result = trap_error(entry.res) # auto raise appropriate exception if failed
44-
# note `entry.res` returns results, if ``< 0`` its an error, if ``>= 0`` its the value
45-
55+
try:
56+
result = entry.res # auto raises appropriate exception if failed
57+
except Exception as e:
58+
raise e # do stuff with error
4659
# done with current entry so clear it from completion queue.
4760
io_uring_cqe_seen(ring, entry)
4861
return result # type: int
@@ -54,20 +67,20 @@ def main():
5467
try:
5568
io_uring_queue_init(8, ring)
5669

57-
fd = open(ring, cqe, '/tmp/liburing-test-file.txt', O_CREAT | O_RDWR)
58-
print('fd:', fd)
70+
fd = open(ring, cqe, "/tmp/liburing-test-file.txt", O_CREAT | O_RDWR)
71+
print("fd:", fd)
5972

60-
length = write(ring, cqe, fd, b'hi... bye!')
61-
print('wrote:', length)
73+
length = write(ring, cqe, fd, b"hi... bye!")
74+
print("wrote:", length)
6275

6376
content = read(ring, cqe, fd, length)
64-
print('read:', content)
77+
print("read:", content)
6578

6679
close(ring, cqe, fd)
67-
print('closed.')
80+
print("closed.")
6881
finally:
6982
io_uring_queue_exit(ring)
7083

7184

72-
if __name__ == '__main__':
85+
if __name__ == "__main__":
7386
main()

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "pyoz.backend"
66
name = "liburing"
77
readme = "README.md"
88
license = "CC0-1.0"
9-
version = "2026.3.25"
9+
version = "2026.3.26"
1010
authors = [{name="Ritesh"}]
1111
keywords = ["python", "socket", "async", "cython", "file", "python3", "io", "syscall", "futex", "statx",
1212
"io-uring", "uring", "liburing"]
@@ -64,5 +64,5 @@ include-ext = ["py", "zig"]
6464

6565
# Linux platform tag for wheel builds (default: "linux_x86_64" or "linux_aarch64")
6666
# Use manylinux tags only if building in a manylinux container
67-
# linux-platform-tag = "manylinux_2_17_x86_64"
67+
linux-platform-tag = "manylinux_2_17_x86_64"
6868

src/liburing/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
from .version import * # noqa
33

44

5-
__version__ = "2026.3.25"
5+
__version__ = "2026.3.26"

src/liburing/class.zig

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Liburing - io_uring related classes
22
const c = @import("c.zig").c;
3+
const e = @import("error.zig");
34
const oz = @import("PyOZ");
45
const std = @import("std");
56
const consts = @import("const.zig");
@@ -164,8 +165,8 @@ pub const CQE = extern struct {
164165
return self._cqe.user_data;
165166
}
166167

167-
pub fn get_res(self: *const Self) i32 {
168-
return self._cqe.res;
168+
pub fn get_res(self: *const Self) ?i32 {
169+
return e.trap_error(self._cqe.res);
169170
}
170171

171172
pub fn get_flags(self: *const Self) u32 {
@@ -199,8 +200,8 @@ pub const Cqe = extern struct {
199200
// _array: ?[*]CQE = null, // custom memory for batch cqe
200201
_io_uring_cqe: ?[*]c.io_uring_cqe, // Note: Memory is managed by `io_uring`
201202

202-
// TODO:
203203
pub fn __new__(no: ?u32) ?Cqe {
204+
// TODO: `no` is need to get `io_uring_peek_batch_cqe` working
204205
if (no) |_| return oz.raiseNotImplementedError("`Cqe(no)` - Custom memory allocation not coded yet!");
205206
return .{ ._io_uring_cqe = null };
206207
}

test/file/file_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def test_readv_writev(ring, cqe, tmp_dir):
6161
liburing.io_uring_wait_cqe(ring, cqe)
6262

6363
entry = cqe[0]
64-
liburing.trap_error(entry.res)
64+
assert entry.res == 10
6565
assert entry.user_data == 0
6666
liburing.io_uring_cqe_seen(ring, entry)
6767

@@ -79,7 +79,7 @@ def test_readv_writev(ring, cqe, tmp_dir):
7979
liburing.io_uring_wait_cqe(ring, cqe)
8080

8181
entry = cqe[0]
82-
liburing.trap_error(entry.res)
82+
assert entry.res == 10
8383
assert entry.user_data == 1
8484
liburing.io_uring_cqe_seen(ring, entry)
8585

@@ -132,7 +132,7 @@ def _onwait_flag(ring, cqe, path):
132132
pass # print("test_rwf_nowait_flag BlockingIOError", flush=True)
133133
else:
134134
entry = cqe[0]
135-
liburing.trap_error(entry.res)
135+
assert entry.res == 10
136136
assert entry.res == 6 + 4
137137
assert entry.user_data == 1
138138
assert one == b"hi... "

test/file/open_close_test.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def test_open_close(ring, cqe):
1212
liburing.io_uring_submit(ring)
1313
liburing.io_uring_wait_cqe(ring, cqe) # bug: liburing.io_uring_wait_cqe
1414
entry = cqe[0]
15-
fd = liburing.trap_error(entry.res)
15+
fd = entry.res
1616
assert entry.user_data == 123
1717
liburing.io_uring_cqe_seen(ring, entry)
1818
# close
@@ -23,7 +23,7 @@ def test_open_close(ring, cqe):
2323
liburing.io_uring_submit(ring)
2424
liburing.io_uring_wait_cqe(ring, cqe)
2525
entry = cqe[0]
26-
assert liburing.trap_error(entry.res) == 0
26+
assert entry.res == 0
2727
assert entry.user_data == 321
2828

2929

@@ -37,7 +37,7 @@ def test_openat2_close(ring, cqe):
3737
liburing.io_uring_submit(ring)
3838
liburing.io_uring_wait_cqe(ring, cqe)
3939
entry = cqe[0]
40-
fd = liburing.trap_error(entry.res)
40+
fd = entry.res
4141
assert entry.user_data == 123
4242
liburing.io_uring_cqe_seen(ring, entry)
4343
# close
@@ -48,7 +48,7 @@ def test_openat2_close(ring, cqe):
4848
liburing.io_uring_submit(ring)
4949
liburing.io_uring_wait_cqe(ring, cqe)
5050
entry = cqe[0]
51-
assert liburing.trap_error(entry.res) == 0
51+
assert entry.res == 0
5252
assert entry.user_data == 321
5353

5454

@@ -66,7 +66,7 @@ def test_open_close_direct(ring, cqe):
6666
liburing.io_uring_submit(ring)
6767
liburing.io_uring_wait_cqe(ring, cqe)
6868
entry = cqe[0]
69-
assert liburing.trap_error(entry.res) == 0
69+
assert entry.res == 0
7070
assert entry.user_data == 123
7171
liburing.io_uring_cqe_seen(ring, entry)
7272
# close
@@ -77,7 +77,7 @@ def test_open_close_direct(ring, cqe):
7777
liburing.io_uring_submit(ring)
7878
liburing.io_uring_wait_cqe(ring, cqe)
7979
entry = cqe[0]
80-
assert liburing.trap_error(entry.res) == 0
80+
assert entry.res == 0
8181
assert entry.user_data == 321
8282
# unregister
8383
liburing.io_uring_unregister_files(ring)
@@ -97,8 +97,7 @@ def test_openat2_close_direct(ring, cqe, tmp_dir):
9797
liburing.io_uring_submit(ring)
9898
liburing.io_uring_wait_cqe(ring, cqe)
9999
entry = cqe[0]
100-
result = liburing.trap_error(entry.res)
101-
assert result == 0
100+
assert entry.res == 0
102101
assert entry.user_data == 123
103102
liburing.io_uring_cqe_seen(ring, entry)
104103
# close
@@ -109,7 +108,7 @@ def test_openat2_close_direct(ring, cqe, tmp_dir):
109108
liburing.io_uring_submit(ring)
110109
liburing.io_uring_wait_cqe(ring, cqe)
111110
entry = cqe[0]
112-
assert liburing.trap_error(entry.res) == 0
111+
assert entry.res == 0
113112
assert entry.user_data == 321
114113
# unregister
115114
liburing.io_uring_unregister_files(ring)
@@ -128,7 +127,7 @@ def test_openat2_close_direct_auto_file_index_alloc(ring, cqe):
128127
assert liburing.io_uring_submit(ring) == 1
129128
assert liburing.io_uring_wait_cqe(ring, cqe) == 0
130129
entry = cqe[0]
131-
find_index = liburing.trap_error(entry.res)
130+
find_index = entry.res
132131
assert entry.user_data == 123
133132
liburing.io_uring_cqe_seen(ring, entry)
134133
# close
@@ -139,7 +138,7 @@ def test_openat2_close_direct_auto_file_index_alloc(ring, cqe):
139138
assert liburing.io_uring_submit(ring) == 1
140139
assert liburing.io_uring_wait_cqe(ring, cqe) == 0
141140
entry = cqe[0]
142-
assert liburing.trap_error(entry.res) == 0
141+
assert entry.res == 0
143142
assert entry.user_data == 321
144143
liburing.io_uring_cqe_seen(ring, entry)
145144
# unregister
@@ -154,4 +153,4 @@ def test_close_error(ring, cqe):
154153
assert liburing.io_uring_wait_cqe(ring, cqe) == 0
155154
assert cqe[0].user_data == 123
156155
with pytest.raises(OSError, match="Bad file descriptor"):
157-
liburing.trap_error(cqe[0].res)
156+
cqe[0].res

test/futex_test.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ def test_multi_wake(ring, cqe):
9595
for i in range(3):
9696
assert liburing.io_uring_wait_cqe(ring, cqe) == 0
9797
entry = cqe[0]
98-
liburing.trap_error(entry.res)
98+
if not i:
99+
assert entry.res == 2
99100
liburing.io_uring_cqe_seen(ring, entry)
100101
try:
101102
liburing.io_uring_peek_cqe(ring, cqe)
@@ -165,7 +166,8 @@ def test_multi_wake_waitv(ring, cqe):
165166
for i in range(3):
166167
assert liburing.io_uring_wait_cqe(ring, cqe) == 0
167168
entry = cqe[0]
168-
liburing.trap_error(entry.res)
169+
if not i:
170+
assert entry.res == 2
169171
liburing.io_uring_cqe_seen(ring, entry)
170172
try:
171173
liburing.io_uring_peek_cqe(ring, cqe)

test/os/unlink_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def test_unlink(tmp_dir, ring, cqe):
2828

2929
for i in range(2):
3030
entry = cqe[i]
31-
assert liburing.trap_error(entry.res) == 0
31+
assert entry.res == 0
3232
assert entry.user_data == i + 1
3333
liburing.io_uring_cq_advance(ring, 2)
3434

@@ -58,7 +58,7 @@ def test_unlinkat_error(tmp_dir, ring, cqe):
5858

5959
entry = cqe[0]
6060
with pytest.raises(NotADirectoryError):
61-
assert liburing.trap_error(entry.res) == 0
61+
assert entry.res == 0
6262
assert entry.user_data == 1
6363
liburing.io_uring_cqe_seen(ring, entry)
6464

@@ -71,7 +71,7 @@ def test_unlinkat_error(tmp_dir, ring, cqe):
7171

7272
entry = cqe[0]
7373
with pytest.raises(IsADirectoryError):
74-
assert liburing.trap_error(entry.res) == 0
74+
assert entry.res == 0
7575
assert entry.user_data == 1
7676

7777
liburing.io_uring_cqe_seen(ring, entry)

0 commit comments

Comments
 (0)