mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Have single_or_tuple_any recursively check for tuples
This commit is contained in:
2 files changed
+31
-11
No files matched your search
@@ -52,3 +52,5 @@ class ReturnInt(metaclass=MCReturnInt):
|
||||
|
||||
|
||||
assert isinstance("a", ReturnInt) is True
|
||||
|
||||
assert isinstance(1, ((int, float,), str))
|
||||
+29
-11
@@ -569,17 +569,35 @@ pub fn single_or_tuple_any<T: PyValue, F: Fn(PyRef<T>) -> PyResult<bool>>(
|
||||
message: fn(&PyObjectRef) -> String,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<bool> {
|
||||
match_class!(match obj {
|
||||
obj @ T => predicate(obj),
|
||||
tuple @ PyTuple => {
|
||||
for obj in tuple.elements.iter() {
|
||||
let inner_val = PyRef::<T>::try_from_object(vm, obj.clone())?;
|
||||
if predicate(inner_val)? {
|
||||
return Ok(true);
|
||||
// TODO: figure out some way to have recursive calls without... this
|
||||
use std::marker::PhantomData;
|
||||
struct Checker<'vm, T: PyValue, F: Fn(PyRef<T>) -> PyResult<bool>> {
|
||||
predicate: F,
|
||||
message: fn(&PyObjectRef) -> String,
|
||||
vm: &'vm VirtualMachine,
|
||||
t: PhantomData<T>,
|
||||
}
|
||||
impl<T: PyValue, F: Fn(PyRef<T>) -> PyResult<bool>> Checker<'_, T, F> {
|
||||
fn check(&self, obj: PyObjectRef) -> PyResult<bool> {
|
||||
match_class!(match obj {
|
||||
obj @ T => (self.predicate)(obj),
|
||||
tuple @ PyTuple => {
|
||||
for obj in tuple.elements.iter() {
|
||||
if self.check(obj.clone())? {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
obj => Err(self.vm.new_type_error((self.message)(&obj))),
|
||||
})
|
||||
}
|
||||
obj => Err(vm.new_type_error(message(&obj))),
|
||||
})
|
||||
}
|
||||
let checker = Checker {
|
||||
predicate,
|
||||
message,
|
||||
vm,
|
||||
t: PhantomData,
|
||||
};
|
||||
checker.check(obj)
|
||||
}
|
||||
Reference in new issue
Block a user