Background
While reviewing #203 / PR #210, I confirmed against the Python 3.14 asyncio-eventloop docs that the asyncio policy system — including `asyncio.set_event_loop_policy()` and `WindowsSelectorEventLoopPolicy` — is scheduled for removal in Python 3.16, not merely deprecated.
Note: The asyncio policy system is deprecated and will be removed in Python 3.16; from there on, this function will return the current running event loop if present else it will return the loop set by `set_event_loop()`.
This is a more aggressive timeline than #203 originally noted (which deferred the change because "the replacement story is messier").
Affected code
```python
proxybroker/cli.py:11-12
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
```
This module-level statement runs at import time on Windows to force the selector loop (avoiding aiohttp/aiodns issues with the proactor loop on Windows).
Why we did this in the first place
aiohttp / aiodns historically require the selector event loop on Windows; the default proactor loop breaks SSL and DNS in subtle ways. The current code uses the documented override mechanism.
Replacement options to evaluate
-
Manual loop construction. In Python 3.16+, the policy system is gone. The new pattern is:
```python
if sys.platform == "win32":
loop = asyncio.SelectorEventLoop()
asyncio.set_event_loop(loop)
```
But this only sets the loop for the current thread, not the default for new threads.
-
`asyncio.run()` + custom loop factory. Pass a custom event loop to `asyncio.run()` via the `loop_factory` parameter (added in 3.12+). This is cleaner but requires a broader refactor of `cli.py` to use `asyncio.run()` instead of the manual `new_event_loop` + `set_event_loop` + `run_until_complete` + `close` pattern.
-
Drop Windows selector override entirely. Modern aiohttp/aiodns may have fixed the proactor compatibility issues — needs verification across the supported Windows + Python matrix.
Acceptance criteria
Priority
Medium — Python 3.16 lands in ~Oct 2027 per the PEP 596 schedule, so we have ~17 months. But this should be addressed before then to avoid a hard break.
Related
Background
While reviewing #203 / PR #210, I confirmed against the Python 3.14 asyncio-eventloop docs that the asyncio policy system — including `asyncio.set_event_loop_policy()` and `WindowsSelectorEventLoopPolicy` — is scheduled for removal in Python 3.16, not merely deprecated.
This is a more aggressive timeline than #203 originally noted (which deferred the change because "the replacement story is messier").
Affected code
```python
proxybroker/cli.py:11-12
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
```
This module-level statement runs at import time on Windows to force the selector loop (avoiding aiohttp/aiodns issues with the proactor loop on Windows).
Why we did this in the first place
aiohttp / aiodns historically require the selector event loop on Windows; the default proactor loop breaks SSL and DNS in subtle ways. The current code uses the documented override mechanism.
Replacement options to evaluate
Manual loop construction. In Python 3.16+, the policy system is gone. The new pattern is:
```python
if sys.platform == "win32":
loop = asyncio.SelectorEventLoop()
asyncio.set_event_loop(loop)
```
But this only sets the loop for the current thread, not the default for new threads.
`asyncio.run()` + custom loop factory. Pass a custom event loop to `asyncio.run()` via the `loop_factory` parameter (added in 3.12+). This is cleaner but requires a broader refactor of `cli.py` to use `asyncio.run()` instead of the manual `new_event_loop` + `set_event_loop` + `run_until_complete` + `close` pattern.
Drop Windows selector override entirely. Modern aiohttp/aiodns may have fixed the proactor compatibility issues — needs verification across the supported Windows + Python matrix.
Acceptance criteria
Priority
Medium — Python 3.16 lands in ~Oct 2027 per the PEP 596 schedule, so we have ~17 months. But this should be addressed before then to avoid a hard break.
Related