GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — raise TypeError when `__iter__` method is `None` by elmjag · Pull Request #7092 · RustPython/RustPython
raise TypeError when
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||||||||||||||
| use crate::common::lock::{ | ||||||||||||||||||
| PyMappedRwLockReadGuard, PyMappedRwLockWriteGuard, PyRwLockReadGuard, PyRwLockWriteGuard, | ||||||||||||||||||
| }; | ||||||||||||||||||
| use crate::vm::PyMethod; | ||||||||||||||||||
| use crate::{ | ||||||||||||||||||
| AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, | ||||||||||||||||||
| builtins::{PyInt, PyStr, PyStrInterned, PyStrRef, PyType, PyTypeRef}, | ||||||||||||||||||
|
|
@@ -534,7 +535,30 @@ pub(crate) fn richcompare_wrapper( | |||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| fn iter_wrapper(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult { | ||||||||||||||||||
| vm.call_special_method(&zelf, identifier!(vm, __iter__), ()) | ||||||||||||||||||
| fn method_is_none(method: &PyMethod, vm: &VirtualMachine) -> bool { | ||||||||||||||||||
| match method { | ||||||||||||||||||
| PyMethod::Attribute(meth) => vm.is_none(meth), | ||||||||||||||||||
| _ => false, | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| // | ||||||||||||||||||
| // look-up '__iter__' method | ||||||||||||||||||
| // | ||||||||||||||||||
| 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()))?; | ||||||||||||||||||
|
Comment on lines
+548
to
+551
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 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 The code at line 551 currently raises The 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
Suggested change
🤖 Prompt for AI Agents
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions |
||||||||||||||||||
|
|
||||||||||||||||||
| // | ||||||||||||||||||
| // setting '__iter__' method to 'None' value is used | ||||||||||||||||||
| // to mark non-iterable objects, raise TypeError | ||||||||||||||||||
| // | ||||||||||||||||||
| if method_is_none(&method, vm) { | ||||||||||||||||||
| return Err(vm.new_type_error(format!("'{}' object is not iterable", zelf.class().name()))); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| method.invoke((), vm) | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| fn bool_wrapper(num: PyNumber<'_>, vm: &VirtualMachine) -> PyResult<bool> { | ||||||||||||||||||
|
|
||||||||||||||||||
There was an error while loading. Please reload this page.