Merge pull request #1772 from palaviv/set-fixes

Set fixes
This commit is contained in:
Aviv Palivoda authored and GitHub committed 2020-02-29 12:53:16 +02:00
commit e07ca66db4
3 files changed
+34 -12

No files matched your search

-7
View File
@@ -172,7 +172,6 @@ class TestJointOps:
else:
self.fail("s-t did not screen-out general iterables")
@unittest.skip("TODO: RUSTPYTHON")
def test_symmetric_difference(self):
i = self.s.symmetric_difference(self.otherword)
for c in self.letters:
@@ -187,7 +186,6 @@ class TestJointOps:
self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
@unittest.skip("TODO: RUSTPYTHON")
def test_xor(self):
i = self.s.symmetric_difference(self.otherword)
self.assertEqual(self.s ^ set(self.otherword), i)
@@ -207,7 +205,6 @@ class TestJointOps:
self.assertNotEqual(self.s, frozenset(self.otherword))
self.assertEqual(self.s != self.word, True)
@unittest.skip("TODO: RUSTPYTHON")
def test_setOfFrozensets(self):
t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
s = self.thetype(t)
@@ -515,7 +512,6 @@ class TestSet(TestJointOps, unittest.TestCase):
for c in (self.word + self.otherword):
self.assertIn(c, self.s)
@unittest.skip("TODO: RUSTPYTHON")
def test_intersection_update(self):
retval = self.s.intersection_update(self.otherword)
self.assertEqual(retval, None)
@@ -582,7 +578,6 @@ class TestSet(TestJointOps, unittest.TestCase):
else:
self.assertNotIn(c, self.s)
@unittest.skip("TODO: RUSTPYTHON")
def test_symmetric_difference_update(self):
retval = self.s.symmetric_difference_update(self.otherword)
self.assertEqual(retval, None)
@@ -713,7 +708,6 @@ class TestFrozenSet(TestJointOps, unittest.TestCase):
t = self.thetype(s)
self.assertEqual(id(s), id(t))
@unittest.skip("TODO: RUSTPYTHON")
def test_hash(self):
self.assertEqual(hash(self.thetype('abcdeb')),
hash(self.thetype('ebecda')))
@@ -732,7 +726,6 @@ class TestFrozenSet(TestJointOps, unittest.TestCase):
dup = self.s.copy()
self.assertEqual(id(self.s), id(dup))
@unittest.skip("TODO: RUSTPYTHON")
def test_frozen_as_dictkey(self):
seq = list(range(10)) + list('abcdefg') + ['apple']
key1 = self.thetype(seq)
+21 -5
View File
@@ -9,6 +9,7 @@ use super::objlist::PyListIterator;
use super::objtype::{self, PyClassRef};
use crate::dictdatatype;
use crate::function::{Args, OptionalArg};
use crate::pyhash;
use crate::pyobject::{
PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
@@ -206,8 +207,11 @@ impl PySetInner {
fn symmetric_difference(&self, other: PyIterable, vm: &VirtualMachine) -> PyResult<PySetInner> {
let mut new_inner = self.clone();
for item in other.iter(vm)? {
new_inner.content.delete_or_insert(vm, &item?, ())?
// We want to remove duplicates in other
let other_set = Self::new(other, vm)?;
for item in other_set.content.keys() {
new_inner.content.delete_or_insert(vm, &item, ())?
}
Ok(new_inner)
@@ -294,7 +298,7 @@ impl PySetInner {
others: Args<PyIterable>,
vm: &VirtualMachine,
) -> PyResult<()> {
let temp_inner = self.copy();
let mut temp_inner = self.copy();
self.clear();
for iterable in others {
for item in iterable.iter(vm)? {
@@ -303,6 +307,7 @@ impl PySetInner {
self.add(&obj, vm)?;
}
}
temp_inner = self.copy()
}
Ok(())
}
@@ -322,12 +327,18 @@ impl PySetInner {
vm: &VirtualMachine,
) -> PyResult<()> {
for iterable in others {
for item in iterable.iter(vm)? {
self.content.delete_or_insert(vm, &item?, ())?;
// We want to remove duplicates in iterable
let iterable_set = Self::new(iterable, vm)?;
for item in iterable_set.content.keys() {
self.content.delete_or_insert(vm, &item, ())?;
}
}
Ok(())
}
fn hash(&self, vm: &VirtualMachine) -> PyResult<pyhash::PyHash> {
pyhash::hash_iter_unordered(self.content.keys(), vm)
}
}
macro_rules! try_set_cmp {
@@ -780,6 +791,11 @@ impl PyFrozenSet {
};
Ok(vm.new_str(s))
}
#[pymethod(name = "__hash__")]
fn hash(&self, vm: &VirtualMachine) -> PyResult<pyhash::PyHash> {
self.inner.hash(vm)
}
}
struct SetIterable {
+13
View File
@@ -84,6 +84,19 @@ pub fn hash_iter<'a, I: std::iter::Iterator<Item = &'a PyObjectRef>>(
Ok(hasher.finish() as PyHash)
}
pub fn hash_iter_unordered<I: std::iter::Iterator<Item = PyObjectRef>>(
iter: I,
vm: &VirtualMachine,
) -> PyResult<PyHash> {
let mut hash: PyHash = 0;
for element in iter {
let item_hash = vm._hash(&element)?;
// xor is commutative and hash should be independent of order
hash ^= item_hash;
}
Ok(hash)
}
pub fn hash_bigint(value: &BigInt) -> PyHash {
match value.to_i64() {
Some(i64_value) => (i64_value % MODULUS as i64),