(TLDR: Keep lazy tasks the default forever, encourage use of eager tasks, add eager_tasks flag to run() but not to create_task().)
Having initiated, helped with, and observed many, many of these “should be nearly 100% compatible” changes, I believe we should be very conservative. I don’t know how far back in terms of Python versions libraries like aiohttp or anyio or other libraries built on top of asyncio go, but in other areas I’ve often hear from library maintainers who insisted that a certain way of spelling some thing should remain valid (with the same semantics) for the entire range of Python versions they support, and preferably 1-2 versions more, before they are willing to change their code to use the new spelling across all versions. And nobody wants to maintain support for both spellings, even if it could be done using some helper function (always better than in-lining a version check).
This means we can’t require them to use eager_tasks=False anywhere until all Python versions they need to support have that flag.
I’m not actually sure how being able to pick at task creation helps any use case, so I’m so far neutral on the first bullet as well. Someone who has a need for this should raise their hand and explain their use case (and we’ll have to guess how real that use case is, since this is all hypothetical). AFAIK Instagram, who spearheaded eager tasks, didn’t give their developers a choice.
There was mention of wanting to start with eager tasks but going back to lazy tasks during shutdown. I honestly didn’t understand the reason for doing that, but as long as we can still call set_task_factory() with the lazy task factory at that point, the requirement is satisfied.
All in all I currently support the proposal someone made several posts back: keep lazy_tasks as the default “forever” but encourage using eager tasks to all new users, and encourage libraries to fully support (and test!) both.
PS. Whenever I hear someone say both “let’s switch ASAP” and “I only had to change a few tests out of thousands” I cringe a little bit – those few tests that didn’t work represent many hours of debugging for every developer whose code happens to set up the same scenario as one of those tests (but much more complicated – a failing unit test is much easier to debug than a mysterious occasional application error, whe all you know is that it worked in 3.12 but occasionally broke in 3.14).
Also app developers may skip multiple Python releases since they can’t defend the effort of testing and upgrading to their management, making them miss deprecation warnings. (We can sort of morally oblige libraries to support every version, but not developers of proprietary applications.)