Skip to content

Conversation

@terryluan12
Copy link
Contributor

Notes:

  • Windows-only tests in test_server.py, test_proactor_events.py, test_buffered_proto.py, test_sslproto.py, test_subprocess.py (kinda), and test_windows_events.py and test_windows_utils.py
  • I was not able to run test_ssl.TestSSL.test_create_server_ssl_1 and test_ssl.TestSSL.test_create_server_ssl_over_ssl due to lack of memory
  • Linux skip bugs in test_subprocess.py and test_events.py

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 30, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (21)
  • Lib/asyncio/__main__.py is excluded by !Lib/**
  • Lib/asyncio/base_events.py is excluded by !Lib/**
  • Lib/asyncio/base_subprocess.py is excluded by !Lib/**
  • Lib/asyncio/events.py is excluded by !Lib/**
  • Lib/asyncio/format_helpers.py is excluded by !Lib/**
  • Lib/asyncio/futures.py is excluded by !Lib/**
  • Lib/asyncio/locks.py is excluded by !Lib/**
  • Lib/asyncio/proactor_events.py is excluded by !Lib/**
  • Lib/asyncio/queues.py is excluded by !Lib/**
  • Lib/asyncio/runners.py is excluded by !Lib/**
  • Lib/asyncio/selector_events.py is excluded by !Lib/**
  • Lib/asyncio/sslproto.py is excluded by !Lib/**
  • Lib/asyncio/staggered.py is excluded by !Lib/**
  • Lib/asyncio/streams.py is excluded by !Lib/**
  • Lib/asyncio/taskgroups.py is excluded by !Lib/**
  • Lib/asyncio/tasks.py is excluded by !Lib/**
  • Lib/asyncio/timeouts.py is excluded by !Lib/**
  • Lib/asyncio/transports.py is excluded by !Lib/**
  • Lib/asyncio/unix_events.py is excluded by !Lib/**
  • Lib/asyncio/windows_events.py is excluded by !Lib/**
  • Lib/test/test_unittest/test_async_case.py is excluded by !Lib/**

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@fanninpm fanninpm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase this branch on a fresh copy of main, then note the following little changes.

This PR also contains a "rider". At RustPython, we prefer to keep our PRs limited in scope, so you don't have to slog through 58 separate review comments.

@terryluan12
Copy link
Contributor Author

terryluan12 commented Jan 2, 2026

@fanninpm thanks for all the comments! I'll go through them, and resolve them! (Also hope you had a great New Year + Happy Holiday season!)

Could you also clarify what you mean by rider (I could not understand from the wikipedia link, and didn't find anything online). Do you mean the dual function of updating the library + adding the tests?

(And if so, how would you suggest proceeding? Opening a new PR/closing this one?)

@terryluan12
Copy link
Contributor Author

@fanninpm, nevermind, I see what you mean 😓 I completely did not realize that unrelated commits had came with this PR. Thanks for catching it!

@terryluan12
Copy link
Contributor Author

@fanninpm everything should be good; I've made the formatting changes. As a clarification, I found some of the tests were automatically skipped in RustPython, but were running fine on CPython. The reason is commented below each instance of this occurring

Copy link
Contributor

@fanninpm fanninpm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moral of the story: Don't skip any tests you don't have to skip. Most of the time, marking it as an expected failure will work and will let someone know that they totally accidentally made a test now pass.

Skipping a test should only be done if RustPython panics or hangs or if a test is flaky. Commenting out a test should only be done only in the extremest of circumstances: e.g., the test raises a syntax error in RustPython.

@terryluan12
Copy link
Contributor Author

@fanninpm
So for all the commented out code, when uncommented out, the code crashes the test, and it is unable to run at all

For all the CPython specific tests, If I don't add the explicit skip, it still skips, but for a different reason (for example if I remove the skip in PyTask_CFutureSubclass_Tests in test_tasks.py it skips it for the reason skipped 'requires the C _asyncio module' (because as the code says, it needs a CPython specific module).

I figured better to be thorough and add the explicit skip, so when "TODO: RustPython" is searched, it shows up. Let me know if you want me to remove it

@fanninpm
Copy link
Contributor

fanninpm commented Jan 3, 2026

So for all the commented out code, when uncommented out, the code crashes the test, and it is unable to run at all

Does the @unittest.skip() decorator prevent this from happening?

For all the CPython specific tests, If I don't add the explicit skip, it still skips, but for a different reason (for example if I remove the skip in PyTask_CFutureSubclass_Tests in test_tasks.py it skips it for the reason skipped 'requires the C _asyncio module' (because as the code says, it needs a CPython specific module).

I figured better to be thorough and add the explicit skip, so when "TODO: RustPython" is searched, it shows up. Let me know if you want me to remove it

It might be better to just leave a comment, rather than a @unittest.skip() decorator in this instance.

@terryluan12
Copy link
Contributor Author

So for all the commented out code, when uncommented out, the code crashes the test, and it is unable to run at all

Does the @unittest.skip() decorator prevent this from happening?

No it does not

For all the CPython specific tests, If I don't add the explicit skip, it still skips, but for a different reason (for example if I remove the skip in PyTask_CFutureSubclass_Tests in test_tasks.py it skips it for the reason skipped 'requires the C _asyncio module' (because as the code says, it needs a CPython specific module).
I figured better to be thorough and add the explicit skip, so when "TODO: RustPython" is searched, it shows up. Let me know if you want me to remove it

It might be better to just leave a comment, rather than a @unittest.skip() decorator in this instance.

Ok, I'll make the changes

@terryluan12
Copy link
Contributor Author

@fanninpm Made all changes! I was able to change all the skips into expectedFailures (/removed the ones in test_tasks), and I removed all the CPython skips. Please let me know if there is anything else I should fix (assuming the tests all pass)!

@terryluan12
Copy link
Contributor Author

Re: the CPython specific tests, should I also add an issue for those?

@terryluan12
Copy link
Contributor Author

As an update, I've narrowed down the hang to an issue in the wait method of the Condition class. I think it's an issue with the AST generation? (but not 100%)

The test that is failing is test_locks.ConditionTests.test_cancelled_error_re_aquire
The relevant function is below


async def wait(self):
    """Wait until notified.

    If the calling task has not acquired the lock when this
    method is called, a RuntimeError is raised.

    This method releases the underlying lock, and then blocks
    until it is awakened by a notify() or notify_all() call for
    the same condition variable in another task.  Once
    awakened, it re-acquires the lock and returns True.

    This method may return spuriously,
    which is why the caller should always
    re-check the state and be prepared to wait() again.
    """
    if not self.locked():
        raise RuntimeError('cannot wait on un-acquired lock')

    fut = self._get_loop().create_future()
    self.release()
    try:
        try:
            self._waiters.append(fut)
            try:
                await fut                          # A) It reaches here fine
                return True
            finally:
                self._waiters.remove(fut)

        finally:
            # Must re-acquire lock even if wait is cancelled.
            # We only catch CancelledError here, since we don't want any
            # other (fatal) errors with the future to cause us to spin.
            err = None
            while True:                             # B) The code enters a loop here to reacquire the lock
                try:
                    await self.acquire()            # C) While waiting here, the task is cancelled
                    break
                except exceptions.CancelledError as e:
                    err = e                         # D) The code reaches here fine

            if err is not None:
                try:
                    raise err                       # E) The error is reraised here
                finally:
                    err = None                      # F) It reaches here
    except BaseException:
        self._notify(1)                             # G) It is supposed to exit here
        raise

Whereas in CPython, the program is supposed to go from F) to G), RustPython instead goes from F) to B), re-entering the final statement again (reaquiring the lock again at C), reaching a deadlock state, and hanging.

@terryluan12 terryluan12 marked this pull request as draft January 6, 2026 04:39
@youknowone
Copy link
Member

Thanks! That looks like a compiler bug. Is it possible to create a minimal reproducible script?

'the C _asyncio module' is a c module but probably not a CPython specific feature. We just need to implement it later.

Though we usually prefer to update asyncio and test_asyncio at the same time, test_asyncio anyway even didn't exist in RustPython.

Let's split this PR to 2 parts. Upgrade asyncio first, and see what's happening to other libraries. Currently it is not able to check because test_asyncio is hanging and other tests are not running. If no problem, asyncio will be merged. Then let's try to add test_asyncio again. It will take time due to the compiler problem

@terryluan12
Copy link
Contributor Author

terryluan12 commented Jan 6, 2026

Thanks! That looks like a compiler bug. Is it possible to create a minimal reproducible script?

'the C _asyncio module' is a c module but probably not a CPython specific feature. We just need to implement it later.

Though we usually prefer to update asyncio and test_asyncio at the same time, test_asyncio anyway even didn't exist in RustPython.

Let's split this PR to 2 parts. Upgrade asyncio first, and see what's happening to other libraries. Currently it is not able to check because test_asyncio is hanging and other tests are not running. If no problem, asyncio will be merged. Then let's try to add test_asyncio again. It will take time due to the compiler problem

I'll work on getting something reproducible! In the meantime, Reopening this PR (Force pushing accidentally closed the issue)

@terryluan12 terryluan12 reopened this Jan 6, 2026
@terryluan12 terryluan12 changed the title Update asyncio library + Add asyncio tests Update asyncio library Jan 6, 2026
@terryluan12 terryluan12 marked this pull request as ready for review January 6, 2026 05:14
@terryluan12 terryluan12 requested a review from fanninpm January 6, 2026 05:15
@youknowone
Copy link
Member

youknowone commented Jan 6, 2026

Great! Failing test is unexpected success

======================================================================
UNEXPECTED SUCCESS: test_loop_factory (test.test_unittest.test_async_case.TestAsyncCase.test_loop_factory)
----------------------------------------------------------------------

@fanninpm
Copy link
Contributor

fanninpm commented Jan 6, 2026

Great! Failing test is unexpected success

======================================================================
UNEXPECTED SUCCESS: test_loop_factory (test.test_unittest.test_async_case.TestAsyncCase.test_loop_factory)
----------------------------------------------------------------------

Is it certain that this is not a fluke?

@youknowone
Copy link
Member

usually not when 3 CI envs agree on

@youknowone
Copy link
Member

@terryluan12 could you remove expectedFailure marker from the successful one?

@terryluan12
Copy link
Contributor Author

@youknowone @fanninpm It seems test_multiprocessing_fork is hanging somewhat intermittently; How should we proceed?

@youknowone
Copy link
Member

@terryluan12 If you can find out what test is the cause, mark it as @unittest.skip("TODO: RUSTPYTHON; randomly hang") But it can be done in different PR

@terryluan12
Copy link
Contributor Author

Sounds good. I'm looking right now. I think I found it, but just need to confirm

Copy link
Member

@youknowone youknowone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding information "random" is important. Otherwise another patch will remove the line, and watching CI passes just like now without patch, and then the CI will hang again

@terryluan12
Copy link
Contributor Author

terryluan12 commented Jan 7, 2026

Sounds good! In terms of test_rapid_restart, it doesn't randomly hang; The tests are dynamically generated for 3 or so types, and for two of these types, they pass, and for the last one they fail. I think I've got it so that the expectedFailure is dynamically added though, so should be removed soon.

@terryluan12
Copy link
Contributor Author

Lol, okay, this is so hacked together. Thoughts @youknowone @fanninpm ? (I annotated the lines added, but they will not be on the final commit)

def test_rapid_restart(self):
    failing_test = "WithManagerTestManagerRestart"   # RUSTPYTHON
    rustpython_errors = False                        # RUSTPYTHON
    try:                                             # RUSTPYTHON
        authkey = os.urandom(32)
        manager = QueueManager(
            address=(socket_helper.HOST, 0), authkey=authkey,
            serializer=SERIALIZER, shutdown_timeout=SHUTDOWN_TIMEOUT)
        try:
            srvr = manager.get_server()
            addr = srvr.address
            # Close the connection.Listener socket which gets opened as a part
            # of manager.get_server(). It's not needed for the test.
            srvr.listener.close()
            manager.start()

            p = self.Process(target=self._putter, args=(manager.address, authkey))
            p.start()
            p.join()
            queue = manager.get_queue()
            self.assertEqual(queue.get(), 'hello world')
            del queue
        finally:
            if hasattr(manager, "shutdown"):
                manager.shutdown()

        manager = QueueManager(
            address=addr, authkey=authkey, serializer=SERIALIZER,
            shutdown_timeout=SHUTDOWN_TIMEOUT)
        try:
            manager.start()
            self.addCleanup(manager.shutdown)
        except OSError as e:
            if e.errno != errno.EADDRINUSE:
                raise
            # Retry after some time, in case the old socket was lingering
            # (sporadic failure on buildbots)
            time.sleep(1.0)
            manager = QueueManager(
                address=addr, authkey=authkey, serializer=SERIALIZER,
                shutdown_timeout=SHUTDOWN_TIMEOUT)
            if hasattr(manager, "shutdown"):
                self.addCleanup(manager.shutdown)
    except Exception as e:                           # RUSTPYTHON
        if self.__class__.__name__ != failing_test:  # RUSTPYTHON
            raise                                    # RUSTPYTHON
    else:                                            # RUSTPYTHON
        if self.__class__.__name__ == failing_test:  # RUSTPYTHON
            raise                                    # RUSTPYTHON

@youknowone
Copy link
Member

youknowone commented Jan 7, 2026

We usually don't edit the inside of test without a good reason. Because editing inside increase the cost of updating the test to a new version. Is this test critical enough to enable by editing test code? Otherwise marking the entire test expectedFailure is more desired.

@terryluan12
Copy link
Contributor Author

terryluan12 commented Jan 7, 2026

We usually don't edit the inside of test without a good reason. Because editing inside increase the cost of updating the test to a new version. Is this test critical enough to enable by editing test code? Otherwise marking the entire test expectedFailure is more desired.

I'm not sure what's meant by criticality, but the main issue is that these tests are run/created dynamically. So this test is used for the WithProcessesTestManagerRestart, WithThreadsTestManagerRestart, and WithManagerTestManagerRestart test classes.

As a result, if it's marked expectedFailure, then it will be expectedFailure for all three test classes; but the issue is that it succeeds for two out of the three classes, so no matter what, tests will fail

@youknowone
Copy link
Member

You can create an override of the method in the subclass
Searching " super()" in test code will show examples

@github-actions
Copy link
Contributor

Code has been automatically formatted

The code in this PR has been formatted using cargo fmt --all.
Please pull the latest changes before pushing again:

git pull origin update_asyncio

@terryluan12 terryluan12 marked this pull request as draft January 10, 2026 17:10
@fanninpm
Copy link
Contributor

Could you please rebase this branch on a fresh copy of main? #6410 has just been merged and contains a lot of changes to the test suite.

@youknowone
Copy link
Member

This must be almost done. Could you rebase this one to the main?

@terryluan12 terryluan12 force-pushed the update_asyncio branch 2 times, most recently from 3615b3f to f37485f Compare January 15, 2026 00:56
@terryluan12 terryluan12 marked this pull request as ready for review January 15, 2026 01:55
@terryluan12
Copy link
Contributor Author

I believe the failure in the ubuntu CI, is the same issue as #6716. Other than that, this should be good to rereview!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants