Update types from v3.14.2#6833
Conversation
Co-Authored-By: CPython Developers <>
📝 WalkthroughWalkthroughAdds a new Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Caller
participant Frame
participant PyAnextAwaitable
participant PyGenerator
Caller->>Frame: attempt "await" / "yield from" on object
Frame->>PyAnextAwaitable: resolve awaitable (GetAwaitable / GetYieldFromIter)
alt obj is PyGenerator with ITERABLE_COROUTINE
PyAnextAwaitable->>PyGenerator: return generator as awaitable iterator (no __await__ call)
PyGenerator-->>Frame: iterator returned
else other object
PyAnextAwaitable->>PyGenerator: (not applicable) or call __await__ on object
PyAnextAwaitable-->>Frame: awaitable or raise TypeError
end
Frame->>Caller: proceed with await/yield-from using returned iterator or propagate error
rect rgba(0,128,0,0.5)
Note over Frame,PyAnextAwaitable: Flag check for ITERABLE_COROUTINE is central to branching
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Code has been automatically formatted The code in this PR has been formatted using:
git pull origin update-3.14.2-types |
📦 Library DependenciesThe following Lib/ modules were modified. Here are their dependencies: [+] lib: cpython/Lib/_opcode_metadata.py
[+] lib: cpython/Lib/pydoc_data
[+] lib: cpython/Lib/types.py
Legend:
|
1e5e723 to
b25479a
Compare
- Add ITERABLE_COROUTINE (0x0100) to CodeFlags in bytecode.rs - Update frame.rs to check for both COROUTINE and ITERABLE_COROUTINE flags when validating 'yield from' on coroutine objects - Remove False and workaround in types.coroutine() now that the flag is supported - Remove @unittest.expectedFailure from test_async_def and test_genfunc Co-Authored-By: Claude Opus 4.5 <[email protected]>
Generators decorated with @types.coroutine have the CO_ITERABLE_COROUTINE flag set, making them awaitable. The GetAwaitable instruction now properly handles this case instead of only checking for __await__ method. This fixes the "object generator can't be used in 'await' expression" error that occurred with asyncio.sleep(0) which uses @types.coroutine decorated __sleep0() generator internally. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Generators decorated with @types.coroutine have the CO_ITERABLE_COROUTINE flag and can be used in await expressions. The PyAnextAwaitable's get_awaitable_iter method was missing this check, causing builtin anext() to fail with "object generator can't be used in 'await' expression" when used with such generators. Co-Authored-By: Claude Opus 4.5 <[email protected]>
For generators without CO_ITERABLE_COROUTINE flag, try to get __await__ method instead of returning an error immediately. This matches CPython's _PyCoro_GetAwaitableIter behavior which allows generator subclasses that define __await__ to be used in await expressions. Co-Authored-By: Claude Opus 4.5 <[email protected]>
df2a9ce to
b76dde1
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/vm/src/frame.rs (1)
1008-1032: Allow generator subclasses with__await__to be awaited.The current code uses
downcast_ref::<PyGenerator>()which matches any generator, including subclasses, then immediately returns a TypeError if theITERABLE_COROUTINEflag is absent. This blocks generator subclasses that implement__await__, preventing the fallback__await__lookup.Only generators that fail to have the
ITERABLE_COROUTINEflag AND lack an__await__method should error. The check should be restructured to only apply the generator-specific logic when the flag is actually set, allowing non-flagged generators to fall through to the__await__fallback.🔧 Suggested fix (preserve __await__ fallback for non-flagged generators)
- } else if let Some(generator) = awaited_obj.downcast_ref::<PyGenerator>() { - // Generator with CO_ITERABLE_COROUTINE flag can be awaited - // (e.g., generators decorated with `@types.coroutine`) - if generator - .as_coro() - .frame() - .code - .flags - .contains(bytecode::CodeFlags::ITERABLE_COROUTINE) - { - awaited_obj - } else { - return Err(vm.new_type_error(format!( - "object {} can't be used in 'await' expression", - awaited_obj.class().name(), - ))); - } - } else { + } else if awaited_obj + .downcast_ref::<PyGenerator>() + .is_some_and(|generator| { + generator + .as_coro() + .frame() + .code + .flags + .contains(bytecode::CodeFlags::ITERABLE_COROUTINE) + }) + { + awaited_obj + } else { let await_method = vm.get_method_or_type_error( awaited_obj.clone(), identifier!(vm, __await__), || { format!( "object {} can't be used in 'await' expression", awaited_obj.class().name(), ) }, )?; let result = await_method.call((), vm)?; // Check that __await__ returned an iterator if !PyIter::check(&result) { return Err(vm.new_type_error(format!( "__await__() returned non-iterator of type '{}'", result.class().name() ))); } result };
This pull request updates
typesmodule to v3.14.2. While doing it, it fixes also async-related feature. This pull request's base is generated by #6827.Summary by CodeRabbit
New Features
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.