Skip to content

gh-158093: Add more test coverage for concurrent set operations - #158107

Open
CaQtiml wants to merge 2 commits into
python:mainfrom
CaQtiml:test-concurrent-set-pop
Open

CaQtiml wants to merge 2 commits into
python:mainfrom
CaQtiml:test-concurrent-set-pop

Conversation

@CaQtiml

@CaQtiml CaQtiml commented Sep 24, 2026 •

Copy link
Copy Markdown

Add a case for multiple threads calling set.pop() on the same set. The test checks that all original items are returned exactly once and the set ends up empty.

I only see a test for normal usage (Lib/test/test_set.py), but I do not see any case testing .pop concurrently, so I believe this case will add coverage for free-threaded Python.

Add more test coverage for concurrent operations on built-in sets.

The tests cover concurrent calls to pop(), add(), remove(), discard(), copy(), clear(), update(), difference_update(), and symmetric_difference_update(). You can see more details in a comment below.

Testing

  • make patchcheck
  • ./python.exe -B -X gil=0 -m test test_free_threading.test_set

@python-cla-bot

python-cla-bot Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

@bedevere-app bedevere-app Bot added the tests Tests in the Lib/test dir label Sep 24, 2026
@bedevere-app

bedevere-app Bot commented Sep 24, 2026

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@bedevere-app

bedevere-app Bot commented Sep 28, 2026

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@CaQtiml CaQtiml changed the title gh-158093: Add concurrent test for set.pop() method gh-158093: Add more test coverage for concurrent set operations Sep 30, 2026
@CaQtiml

CaQtiml commented Sep 30, 2026

Copy link
Copy Markdown
Author

I add following tests.

  • test_pop_concurrent tests calling pop() from several threads on the same set. The expected result is that each original element is received exactly once, and the original set becomes empty.
  • test_add_concurrent tests calling add() from several threads. Each thread has its own range of elements, and the expected final set is the union of all ranges. All elements in each range are added to the same set, which is empty at the beginning. In the end, the set has to be the same as the expected set.
  • test_remove_discard_concurrent tests calling remove() and discard() separately from several threads. Each thread has its own range of elements, and the starting set is the union of all ranges, plus some more elements that are not expected to be removed. In the end, this set has to contain only the elements that are not expected to be removed.
  • test_copy_clear_concurrent tests set.copy() while another thread clears the set. In the end, the copied set is either the initial set or an empty set, depending on the execution order. The starting set has to be empty in the end because of clear()
  • test_update_concurrent tests calling update() from several threads. Each thread has its own range of elements, and a starting set has some elements. After the starting set gets updated by all threads, it has to be the same as the union of the starting set and all range elements. Also, the source sets must not be changed.
  • test_update_opposing tests opposing updates of two shared sets. A thread updates the first set with the second set, while another thread updates the second set with the first set. In the end, both sets have to be the union of the first and second sets.
  • test_difference_update_concurrent and test_symmetric_difference_update_concurrent use the same concurrency structure as test_update_concurrent, but for .difference_update and .symmetric_difference_update, respectively.
  • test_difference_update_opposing and test_symmetric_difference_update_opposing use the same concurrency structure as test_update_opposing, but for .difference_update and .symmetric_difference_update, respectively. Their expected results depend on the execution order.

I decided to omit tests for intersection_update() and __iand__() for now because I found a possible race condition that I think should be discussed in another issue (let me check in more detail first if there is an existing issue on what I find). So, I want this PR to include only tests for operations where I have not found a problem.

So, what I added tests pop(), add(), remove(), discard(), copy(), clear(), update(), difference_update(), and symmetric_difference_update(). The tests for update(), difference_update(), and symmetric_difference_update() also use the same internal implementations used by __ior__(), __isub__(), and __ixor__(), respectively.

AI Disclosure: I used Codex to help implement tests, but I verified all test cases manually. I wrote this comment myself; AI was only used to fix grammar.

@CaQtiml
CaQtiml force-pushed the test-concurrent-set-pop branch from b9e8945 to 1cac88d Compare September 30, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting review skip news tests Tests in the Lib/test dir

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants