Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-121468: Ensure PDB cleans up event loop policies after using asyncio. #131388

Merged
merged 3 commits into from
Mar 19, 2025

Conversation

freakboy3742
Copy link
Contributor

@freakboy3742 freakboy3742 commented Mar 18, 2025

#124367 added a PDB test that interacts with asyncio. Under some conditions, this can lead to a warning during test execution because the PDB test "alters the execution environment" by setting an event loop policy:

$ python.exe -m test  test_asyncio.test_unix_events test_pdb
Using random seed: 451824264
0:00:00 load avg: 15.60 Run 2 tests sequentially in a single process
0:00:00 load avg: 15.60 [1/2] test_asyncio.test_unix_events
0:00:00 load avg: 15.55 [1/2] test_asyncio.test_unix_events passed
0:00:00 load avg: 15.55 [2/2] test_pdb
Warning -- asyncio.events._event_loop_policy was modified by test_pdb
Warning --   Before: None
Warning --   After:  <asyncio.unix_events._UnixDefaultEventLoopPolicy object at 0x101d80190> 
0:00:08 load avg: 15.51 [2/2/1] test_pdb failed (env changed)

== Tests result: SUCCESS ==

1 test altered the execution environment (env changed):
    test_pdb

1 test OK.

Total duration: 8.1 sec
Total tests: run=282 skipped=2
Total test files: run=2/2 env_changed=1
Result: SUCCESS

This problem only manifests if you run the tests suite sequentially, or if an asyncio test is performed in the same process as the test_pdb test. iOS and Android tests are always run sequentially, so those platforms are hitting this problem reliably.

This fix ensures that test_pdb cleans up the event policy at the end of each test. The approach I've taken seems consistent with other "end of test cleanup" methods in test_asyncio.

@freakboy3742
Copy link
Contributor Author

!buildbot iOS|Android

@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @freakboy3742 for commit e8ed3a8 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F131388%2Fmerge

The command will test the builders whose names match following regular expression: iOS|Android

The builders matched are:

  • AMD64 Android PR
  • aarch64 Android PR
  • iOS ARM64 Simulator PR

@gaogaotiantian
Copy link
Member

Hmm, I have some doubts to do this in PdbTestInput. For the majority of tests, this is not needed. Well actually there's only one test that needs it. It might be benign but it just feels weird to me to do it in such a common function. Do you mind just putting it in the actual test?

@freakboy3742
Copy link
Contributor Author

Hmm, I have some doubts to do this in PdbTestInput. For the majority of tests, this is not needed.

True - but AFAICT, it should be a benign (and fast) cleanup; and it guarantees that any PDB test that triggers asyncio activity will guarantee that it will be cleaned up automatically, rather than requiring test developers to remember that asyncio cleanup is needed on a per-test basis.

This is especially significant for iOS and Android, because they often end up as the "canary" identifying issues with sequential test execution. There's nothing iOS- or Android-speciifc about this test or test failure, but the iOS and Android buildbots are the only ones that reveal the problem because they're the only test configurations that actually run the tests sequentially. Anything we can do to systematically prevent this class of failure in the future is a win for me because I don't have to chase down buildbot failures that aren't actually caused by iOS- or Android-specific issues.

@gaogaotiantian
Copy link
Member

gaogaotiantian commented Mar 18, 2025

The reason it feels weird to me is that this piece of code does not belong there. PdbTestInput has a clear semantics and it does not include cleaning up test residues.

I think a better place would be tests.addTest(doctest.DocTestSuite(test_pdb, setUp=setUpPdbBackend('monitoring'))) (make sure you updated to the latest main as this was just merged). You can put a tearDown there which set the policy to None - that makes more sense to me.

@freakboy3742
Copy link
Contributor Author

I think a better place would be tests.addTest(doctest.DocTestSuite(test_pdb, setUp=setUpPdbBackend('monitoring')))

Agreed - that makes more sense. I've made that modification.

@freakboy3742
Copy link
Contributor Author

!buildbot iOS|Android

@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @freakboy3742 for commit 6c794e0 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F131388%2Fmerge

The command will test the builders whose names match following regular expression: iOS|Android

The builders matched are:

  • AMD64 Android PR
  • aarch64 Android PR
  • iOS ARM64 Simulator PR

@freakboy3742
Copy link
Contributor Author

!buildbot iOS

@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by @freakboy3742 for commit 584aa2b 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F131388%2Fmerge

The command will test the builders whose names match following regular expression: iOS

The builders matched are:

  • iOS ARM64 Simulator PR

@gaogaotiantian
Copy link
Member

So we are doing a double insurance here.

@freakboy3742
Copy link
Contributor Author

@gaogaotiantian Following discussion with @graingert on Discord, I've modified this to use a two-prong approach:

  1. Modifying the usage of asyncio.run() to use the correct "long term" API
  2. Retaining the cleanup-on-tearDown so that if a new PDB test forgets to use the loop_factory API, it won't break iOS and Android CI.

@graingert mentioned he has an in-progress PR to fail if the async.run() API is used in the "non-clean" (i.e., not passing the loop factory) way; until that lands, the 2 prong approach gives some safety that iOS and Android buildbots won't break.

@freakboy3742 freakboy3742 merged commit b754aee into python:main Mar 19, 2025
43 checks passed
@freakboy3742 freakboy3742 deleted the pdb-async-cleanup branch March 19, 2025 00:33
colesbury pushed a commit to colesbury/cpython that referenced this pull request Mar 20, 2025
… asyncio. (python#131388)

Adds teardown logic, plus a change to asyncio.run usage, to avoid warnings when
running the test suite single process.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants