mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Add reduce for set, frozenset.
This commit is contained in:
1 parent
634a6c2435
commit
ac0d5ff8b0
2 files changed
+44
-29
No files matched your search
@@ -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
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user