Add reduce for set, frozenset.

This commit is contained in:
jfh committed 2021-08-14 01:11:13 +03:00
1 parent 634a6c2435
commit ac0d5ff8b0
2 files changed
+44 -29

No files matched your search

-16
View File
@@ -258,8 +258,6 @@ class TestJointOps:
it = pickle.loads(d)
self.assertEqual(self.thetype(it), data - self.thetype((drop,)))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_deepcopy(self):
class Tracer:
def __init__(self, value):
@@ -673,8 +671,6 @@ class TestSetSubclass(TestSet):
thetype = SetSubclass
basetype = set
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_pickling(self):
super().test_pickling()
@@ -688,8 +684,6 @@ class SetSubclassWithKeywordArgs(set):
set.__init__(self, iterable)
class TestSetSubclassWithKeywordArgs(TestSet):
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_keywords_in_subclass(self):
'SF bug #1486663 -- this used to erroneously raise a TypeError'
SetSubclassWithKeywordArgs(newarg=1)
@@ -787,8 +781,6 @@ class TestFrozenSetSubclass(TestFrozenSet):
thetype = FrozenSetSubclass
basetype = frozenset
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_pickling(self):
super().test_pickling()
@@ -1591,8 +1583,6 @@ class TestCopyingSingleton(TestCopying, unittest.TestCase):
def setUp(self):
self.set = set(["hello"])
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_deep_copy(self):
super().test_deep_copy()
@@ -1602,8 +1592,6 @@ class TestCopyingTriple(TestCopying, unittest.TestCase):
def setUp(self):
self.set = set(["zero", 0, None])
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_deep_copy(self):
super().test_deep_copy()
@@ -1613,8 +1601,6 @@ class TestCopyingTuple(TestCopying, unittest.TestCase):
def setUp(self):
self.set = set([(1, 2)])
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_deep_copy(self):
super().test_deep_copy()
@@ -1624,8 +1610,6 @@ class TestCopyingNested(TestCopying, unittest.TestCase):
def setUp(self):
self.set = set([((1, 2), (3, 4))])
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_deep_copy(self):
super().test_deep_copy()
+44 -13
View File
@@ -1,11 +1,11 @@
/*
* Builtin set type with a sequence of unique items.
*/
use super::pytype::PyTypeRef;
use super::{pytype::PyTypeRef, PyDictRef};
use crate::common::hash::PyHash;
use crate::common::rc::PyRc;
use crate::dictdatatype;
use crate::function::{Args, OptionalArg};
use crate::function::{Args, FuncArgs, OptionalArg};
use crate::slots::{Comparable, Hashable, Iterable, PyComparisonOp, PyIter, Unhashable};
use crate::vm::{ReprGuard, VirtualMachine};
use crate::{
@@ -113,7 +113,7 @@ impl PySetInner {
} else {
(self, other)
};
for key in subset.content.keys() {
for key in subset.elements() {
if !superset.contains(&key, vm)? {
return Ok(false);
}
@@ -155,7 +155,7 @@ impl PySetInner {
// We want to remove duplicates in other
let other_set = Self::new(other, vm)?;
for item in other_set.content.keys() {
for item in other_set.elements() {
new_inner.content.delete_or_insert(vm, &item, ())?
}
@@ -193,14 +193,14 @@ impl PySetInner {
PySetIterator {
dict: PyRc::clone(&self.content),
elements: self.content.keys(),
elements: self.elements(),
size_info: AtomicCell::new(set_size),
}
}
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
let mut str_parts = Vec::with_capacity(self.content.len());
for key in self.content.keys() {
for key in self.elements() {
let part = vm.to_repr(&key)?;
str_parts.push(part.as_str().to_owned());
}
@@ -224,6 +224,10 @@ impl PySetInner {
self.content.clear()
}
fn elements(&self) -> Vec<PyObjectRef> {
self.content.keys()
}
fn pop(&self, vm: &VirtualMachine) -> PyResult {
// TODO: should be pop_front, but that requires rearranging every index
if let Some((key, _)) = self.content.pop_back() {
@@ -275,7 +279,7 @@ impl PySetInner {
for iterable in others {
// We want to remove duplicates in iterable
let iterable_set = Self::new(iterable, vm)?;
for item in iterable_set.content.keys() {
for item in iterable_set.elements() {
self.content.delete_or_insert(vm, &item, ())?;
}
}
@@ -283,7 +287,7 @@ impl PySetInner {
}
fn hash(&self, vm: &VirtualMachine) -> PyResult<PyHash> {
crate::utils::hash_iter_unordered(self.content.keys().iter(), vm)
crate::utils::hash_iter_unordered(self.elements().iter(), vm)
}
// Run operation, on failure, if item is a set/set subclass, convert it
@@ -331,6 +335,21 @@ fn extract_set(obj: &PyObjectRef) -> Option<&PySetInner> {
})
}
fn reduce_set(
zelf: &PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<(PyTypeRef, PyObjectRef, Option<PyDictRef>)> {
Ok((
zelf.clone_class(),
vm.ctx.new_tuple(vec![vm.ctx.new_list(
extract_set(zelf)
.unwrap_or(&PySetInner::default())
.elements(),
)]),
zelf.dict(),
))
}
macro_rules! multi_args_set {
($vm:expr, $others:expr, $zelf:expr, $op:tt) => {{
let mut res = $zelf.inner.copy();
@@ -344,11 +363,7 @@ macro_rules! multi_args_set {
#[pyimpl(with(Hashable, Comparable, Iterable), flags(BASETYPE))]
impl PySet {
#[pyslot]
fn tp_new(
cls: PyTypeRef,
_iterable: OptionalArg<PyIterable>,
vm: &VirtualMachine,
) -> PyResult<PyRef<Self>> {
fn tp_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
PySet::default().into_ref_with_type(vm, cls)
}
@@ -543,6 +558,14 @@ impl PySet {
.symmetric_difference_update(iterable.iterable, vm)?;
Ok(zelf.as_object().clone())
}
#[pymethod(magic)]
fn reduce(
zelf: PyRef<Self>,
vm: &VirtualMachine,
) -> PyResult<(PyTypeRef, PyObjectRef, Option<PyDictRef>)> {
reduce_set(&zelf.into_object(), vm)
}
}
impl Comparable for PySet {
@@ -719,6 +742,14 @@ impl PyFrozenSet {
};
Ok(vm.ctx.new_str(s))
}
#[pymethod(magic)]
fn reduce(
zelf: PyRef<Self>,
vm: &VirtualMachine,
) -> PyResult<(PyTypeRef, PyObjectRef, Option<PyDictRef>)> {
reduce_set(&zelf.into_object(), vm)
}
}
impl Hashable for PyFrozenSet {