Skip to content

test_writing_in_recv_events_fails fails in freethreaded mode #1696

Closed

Description

@justeph

Hi all,

As part of the RISE project, we are building, testing, and publishing riscv64 wheels for a number of popular Python packages, including websockets. We are currently publishing wheels for versions 14.1, 14.2, 15.0, and 15.0.1 (see: https://riseproject.gitlab.io/python/wheel_builder/packages/websockets.html).

Our goal is to upstream this work by submitting a pull request to add native riscv64 support directly to this repository. Before doing so, we want to ensure that the build and test process works correctly and that the resulting wheels behave as expected.

While building and testing the latest release, we encountered a test failure specifically when running the test suite against the Python 3.14t wheels. We would like to report this issue and better understand whether it is a known limitation, a riscv64-specific problem, or something we should address as part of the upstreaming effort.

ERROR: test_writing_in_recv_events_fails (tests.sync.test_connection.ClientConnectionTests.test_writing_in_recv_events_fails)
Error when responding to incoming frames is correctly reported.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/project/tests/sync/test_connection.py", line 961, in test_writing_in_recv_events_fails
    self.remote_connection.ping()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/project/.tox/py/lib/python3.14t/site-packages/websockets/sync/connection.py", line 652, in ping
    with self.send_context():
         ~~~~~~~~~~~~~~~~~^^
  File "/opt/_internal/cpython-3.14.2-nogil/lib/python3.14t/contextlib.py", line 141, in __enter__
    return next(self.gen)
  File "/project/.tox/py/lib/python3.14t/site-packages/websockets/sync/connection.py", line 1020, in send_context
    raise self.protocol.close_exc from original_exc
websockets.exceptions.ConnectionClosedError: no close frame received or sent
======================================================================
ERROR: test_writing_in_recv_events_fails (tests.sync.test_connection.ServerConnectionTests.test_writing_in_recv_events_fails)
Error when responding to incoming frames is correctly reported.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/project/tests/sync/test_connection.py", line 961, in test_writing_in_recv_events_fails
    self.remote_connection.ping()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/project/.tox/py/lib/python3.14t/site-packages/websockets/sync/connection.py", line 652, in ping
    with self.send_context():
         ~~~~~~~~~~~~~~~~~^^
  File "/opt/_internal/cpython-3.14.2-nogil/lib/python3.14t/contextlib.py", line 141, in __enter__
    return next(self.gen)
  File "/project/.tox/py/lib/python3.14t/site-packages/websockets/sync/connection.py", line 1020, in send_context
    raise self.protocol.close_exc from original_exc
websockets.exceptions.ConnectionClosedError: no close frame received or sent
----------------------------------------------------------------------
Ran 1959 tests in 111.028s
FAILED (errors=2, skipped=53)

Full log is available here: https://gitlab.com/riseproject/python/websockets/-/jobs/12860760616

I found another issue about a race condition that may or may not be related #1596. I opened a new issue since I feel like it's more free threaded related in my case.

Activity

  1. aaugustin commented on Feb 9, 2026

    @aaugustin
    Member

    This is an extremely defensive test for an edge case that I don't even know if it is possible at all — getting the socket closed for writing by "something else" while it's still open for reading. I'm not really worried if that test fails.

    From the documentation:

    Specifically, you mustn’t attempt to run the main test suite. It isn’t treated as a deliverable of the project. It doesn’t do what you think it does. It’s designed for the needs of developers, not packagers.

  2. aaugustin commented on Feb 9, 2026

    @aaugustin
    Member

    The error you're seeing suggests that the socket is also closed for reading in addition to being closed for writing after socket.shutdown(SHUT_WR). That's unexpected; the socket implementation on riscv64 should support half-closes.

  3. aaugustin commented on Feb 9, 2026

    @aaugustin
    Member

    There's only two threads involved in this test, one of them being the background thread that every websockets connection runs to deal automatically with control frames in the background, and I'm not seeing why free threading would cause this issue.

  4. aaugustin commented on Feb 9, 2026

    @aaugustin
    Member

    Overall sockets in free-threaded Python don't look super robust yet e.g. here's another spurious failure that happens only on free-threaded Python.

  5. aaugustin commented on Feb 9, 2026

    @aaugustin
    Member

    I don't have access to a RISC-V platform and I'm not super interested in debugging why this tests that works on all mainstream platform fails on RISC-V. I don't think it reveals a substantial problem with websockets on RISC-V anyway.

    The most straightforward solution is simply not to run the tests. (You aren't running all the tests in the repository anyway!)

  6. justeph commented on Feb 10, 2026

    @justeph
    ContributorAuthor

    Hi @aaugustin , thank you for detailed explanations! We will skip tests then.
    Would you be open to PR adding riscv-64 support? I can open one if you are open to it.

  7. aaugustin commented on Feb 10, 2026

    @aaugustin
    Member

    What would that mean in practice? Just enabling more builds in cibuildwheel?

  8. justeph commented on Feb 10, 2026

    @justeph
    ContributorAuthor

    Yes

  9. aaugustin commented on Feb 11, 2026

    @aaugustin
    Member

    I'm OK with building wheels for everything that's well supported by cibuildwheel and can be done on GitHub Actions without additional infrastructure.

    While we're there, I think we should do it not just for RISC-V but also for all other platforms with similar stability / popularity. It should be a small config change.

    PR welcome! :-)

  10. justeph commented on Feb 11, 2026

    @justeph
    ContributorAuthor

    Hi @aaugustin I opened a merge request adding:

    • armv7l
    • ppc64le
    • riscv64
    • s390x

    which are the architectures the most commonly built on various other projects. See #1697.
    On my fork, the job takes 57 min to succeed. Maybe it's time to rework a bit the workflow to use matrix build?

  11. aaugustin commented on Feb 11, 2026

    @aaugustin
    Member

    Thank you, that's super useful!

    You mention running the job on your fork. Did you do this with the GitHub Action and, if yes, can you share a link to the build log? I'd just like to see it working before merging.

    If not, I'll do that — I'll just need to push your branch to this repo and trigger manually the GitHub action (which build but doesn't upload to PyPI when run on a branch).

    Taking 1h isn't a concern for me, given the release frequency on this project. GitHub Actions gives us 6 hours.

  12. justeph commented on Feb 11, 2026

    @justeph
    ContributorAuthor

    https://github.com/justeph/websockets/actions/runs/21903021333 Here is the link of the run. There is a revertme commit on top, to make sure workflow start on branch push ;)

  13. aaugustin commented on Feb 11, 2026

    @aaugustin
    Member

    Perfect, I'll merge (and add a quick line to the changelog) tonight.

  14. clawdney commented on Mar 8, 2026

    @clawdney

    Hi! I'm interested in helping with this. Could you share more context about the use case?

  15. aaugustin commented on Mar 8, 2026

    @aaugustin
    Member

    Actually this issue is resolved already, I just forgot to close it. It looks like clawdney is an AI bot and it is not being helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions