Fix builtin hash()

This commit is contained in:
Jeong YunWon
2019-05-09 02:23:28 +09:00
parent 95a894a443
commit 72043dac99
2 changed files with 16 additions and 2 deletions

View File

@@ -303,8 +303,7 @@ fn builtin_hasattr(obj: PyObjectRef, attr: PyStringRef, vm: &VirtualMachine) ->
fn builtin_hash(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(obj, None)]);
vm.call_method(obj, "__hash__", vec![])
vm._hash(obj).and_then(|v| Ok(vm.new_int(v)))
}
// builtin_help

View File

@@ -23,6 +23,7 @@ use crate::obj::objcode::PyCodeRef;
use crate::obj::objdict::PyDictRef;
use crate::obj::objfunction::{PyFunction, PyMethod};
use crate::obj::objgenerator::PyGenerator;
use crate::obj::objint;
use crate::obj::objiter;
use crate::obj::objsequence;
use crate::obj::objstr::{PyString, PyStringRef};
@@ -36,6 +37,7 @@ use crate::pyobject::{
use crate::stdlib;
use crate::sysmodule;
use num_bigint::BigInt;
use num_traits::ToPrimitive;
// use objects::objects;
@@ -912,6 +914,19 @@ impl VirtualMachine {
})
}
pub fn _hash(&self, obj: &PyObjectRef) -> PyResult<usize> {
const PRIME: usize = 0x1fff_ffff_ffff_ffff;
let hash_obj = self.call_method(obj, "__hash__", vec![])?;
if objtype::isinstance(&hash_obj, &self.ctx.int_type()) {
let hash_int = objint::get_value(&hash_obj);
Ok(hash_int
.to_usize()
.unwrap_or_else(|| (hash_int % PRIME).to_usize().unwrap()))
} else {
Err(self.new_type_error("__hash__ method should return an integer".to_string()))
}
}
// https://docs.python.org/3/reference/expressions.html#membership-test-operations
fn _membership_iter_search(&self, haystack: PyObjectRef, needle: PyObjectRef) -> PyResult {
let iter = objiter::get_iter(self, &haystack)?;