Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Lib/test/lock_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,8 @@ def test_nan_timeout(self):
evt = self.eventtype()
self.assertRaises(ValueError, evt.wait, float('nan'))

# Use private attributes (event._cond._waiters)
@support.cpython_only
def test_set_and_clear(self):
# gh-57711: check that wait() returns true even when the event is
# cleared before the waiting thread is woken up.
Expand All @@ -576,8 +578,11 @@ def f():

N = 5
with Bunch(f, N):
# Threads blocked on event.wait()
wait_threads_blocked(N)
# Wait until all threads are registered as waiters in
# event.wait().
for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
if len(event._cond._waiters) >= N:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If possible, I would prefer to avoid accessing private attributes.

Can you try instead to test if len(results) >= N: break?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IMO, test might be something like below:

    def test_set_and_clear(self):
        # gh-57711: check that wait() returns true even when the event is
        # cleared before the waiting thread is woken up.
        event = self.eventtype()
        N = 5
        ready = []
        results = []
        def f():
            ready.append(True)
            results.append(event.wait(support.LONG_TIMEOUT))

        with Bunch(f, N):
            # Threads blocked on event.wait()
            for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
                if len(ready) >= N:
                    break

            # Threads unblocked
            event.set()
            for _ in support.sleeping_retry(support.SHORT_TIMEOUT):
                if len(results) >= N:
                    break
            event.clear()

        self.assertEqual(results, [True] * N)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

with Bunch(...): already waits until all started threads complete. Is it really needed to wait until len(results) >= N before calling event.clear()?

The test description says:

check that wait() returns true even when the event is cleared before the waiting thread is woken up.

Waiting for theads between set() and clear() seems to go against the test description.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You are right. The assertEqual will fail if there is a missing value or a false value So we can remove the last support.sleeping_retry that tests the results.

@YvesDup YvesDup Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If possible, I would prefer to avoid accessing private attributes.

Is it acceptable to check from the representation string of Condition ? The last value is the number of waiting threads.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If my suggested if len(results) >= N: break test works, there is no need to query Condition internals.

@YvesDup YvesDup Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

When entering in the Bunch block, run your suggestion if len(results) >= N: break test hangs.
The results list is only updated when we quit the wait method in each thread, that is triggered from the call to the setmethod of Event in the main thread, later.
Query Condition internals seems necessary and the only way to proceed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@vstinner , sorry to bother you, but the test_set_and_clear test still fails in CI. Could we fix this, please? The OP’s suggestion seems to me to be the only valid one.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the reminder, I forgot about this change. So using only public attributes doesn't work, ok. So I just added @support.cpython_only marker on the test.

break

# Threads unblocked
event.set()
Expand Down
Loading