Source: python-trio
Version: 0.25.0-1
Severity: normal
User: [email protected]
Usertags: python3.13
Forwarded: https://github.com/python-trio/trio/issues/3004

This package failed build from source when test-built against a version of
python3-defaults that includes 3.13 as a supported version.

To reproduce this issue, build against python3-defaults (python3-all-dev etc.)
from Debian experimental.

What's new in Python 3.13:
https://docs.python.org/3.13/whatsnew/3.13.html

Log snippet:

   dh_auto_test -O--buildsystem=pybuild
I: pybuild base:311: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_trio/build; 
python3.13 -m pytest -m "not redistributors_should_skip" -p 
trio._tests.pytest_plugin -k "not test_SocketType_resolve and not 
test_getprotobyname" --skip-optional-imports
============================= test session starts ==============================
platform linux -- Python 3.13.0rc2, pytest-8.3.3, pluggy-1.5.0
rootdir: /<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_trio/build
configfile: pyproject.toml
plugins: typeguard-4.3.0
collected 776 items / 45 deselected / 1 skipped / 731 selected

trio/_core/_tests/test_asyncgen.py .......                               [  0%]
trio/_core/_tests/test_exceptiongroup_gc.py ..                           [  1%]
trio/_core/_tests/test_guest_mode.py ..............                      [  3%]
trio/_core/_tests/test_instrumentation.py ........                       [  4%]
trio/_core/_tests/test_io.py ............................                [  8%]
trio/_core/_tests/test_ki.py .F.....F...                                 [  9%]
trio/_core/_tests/test_local.py ....                                     [ 10%]
trio/_core/_tests/test_mock_clock.py .....s                              [ 10%]
trio/_core/_tests/test_parking_lot.py ....                               [ 11%]
trio/_core/_tests/test_run.py ................................s......... [ 17%]
........................................................................ [ 27%]
.................................                                        [ 31%]
trio/_core/_tests/test_thread_cache.py ..ss..                            [ 32%]
trio/_core/_tests/test_tutil.py .                                        [ 32%]
trio/_core/_tests/test_unbounded_queue.py .....                          [ 33%]
trio/_core/_tests/test_windows.py sssssss                                [ 34%]
trio/_tests/test_abc.py ...                                              [ 34%]
trio/_tests/test_channel.py .............                                [ 36%]
trio/_tests/test_contextvars.py ...                                      [ 36%]
trio/_tests/test_deprecate.py ...........                                [ 38%]
trio/_tests/test_deprecate_strict_exception_groups_false.py ...          [ 38%]
trio/_tests/test_dtls.py ..s.............s.............                  [ 42%]
trio/_tests/test_exports.py ...                                          [ 43%]
trio/_tests/test_fakenet.py ....s....                                    [ 44%]
trio/_tests/test_file_io.py .................                            [ 46%]
trio/_tests/test_highlevel_generic.py ..                                 [ 47%]
trio/_tests/test_highlevel_open_tcp_listeners.py ....................    [ 49%]
trio/_tests/test_highlevel_open_tcp_stream.py .......................    [ 52%]
trio/_tests/test_highlevel_open_unix_stream.py .....s                    [ 53%]
trio/_tests/test_highlevel_serve_listeners.py ....                       [ 54%]
trio/_tests/test_highlevel_socket.py .......                             [ 55%]
trio/_tests/test_highlevel_ssl_helpers.py ...                            [ 55%]
trio/_tests/test_path.py .s................F................             [ 60%]
trio/_tests/test_scheduler_determinism.py ..                             [ 60%]
trio/_tests/test_signals.py ........                                     [ 61%]
trio/_tests/test_socket.py .......s.......................               [ 66%]
trio/_tests/test_ssl.py ......s.............................s........... [ 72%]
...............                                                          [ 74%]
trio/_tests/test_subprocess.py ....................s........             [ 78%]
trio/_tests/test_sync.py ..................................              [ 83%]
trio/_tests/test_testing.py ...................                          [ 85%]
trio/_tests/test_testing_raisesgroup.py ..........                       [ 87%]
trio/_tests/test_threads.py F.F......................................... [ 93%]
.s....                                                                   [ 94%]
trio/_tests/test_timeouts.py sss.                                        [ 94%]
trio/_tests/test_tracing.py ..                                           [ 94%]
trio/_tests/test_unix_pipes.py ...........                               [ 96%]
trio/_tests/test_util.py .........                                       [ 97%]
trio/_tests/test_wait_for_object.py ssss                                 [ 98%]
trio/_tests/test_windows_pipes.py ssssss                                 [ 99%]
trio/_tests/tools/test_mypy_annotate.py .......                          [100%]

=================================== FAILURES ===================================
_______________________________ test_ki_enabled ________________________________

    async def test_ki_enabled() -> None:
        # Regular tasks aren't KI-protected
        assert not _core.currently_ki_protected()
    
        # Low-level call-soon callbacks are KI-protected
        token = _core.current_trio_token()
        record = []
    
        def check() -> None:
            record.append(_core.currently_ki_protected())
    
        token.run_sync_soon(check)
        await wait_all_tasks_blocked()
        assert record == [True]
    
        @_core.enable_ki_protection
        def protected() -> None:
            assert _core.currently_ki_protected()
            unprotected()
    
        @_core.disable_ki_protection
        def unprotected() -> None:
            assert not _core.currently_ki_protected()
    
>       protected()

trio/_core/_tests/test_ki.py:62: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
trio/_core/_ki.py:181: in wrapper
    return fn(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    @_core.enable_ki_protection
    def protected() -> None:
>       assert _core.currently_ki_protected()
E       assert False
E        +  where False = <function currently_ki_protected at 0xffff83496700>()
E        +    where <function currently_ki_protected at 0xffff83496700> = 
_core.currently_ki_protected

trio/_core/_tests/test_ki.py:55: AssertionError
___________________________ test_ki_disabled_in_del ____________________________

    def test_ki_disabled_in_del() -> None:
        def nestedfunction() -> bool:
            return _core.currently_ki_protected()
    
        def __del__() -> None:
            assert _core.currently_ki_protected()
            assert nestedfunction()
    
        @_core.disable_ki_protection
        def outerfunction() -> None:
            assert not _core.currently_ki_protected()
            assert not nestedfunction()
            __del__()
    
        __del__()
>       outerfunction()

trio/_core/_tests/test_ki.py:255: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
trio/_core/_ki.py:181: in wrapper
    return fn(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    @_core.disable_ki_protection
    def outerfunction() -> None:
>       assert not _core.currently_ki_protected()
E       assert not True
E        +  where True = <function currently_ki_protected at 0xffff83496700>()
E        +    where <function currently_ki_protected at 0xffff83496700> = 
_core.currently_ki_protected

trio/_core/_tests/test_ki.py:250: AssertionError
_________________________ test_async_method_signature __________________________

path = 
trio.Path('/tmp/pytest-of-debusine-worker/pytest-0/test_async_method_signature0/test')

    async def test_async_method_signature(path: trio.Path) -> None:
        # use `resolve` as a representative of wrapped methods
    
        assert path.resolve.__name__ == "resolve"
        assert path.resolve.__qualname__ == "Path.resolve"
    
        assert path.resolve.__doc__ is not None
>       assert "pathlib.Path.resolve" in path.resolve.__doc__
E       AssertionError: assert 'pathlib.Path.resolve' in 'Like 
:meth:`~pathlib._local.Path.resolve`, but async.\n\nMake the path absolute, 
resolving all symlinks on the way and also\nnormalizing it.\n'
E        +  where 'Like :meth:`~pathlib._local.Path.resolve`, but 
async.\n\nMake the path absolute, resolving all symlinks on the way and 
also\nnormalizing it.\n' = resolve.__doc__
E        +    where resolve = 
trio.Path('/tmp/pytest-of-debusine-worker/pytest-0/test_async_method_signature0/test').resolve

trio/_tests/test_path.py:125: AssertionError
____________________________ test_do_in_trio_thread ____________________________

    async def test_do_in_trio_thread() -> None:
        trio_thread = threading.current_thread()
    
        async def check_case(
            do_in_trio_thread: Callable[..., threading.Thread],
            fn: Callable[..., T | Awaitable[T]],
            expected: tuple[str, T],
            trio_token: _core.TrioToken | None = None,
        ) -> None:
            record: RecordType = []
    
            def threadfn() -> None:
                try:
                    record.append(("start", threading.current_thread()))
                    x = do_in_trio_thread(fn, record, trio_token=trio_token)
                    record.append(("got", x))
                except BaseException as exc:
                    print(exc)
                    record.append(("error", type(exc)))
    
            child_thread = threading.Thread(target=threadfn, daemon=True)
            child_thread.start()
            while child_thread.is_alive():
                print("yawn")
                await sleep(0.01)
            assert record == [("start", child_thread), ("f", trio_thread), 
expected]
    
        token = _core.current_trio_token()
    
        def f1(record: RecordType) -> int:
            assert not _core.currently_ki_protected()
            record.append(("f", threading.current_thread()))
            return 2
    
>       await check_case(from_thread_run_sync, f1, ("got", 2), trio_token=token)

trio/_tests/test_threads.py:94: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

do_in_trio_thread = <function run_sync at 0xffff8314d620>
fn = <function test_do_in_trio_thread.<locals>.f1 at 0xffff82018220>
expected = ('got', 2)
trio_token = TrioToken(_reentry_queue=EntryQueue(queue=deque([]), 
idempotent_queue={}, wakeup=<trio._core._wakeup_socketpair.WakeupSocketpair 
object at 0xffff8213ed50>, done=True, lock=<unlocked _thread.RLock object 
owner=0 count=0 at 0xffff82517740>))

    async def check_case(
        do_in_trio_thread: Callable[..., threading.Thread],
        fn: Callable[..., T | Awaitable[T]],
        expected: tuple[str, T],
        trio_token: _core.TrioToken | None = None,
    ) -> None:
        record: RecordType = []
    
        def threadfn() -> None:
            try:
                record.append(("start", threading.current_thread()))
                x = do_in_trio_thread(fn, record, trio_token=trio_token)
                record.append(("got", x))
            except BaseException as exc:
                print(exc)
                record.append(("error", type(exc)))
    
        child_thread = threading.Thread(target=threadfn, daemon=True)
        child_thread.start()
        while child_thread.is_alive():
            print("yawn")
            await sleep(0.01)
>       assert record == [("start", child_thread), ("f", trio_thread), expected]
E       AssertionError: assert [('start', <T...rtionError'>)] == [('start', 
<T...), ('got', 2)]
E         
E         At index 1 diff: ('error', <class 'AssertionError'>) != ('f', 
<_MainThread(MainThread, started 281472901461824)>)
E         Right contains one more item: ('got', 2)
E         Use -v to get more diff

trio/_tests/test_threads.py:85: AssertionError
----------------------------- Captured stdout call -----------------------------
yawn
assert not True
 +  where True = <function currently_ki_protected at 0xffff83496700>()
 +    where <function currently_ki_protected at 0xffff83496700> = 
_core.currently_ki_protected
__________________________ test_run_in_trio_thread_ki __________________________

    def test_run_in_trio_thread_ki() -> None:
        # if we get a control-C during a run_in_trio_thread, then it propagates
        # back to the caller (slick!)
        record = set()
    
        async def check_run_in_trio_thread() -> None:
            token = _core.current_trio_token()
    
            def trio_thread_fn() -> None:
                print("in Trio thread")
                assert not _core.currently_ki_protected()
                print("ki_self")
                try:
                    ki_self()
                finally:
                    import sys
    
                    print("finally", sys.exc_info())
    
            async def trio_thread_afn() -> None:
                trio_thread_fn()
    
            def external_thread_fn() -> None:
                try:
                    print("running")
                    from_thread_run_sync(trio_thread_fn, trio_token=token)
                except KeyboardInterrupt:
                    print("ok1")
                    record.add("ok1")
                try:
                    from_thread_run(trio_thread_afn, trio_token=token)
                except KeyboardInterrupt:
                    print("ok2")
                    record.add("ok2")
    
            thread = threading.Thread(target=external_thread_fn)
            thread.start()
            print("waiting")
            while thread.is_alive():
                await sleep(0.01)
            print("waited, joining")
            thread.join()
            print("done")
    
        _core.run(check_run_in_trio_thread)
>       assert record == {"ok1", "ok2"}
E       AssertionError: assert set() == {'ok1', 'ok2'}
E         
E         Extra items in the right set:
E         'ok2'
E         'ok1'
E         Use -v to get more diff

trio/_tests/test_threads.py:176: AssertionError

During handling of the above exception, another exception occurred:

cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0xffff81f854e0>
when = 'call'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    @classmethod
    def from_call(
        cls,
        func: Callable[[], TResult],
        when: Literal["collect", "setup", "call", "teardown"],
        reraise: type[BaseException] | tuple[type[BaseException], ...] | None = 
None,
    ) -> CallInfo[TResult]:
        """Call func, wrapping the result in a CallInfo.
    
        :param func:
            The function to call. Called without arguments.
        :type func: Callable[[], _pytest.runner.TResult]
        :param when:
            The phase in which the function is called.
        :param reraise:
            Exception or exceptions that shall propagate if raised by the
            function, instead of being wrapped in the CallInfo.
        """
        excinfo = None
        start = timing.time()
        precise_start = timing.perf_counter()
        try:
>           result: TResult | None = func()

/usr/lib/python3/dist-packages/_pytest/runner.py:341: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3/dist-packages/_pytest/runner.py:242: in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/usr/lib/python3/dist-packages/pluggy/_hooks.py:513: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, 
firstresult)
/usr/lib/python3/dist-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/usr/lib/python3/dist-packages/_pytest/threadexception.py:92: in 
pytest_runtest_call
    yield from thread_exception_runtest_hook()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def thread_exception_runtest_hook() -> Generator[None]:
        with catch_threading_exception() as cm:
            try:
                yield
            finally:
                if cm.args:
                    thread_name = (
                        "<unknown>" if cm.args.thread is None else 
cm.args.thread.name
                    )
                    msg = f"Exception in thread {thread_name}\n\n"
                    msg += "".join(
                        traceback.format_exception(
                            cm.args.exc_type,
                            cm.args.exc_value,
                            cm.args.exc_traceback,
                        )
                    )
>                   
> warnings.warn(pytest.PytestUnhandledThreadExceptionWarning(msg))
E                   pytest.PytestUnhandledThreadExceptionWarning: Exception in 
thread Thread-5 (external_thread_fn)
E                   
E                   Traceback (most recent call last):
E                     File "/usr/lib/python3.13/threading.py", line 1041, in 
_bootstrap_inner
E                       self.run()
E                       ~~~~~~~~^^
E                     File "/usr/lib/python3.13/threading.py", line 992, in run
E                       self._target(*self._args, **self._kwargs)
E                       ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E                     File 
"/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_trio/build/trio/_tests/test_threads.py",
 line 156, in external_thread_fn
E                       from_thread_run_sync(trio_thread_fn, trio_token=token)
E                       ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E                     File 
"/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_trio/build/trio/_threads.py", line 
630, in from_thread_run_sync
E                       return _send_message_to_trio(trio_token, RunSync(fn, 
args))
E                     File 
"/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_trio/build/trio/_threads.py", line 
549, in _send_message_to_trio
E                       return message_to_trio.queue.get().unwrap()
E                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
E                     File "/usr/lib/python3/dist-packages/outcome/_impl.py", 
line 138, in unwrap
E                       raise captured_error
E                     File 
"/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_trio/build/trio/_core/_ki.py", line 
181, in wrapper
E                       return fn(*args, **kwargs)
E                     File 
"/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_trio/build/trio/_threads.py", line 
217, in unprotected_fn
E                       ret = self.context.run(self.fn, *self.args)
E                     File 
"/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_trio/build/trio/_tests/test_threads.py",
 line 141, in trio_thread_fn
E                       assert not _core.currently_ki_protected()
E                   AssertionError: assert not True
E                    +  where True = <function currently_ki_protected at 
0xffff83496700>()
E                    +    where <function currently_ki_protected at 
0xffff83496700> = _core.currently_ki_protected

/usr/lib/python3/dist-packages/_pytest/threadexception.py:82: 
PytestUnhandledThreadExceptionWarning
----------------------------- Captured stdout call -----------------------------
running
waiting
in Trio thread
waited, joining
done
=========================== short test summary info ============================
FAILED trio/_core/_tests/test_ki.py::test_ki_enabled - assert False
FAILED trio/_core/_tests/test_ki.py::test_ki_disabled_in_del - assert not True
FAILED trio/_tests/test_path.py::test_async_method_signature - AssertionError...
FAILED trio/_tests/test_threads.py::test_do_in_trio_thread - AssertionError: ...
FAILED trio/_tests/test_threads.py::test_run_in_trio_thread_ki - pytest.Pytes...
========== 5 failed, 692 passed, 35 skipped, 45 deselected in 10.43s ===========
E: pybuild pybuild:389: test: plugin pyproject failed with: exit code=1: cd 
/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_trio/build; python3.13 -m pytest -m 
"not redistributors_should_skip" -p trio._tests.pytest_plugin -k "not 
test_SocketType_resolve and not test_getprotobyname" --skip-optional-imports
I: pybuild base:311: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_trio/build; 
python3.12 -m pytest -m "not redistributors_should_skip" -p 
trio._tests.pytest_plugin -k "not test_SocketType_resolve and not 
test_getprotobyname" --skip-optional-imports
============================= test session starts ==============================
platform linux -- Python 3.12.6, pytest-8.3.3, pluggy-1.5.0
rootdir: /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_trio/build
configfile: pyproject.toml
plugins: typeguard-4.3.0
collected 776 items / 45 deselected / 1 skipped / 731 selected

trio/_core/_tests/test_asyncgen.py .......                               [  0%]
trio/_core/_tests/test_exceptiongroup_gc.py ..                           [  1%]
trio/_core/_tests/test_guest_mode.py ..............                      [  3%]
trio/_core/_tests/test_instrumentation.py ........                       [  4%]
trio/_core/_tests/test_io.py ............................                [  8%]
trio/_core/_tests/test_ki.py ...........                                 [  9%]
trio/_core/_tests/test_local.py ....                                     [ 10%]
trio/_core/_tests/test_mock_clock.py .....s                              [ 10%]
trio/_core/_tests/test_parking_lot.py ....                               [ 11%]
trio/_core/_tests/test_run.py ................................s......... [ 17%]
........................................................................ [ 27%]
.................................                                        [ 31%]
trio/_core/_tests/test_thread_cache.py ..ss..                            [ 32%]
trio/_core/_tests/test_tutil.py .                                        [ 32%]
trio/_core/_tests/test_unbounded_queue.py .....                          [ 33%]
trio/_core/_tests/test_windows.py sssssss                                [ 34%]
trio/_tests/test_abc.py ...                                              [ 34%]
trio/_tests/test_channel.py .............                                [ 36%]
trio/_tests/test_contextvars.py ...                                      [ 36%]
trio/_tests/test_deprecate.py ...........                                [ 38%]
trio/_tests/test_deprecate_strict_exception_groups_false.py ...          [ 38%]
trio/_tests/test_dtls.py ..s.............s.............                  [ 42%]
trio/_tests/test_exports.py ...                                          [ 43%]
trio/_tests/test_fakenet.py ....s....                                    [ 44%]
trio/_tests/test_file_io.py .................                            [ 46%]
trio/_tests/test_highlevel_generic.py ..                                 [ 47%]
trio/_tests/test_highlevel_open_tcp_listeners.py ....................    [ 49%]
trio/_tests/test_highlevel_open_tcp_stream.py .......................    [ 52%]
trio/_tests/test_highlevel_open_unix_stream.py .....s                    [ 53%]
trio/_tests/test_highlevel_serve_listeners.py ....                       [ 54%]
trio/_tests/test_highlevel_socket.py .......                             [ 55%]
trio/_tests/test_highlevel_ssl_helpers.py ...                            [ 55%]
trio/_tests/test_path.py .s.................................             [ 60%]
trio/_tests/test_scheduler_determinism.py ..                             [ 60%]
trio/_tests/test_signals.py ........                                     [ 61%]
trio/_tests/test_socket.py .......s.......................               [ 66%]
trio/_tests/test_ssl.py ......s.............................s........... [ 72%]
...............                                                          [ 74%]
trio/_tests/test_subprocess.py ....................s........             [ 78%]
trio/_tests/test_sync.py ..................................              [ 83%]
trio/_tests/test_testing.py ...................                          [ 85%]
trio/_tests/test_testing_raisesgroup.py ..........                       [ 87%]
trio/_tests/test_threads.py ............................................ [ 93%]
.s....                                                                   [ 94%]
trio/_tests/test_timeouts.py sss.                                        [ 94%]
trio/_tests/test_tracing.py ..                                           [ 94%]
trio/_tests/test_unix_pipes.py ...........                               [ 96%]
trio/_tests/test_util.py .........                                       [ 97%]
trio/_tests/test_wait_for_object.py ssss                                 [ 98%]
trio/_tests/test_windows_pipes.py ssssss                                 [ 99%]
trio/_tests/tools/test_mypy_annotate.py .......                          [100%]

================ 697 passed, 35 skipped, 45 deselected in 9.04s ================
dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p "3.13 
3.12" returned exit code 13
make: *** [debian/rules:7: binary] Error 25
dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2
--------------------------------------------------------------------------------
Build finished at 2024-09-19T09:05:19Z


If required, the full build log is available here (for the next 30 days):
https://debusine.debian.net/artifact/789934/

This bug has been filed at "normal" severity, as we haven't started the
transition to add 3.13 as a supported version, yet. This will be raised to RC
as soon as that happens, hopefully well before trixie.

Thanks,

Stefano

Reply via email to