Skip to content

Conversation

kattakaha
Copy link
Contributor

@kattakaha kattakaha commented Sep 28, 2025

Issue number: closes #7397

Summary

This PR addresses the tech debt noted in AsyncBatchProcessor regarding asyncio.get_event_loop() potentially failing in Python 3.12+. The fix replaces the deprecated asyncio.get_event_loop() call with a future-compatible implementation that works across Python versions.

Changes made

  • Replaced asyncio.get_event_loop() with try/except logic using asyncio.get_running_loop() and asyncio.new_event_loop()
  • Updated code comments to explain the Python version compatibility approach
  • Verified the fix works in Python 3.14.0rc2 where asyncio.get_event_loop() raises RuntimeError
  • Maintained backward compatibility with existing Python versions

User experience

  • No breaking changes for existing users
  • Prevents RuntimeError in Python 3.14+ Lambda environments
  • Ensures AsyncBatchProcessor continues to work reliably across all supported Python versions
  • Tests will be added in a follow-up commit to verify the fix

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@Copilot Copilot AI review requested due to automatic review settings September 28, 2025 12:13
@kattakaha kattakaha requested a review from a team as a code owner September 28, 2025 12:13
@pull-request-size pull-request-size bot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Sep 28, 2025
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR addresses deprecated asyncio API usage in the AsyncBatchProcessor to ensure compatibility with Python 3.12+ where asyncio.get_event_loop() will raise RuntimeError when no event loop is running. The fix replaces the deprecated call with future-compatible logic using asyncio.get_running_loop() and asyncio.new_event_loop().

  • Replace deprecated asyncio.get_event_loop() with try/except pattern using modern asyncio APIs
  • Add comprehensive comments explaining Python version compatibility strategy
  • Maintain backward compatibility while preparing for Python 3.14+ requirements

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +138 to +143
try:
loop = asyncio.get_running_loop()
except RuntimeError:
# No running loop, create a new one for Lambda environment
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
Copy link
Preview

Copilot AI Sep 28, 2025

Choose a reason for hiding this comment

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

The logic is incorrect. asyncio.get_running_loop() is used to get an already running event loop, but in a Lambda environment without an active loop, you should directly create a new one. The correct approach is to use asyncio.get_event_loop() replacement pattern with asyncio.new_event_loop() and asyncio.set_event_loop() or use asyncio.run() for the coroutine execution.

Copilot uses AI. Check for mistakes.

Copy link

Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

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

Hey @kattakaha! I left a small comment that probably we need to think a little bit more about this. I'm testing Python 3.14 to see if this is a problem.

Comment on lines +138 to +143
try:
loop = asyncio.get_running_loop()
except RuntimeError:
# No running loop, create a new one for Lambda environment
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this code block is basically doing nothing with this try/except: trying to get a loop running or create a new one, but since Lambda doesn't have an active loop, it mostly falls into the "except" block, right? I haven't tested it yet, but I'm not sure if this is the correct implementation for it.

Copy link

codecov bot commented Sep 29, 2025

Codecov Report

❌ Patch coverage is 0% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.34%. Comparing base (28c6d34) to head (bb3b95e).
⚠️ Report is 4 commits behind head on develop.

Files with missing lines Patch % Lines
aws_lambda_powertools/utilities/batch/base.py 0.00% 5 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #7440      +/-   ##
===========================================
- Coverage    96.37%   96.34%   -0.03%     
===========================================
  Files          275      275              
  Lines        13048    13052       +4     
  Branches       974      974              
===========================================
  Hits         12575    12575              
- Misses         366      370       +4     
  Partials       107      107              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tech debt: Note about asyncio.get_event_loop() failling in Python 3.12+
2 participants