Source: caio
Version: 0.12.3-1
Severity: serious
Tags: ftbfs
Justification: fails to build from source (but built successfully in the past)
X-Debbugs-Cc: [email protected], [email protected],
[email protected], [email protected],
[email protected]
User: [email protected]
Usertags: s390x
User: [email protected]
Usertags: loong64
User: [email protected]
Usertags: ppc64el
User: [email protected]
Usertags: armhf
User: [email protected]
Usertags: i386
Dear maintainer,
caio FTBFS on armhf, i386, loong64, ppc64el and s390x with various test
failures:
=================================== FAILURES ===================================
______ test_write_operation_properties_before_submission[caio.thread_aio] ______
backend = <module 'caio.thread_aio' from
'/build/reproducible-path/caio-0.12.3/.pybuild/cpython3_3.14_caio/build/caio/thread_aio.cpython-314-i386-linux-gnu.so'>
def test_write_operation_properties_before_submission(backend):
""".fileno/.offset/.nbytes/.payload for a freshly constructed write
Operation must reflect the constructor arguments identically across
every backend, even before it's ever submitted - unlike read (see
below), nothing here depends on backend-specific buffer allocation
strategy."""
with tempfile.NamedTemporaryFile() as f:
fd = f.fileno()
payload = b"the quick brown fox"
op = backend.Operation.write(payload, fd, 7)
assert op.fileno == fd
assert op.offset == 7
> assert op.nbytes == len(payload)
E assert 17744664942566440979 == 19
E + where 17744664942566440979 = <aio.AIOOperation at 0xf614b3a8:
mode="write", fd=12, offset=7, result=0, buffer=0xf641b6c0>.nbytes
E + and 19 = len(b'the quick brown fox')
tests/test_aio_context.py:48: AssertionError
________ test_read_operation_nbytes_before_submission[caio.thread_aio] _________
backend = <module 'caio.thread_aio' from
'/build/reproducible-path/caio-0.12.3/.pybuild/cpython3_3.14_caio/build/caio/thread_aio.cpython-314-i386-linux-gnu.so'>
def test_read_operation_nbytes_before_submission(backend):
"""Only .nbytes is guaranteed consistent for an unsubmitted read across
backends - .payload's pre-submission content is an implementation
detail (some backends pre-allocate a same-size buffer, python_aio
starts with an empty BytesIO instead), so it's deliberately not
asserted here."""
with tempfile.NamedTemporaryFile() as f:
fd = f.fileno()
op = backend.Operation.read(16, fd, 3)
assert op.fileno == fd
assert op.offset == 3
> assert op.nbytes == 16
E assert 17741478008113332240 == 16
E + where 17741478008113332240 = <aio.AIOOperation at 0xf617bc28:
mode="read", fd=12, offset=3, result=0, buffer=0xf6366440>.nbytes
tests/test_aio_context.py:64: AssertionError
________ test_read_with_absurd_nbytes_raises_cleanly[caio.linux_uring] _________
backend = <module 'caio.linux_uring' from
'/build/reproducible-path/caio-0.12.3/.pybuild/cpython3_3.14_caio/build/caio/linux_uring.cpython-314-i386-linux-gnu.so'>
def test_read_with_absurd_nbytes_raises_cleanly(backend):
"""Operation.read() with an unreasonably large nbytes must raise a
catchable exception, never crash the process. A naive allocation
strategy for a size this large doesn't just panic (which PyO3 would
convert to a catchable PanicException) - it can *abort the whole
process* (SIGABRT) via Rust's global alloc-error handler, which is not
recoverable from Python at all. Runs in a subprocess since a real
abort would otherwise take the whole test session down with it.
python_aio doesn't preallocate a buffer at construction time (nbytes is
just stored, the real buffer is sized lazily from whatever the actual
read returns), so it was never at risk here and is skipped.
"""
if backend.__name__ == "caio.python_aio":
pytest.skip("python_aio doesn't preallocate at construction time")
if not backend.__name__.startswith("caio."):
pytest.skip("synthetic test-only variant, not importable by name in
a subprocess")
code = (
f"import {backend.__name__} as m\n"
f"try:\n"
f" m.Operation.read({ABSURD_NBYTES}, 0, 0)\n"
f" print('RESULT: unexpectedly-succeeded')\n"
f"except (OverflowError, MemoryError, ValueError) as e:\n"
f" print(f'RESULT: raised {{type(e).__name__}}')\n"
)
proc = subprocess.run(
[sys.executable, "-c", code],
capture_output=True, text=True, timeout=30, check=False,
)
assert proc.returncode == 0, (
f"process aborted/crashed (returncode={proc.returncode}); "
f"stdout={proc.stdout!r} stderr={proc.stderr!r}"
)
> assert "RESULT: raised" in proc.stdout, (
f"expected a catchable exception; stdout={proc.stdout!r}
stderr={proc.stderr!r}"
)
E AssertionError: expected a catchable exception; stdout='RESULT:
unexpectedly-succeeded\n' stderr=''
E assert 'RESULT: raised' in 'RESULT: unexpectedly-succeeded\n'
E + where 'RESULT: unexpectedly-succeeded\n' =
CompletedProcess(args=['/usr/bin/python3.14', '-c', "import caio.linux_uring as
m\ntry:\n m.Operation.read(46116860... print(f'RESULT: raised
{type(e).__name__}')\n"], returncode=0, stdout='RESULT:
unexpectedly-succeeded\n', stderr='').stdout
tests/test_raw_low_level.py:294: AssertionError
_________ test_read_with_absurd_nbytes_raises_cleanly[caio.linux_aio] __________
backend = <module 'caio.linux_aio' from
'/build/reproducible-path/caio-0.12.3/.pybuild/cpython3_3.14_caio/build/caio/linux_aio.cpython-314-i386-linux-gnu.so'>
def test_read_with_absurd_nbytes_raises_cleanly(backend):
"""Operation.read() with an unreasonably large nbytes must raise a
catchable exception, never crash the process. A naive allocation
strategy for a size this large doesn't just panic (which PyO3 would
convert to a catchable PanicException) - it can *abort the whole
process* (SIGABRT) via Rust's global alloc-error handler, which is not
recoverable from Python at all. Runs in a subprocess since a real
abort would otherwise take the whole test session down with it.
python_aio doesn't preallocate a buffer at construction time (nbytes is
just stored, the real buffer is sized lazily from whatever the actual
read returns), so it was never at risk here and is skipped.
"""
if backend.__name__ == "caio.python_aio":
pytest.skip("python_aio doesn't preallocate at construction time")
if not backend.__name__.startswith("caio."):
pytest.skip("synthetic test-only variant, not importable by name in
a subprocess")
code = (
f"import {backend.__name__} as m\n"
f"try:\n"
f" m.Operation.read({ABSURD_NBYTES}, 0, 0)\n"
f" print('RESULT: unexpectedly-succeeded')\n"
f"except (OverflowError, MemoryError, ValueError) as e:\n"
f" print(f'RESULT: raised {{type(e).__name__}}')\n"
)
proc = subprocess.run(
[sys.executable, "-c", code],
capture_output=True, text=True, timeout=30, check=False,
)
assert proc.returncode == 0, (
f"process aborted/crashed (returncode={proc.returncode}); "
f"stdout={proc.stdout!r} stderr={proc.stderr!r}"
)
> assert "RESULT: raised" in proc.stdout, (
f"expected a catchable exception; stdout={proc.stdout!r}
stderr={proc.stderr!r}"
)
E AssertionError: expected a catchable exception; stdout='RESULT:
unexpectedly-succeeded\n' stderr=''
E assert 'RESULT: raised' in 'RESULT: unexpectedly-succeeded\n'
E + where 'RESULT: unexpectedly-succeeded\n' =
CompletedProcess(args=['/usr/bin/python3.14', '-c', "import caio.linux_aio as
m\ntry:\n m.Operation.read(4611686018... print(f'RESULT: raised
{type(e).__name__}')\n"], returncode=0, stdout='RESULT:
unexpectedly-succeeded\n', stderr='').stdout
tests/test_raw_low_level.py:294: AssertionError
_________ test_read_with_absurd_nbytes_raises_cleanly[caio.thread_aio] _________
backend = <module 'caio.thread_aio' from
'/build/reproducible-path/caio-0.12.3/.pybuild/cpython3_3.14_caio/build/caio/thread_aio.cpython-314-i386-linux-gnu.so'>
def test_read_with_absurd_nbytes_raises_cleanly(backend):
"""Operation.read() with an unreasonably large nbytes must raise a
catchable exception, never crash the process. A naive allocation
strategy for a size this large doesn't just panic (which PyO3 would
convert to a catchable PanicException) - it can *abort the whole
process* (SIGABRT) via Rust's global alloc-error handler, which is not
recoverable from Python at all. Runs in a subprocess since a real
abort would otherwise take the whole test session down with it.
python_aio doesn't preallocate a buffer at construction time (nbytes is
just stored, the real buffer is sized lazily from whatever the actual
read returns), so it was never at risk here and is skipped.
"""
if backend.__name__ == "caio.python_aio":
pytest.skip("python_aio doesn't preallocate at construction time")
if not backend.__name__.startswith("caio."):
pytest.skip("synthetic test-only variant, not importable by name in
a subprocess")
code = (
f"import {backend.__name__} as m\n"
f"try:\n"
f" m.Operation.read({ABSURD_NBYTES}, 0, 0)\n"
f" print('RESULT: unexpectedly-succeeded')\n"
f"except (OverflowError, MemoryError, ValueError) as e:\n"
f" print(f'RESULT: raised {{type(e).__name__}}')\n"
)
proc = subprocess.run(
[sys.executable, "-c", code],
capture_output=True, text=True, timeout=30, check=False,
)
assert proc.returncode == 0, (
f"process aborted/crashed (returncode={proc.returncode}); "
f"stdout={proc.stdout!r} stderr={proc.stderr!r}"
)
> assert "RESULT: raised" in proc.stdout, (
f"expected a catchable exception; stdout={proc.stdout!r}
stderr={proc.stderr!r}"
)
E AssertionError: expected a catchable exception; stdout='RESULT:
unexpectedly-succeeded\n' stderr=''
E assert 'RESULT: raised' in 'RESULT: unexpectedly-succeeded\n'
E + where 'RESULT: unexpectedly-succeeded\n' =
CompletedProcess(args=['/usr/bin/python3.14', '-c', "import caio.thread_aio as
m\ntry:\n m.Operation.read(461168601... print(f'RESULT: raised
{type(e).__name__}')\n"], returncode=0, stdout='RESULT:
unexpectedly-succeeded\n', stderr='').stdout
tests/test_raw_low_level.py:294: AssertionError
=============================== warnings summary ===============================
tests/test_asyncio_adapter.py:35: 13 warnings
/build/reproducible-path/caio-0.12.3/.pybuild/cpython3_3.14_caio/build/tests/test_asyncio_adapter.py:35:
DeprecationWarning: 'asyncio.iscoroutinefunction' is deprecated and slated for
removal in Python 3.16; use inspect.iscoroutinefunction() instead
if not asyncio.iscoroutinefunction(func):
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED
tests/test_aio_context.py::test_write_operation_properties_before_submission[caio.thread_aio]
FAILED
tests/test_aio_context.py::test_read_operation_nbytes_before_submission[caio.thread_aio]
FAILED
tests/test_raw_low_level.py::test_read_with_absurd_nbytes_raises_cleanly[caio.linux_uring]
FAILED
tests/test_raw_low_level.py::test_read_with_absurd_nbytes_raises_cleanly[caio.linux_aio]
FAILED
tests/test_raw_low_level.py::test_read_with_absurd_nbytes_raises_cleanly[caio.thread_aio]
==== 5 failed, 230 passed, 511 skipped, 4 deselected, 13 warnings in 14.09s ====
For example, see
https://buildd.debian.org/status/fetch.php?pkg=caio&arch=i386&ver=0.12.3-1&stamp=1787892157&raw=0.
--
Sebastian Ramacher