Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Implement minimal builtins.anext()
issue : #3609

Signed-off-by: Yash Suthar <[email protected]>
  • Loading branch information
YashSuthar983 committed Oct 28, 2025
commit d08b04e48e976290be8ef033186b60e97b97f917
16 changes: 16 additions & 0 deletions vm/src/stdlib/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,22 @@ mod builtins {
iter_target.get_aiter(vm)
}

#[pyfunction]
fn anext(
aiter: PyObjectRef,
default_value: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
let awaitable = vm.call_method(&aiter, "__anext__", ())?;

if default_value.is_missing() {
Ok(awaitable)
} else {
// TODO: Implement CPython like PyAnextAwaitable to properly handle the default value.
Ok(awaitable)
}
}
Comment on lines +537 to +551
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Incomplete default value handling makes the function only partially functional.

The default_value parameter is accepted but completely ignored—both branches return the same awaitable regardless of whether a default is provided. This causes the function to fail the second use case described in the PR objectives: when the async iterator is exhausted and a default value is provided, RustPython raises StopAsyncIteration instead of returning the default like CPython does.

While the TODO comment acknowledges this limitation, having a function signature that accepts a parameter it cannot honor is problematic because:

  • Users expect CPython-compatible behavior
  • The silent acceptance of default_value creates a false sense of functionality
  • It's better to fail fast than fail silently

Consider one of these approaches before merging:

Option 1 (preferred if feasible): Complete the implementation by adding PyAnextAwaitable to wrap the awaitable and handle the default value case.

Option 2: Reject the default parameter explicitly until support is implemented:

 #[pyfunction]
 fn anext(
     aiter: PyObjectRef,
     default_value: OptionalArg<PyObjectRef>,
     vm: &VirtualMachine,
 ) -> PyResult {
     let awaitable = vm.call_method(&aiter, "__anext__", ())?;
 
-    if default_value.is_missing() {
-        Ok(awaitable)
-    } else {
-        // TODO: Implement CPython like PyAnextAwaitable to properly handle the default value.
-        Ok(awaitable)
+    if let OptionalArg::Present(_) = default_value {
+        Err(vm.new_not_implemented_error(
+            "anext() with default value is not yet implemented".to_owned()
+        ))
+    } else {
+        Ok(awaitable)
     }
 }

Option 3: Defer merging this PR until the default value handling is fully implemented.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#[pyfunction]
fn anext(
aiter: PyObjectRef,
default_value: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
let awaitable = vm.call_method(&aiter, "__anext__", ())?;
if default_value.is_missing() {
Ok(awaitable)
} else {
// TODO: Implement CPython like PyAnextAwaitable to properly handle the default value.
Ok(awaitable)
}
}
#[pyfunction]
fn anext(
aiter: PyObjectRef,
default_value: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
let awaitable = vm.call_method(&aiter, "__anext__", ())?;
if let OptionalArg::Present(_) = default_value {
Err(vm.new_not_implemented_error(
"anext() with default value is not yet implemented".to_owned()
))
} else {
Ok(awaitable)
}
}


#[pyfunction]
fn len(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
obj.length(vm)
Expand Down
Loading