raise TypeError when `__iter__` method is `None` by elmjag · Pull Request #7092 · RustPython/RustPython
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash # Verify what error CPython raises when __iter__ is dynamically deleted after being set # Also check how get_special_method works and what it returns for None vs missing echo "=== Check get_special_method implementation ===" ast-grep --pattern 'fn get_special_method($$$) { $$$ }' echo "" echo "=== Look for get_special_method definition ===" rg -n 'fn get_special_method' crates/vm/src/ -A 20 | head -50
Repository: RustPython/RustPython
Length of output: 1467
🏁 Script executed:
#!/bin/bash echo "=== Check iter_wrapper and surrounding context in slot.rs ===" rg -n 'iter_wrapper\|__iter__' crates/vm/src/types/slot.rs -B 5 -A 10
Repository: RustPython/RustPython
Length of output: 126
🏁 Script executed:
#!/bin/bash echo "=== Check how other slot wrappers handle missing methods ===" rg -n 'new_attribute_error|new_type_error' crates/vm/src/types/slot.rs -B 3 -A 1 | head -100
Repository: RustPython/RustPython
Length of output: 4724
🏁 Script executed:
#!/bin/bash echo "=== Check if there are references to 'not iterable' error messages ===" rg -n 'not iterable' crates/vm/src/ -B 2 -A 2
Repository: RustPython/RustPython
Length of output: 1234
🏁 Script executed:
#!/bin/bash echo "=== Check get_special_method behavior in the codebase ===" rg -n 'get_special_method.*ok_or' crates/vm/src/ -B 3 -A 3 | head -60
Repository: RustPython/RustPython
Length of output: 122
Change error type from AttributeError to TypeError when __iter__ is missing.
The code at line 551 currently raises AttributeError when get_special_method returns None (i.e., when __iter__ is not found). This is inconsistent with CPython, which raises TypeError: '<ClassName>' object is not iterable. This error type also aligns with how other slot wrappers in the codebase handle missing methods—len_wrapper, repr_wrapper, str_wrapper, and others all use new_type_error() for similar cases.
The method_is_none() check at line 557 handles the case where __iter__ exists but returns None, which should also raise the same TypeError (already correct).
Proposed fix
let method_ident = identifier!(vm, __iter__);
let method = vm
.get_special_method(&zelf, method_ident)?
- .ok_or_else(|| vm.new_attribute_error(method_ident.as_str().to_owned()))?;
+ .ok_or_else(|| vm.new_type_error(format!("'{}' object is not iterable", zelf.class().name())))?;📝 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.
| let method_ident = identifier!(vm, __iter__); | |
| let method = vm | |
| .get_special_method(&zelf, method_ident)? | |
| .ok_or_else(|| vm.new_attribute_error(method_ident.as_str().to_owned()))?; | |
| let method_ident = identifier!(vm, __iter__); | |
| let method = vm | |
| .get_special_method(&zelf, method_ident)? | |
| .ok_or_else(|| vm.new_type_error(format!("'{}' object is not iterable", zelf.class().name())))?; |
🤖 Prompt for AI Agents
In `@crates/vm/src/types/slot.rs` around lines 548 - 551, Replace the
AttributeError raised when __iter__ is missing with a TypeError: in the block
that calls vm.get_special_method(&zelf, identifier!(vm, __iter__)), change the
ok_or_else(...) from vm.new_attribute_error(...) to vm.new_type_error(...) and
construct the message as "'<ClassName>' object is not iterable" using the
object's class name (e.g., format!("'{}' object is not iterable",
zelf.class().name())). Keep the existing method_is_none() TypeError behavior
unchanged.