Skip to content

Commit 200f97d

Browse files
committed
Add trait for common set operations on set-like dictionary views.
1 parent ddf485c commit 200f97d

File tree

1 file changed

+18
-44
lines changed

1 file changed

+18
-44
lines changed

vm/src/builtins/dict.rs

Lines changed: 18 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -670,13 +670,6 @@ where
670670

671671
#[pymethod(magic)]
672672
fn reversed(&self) -> Self::ReverseIter;
673-
674-
fn to_set(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PySetInner> {
675-
let len = zelf.dict().len();
676-
let zelf: PyObjectRef = Self::iter(zelf, vm)?;
677-
let iter = PyIterIter::new(vm, zelf, Some(len));
678-
PySetInner::from_iter(iter, vm)
679-
}
680673
}
681674

682675
macro_rules! dict_view {
@@ -911,8 +904,16 @@ dict_view! {
911904
vm.new_tuple((key, value)).into()
912905
}
913906

914-
#[pyimpl(with(DictView, Comparable, Iterable))]
915-
impl PyDictKeys {
907+
// Set operations defined on set-like views of the dictionary.
908+
#[pyimpl]
909+
trait ViewSetOps: DictView {
910+
fn to_set(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PySetInner> {
911+
let len = zelf.dict().len();
912+
let zelf: PyObjectRef = Self::iter(zelf, vm)?;
913+
let iter = PyIterIter::new(vm, zelf, Some(len));
914+
PySetInner::from_iter(iter, vm)
915+
}
916+
916917
#[pymethod(name = "__rxor__")]
917918
#[pymethod(magic)]
918919
fn xor(zelf: PyRef<Self>, other: ArgIterable, vm: &VirtualMachine) -> PyResult<PySet> {
@@ -946,43 +947,13 @@ impl PyDictKeys {
946947
}
947948
}
948949

949-
#[pyimpl(with(DictView, Comparable, Iterable))]
950-
impl PyDictValues {}
950+
impl ViewSetOps for PyDictKeys {}
951+
#[pyimpl(with(DictView, Comparable, Iterable, ViewSetOps))]
952+
impl PyDictKeys {}
951953

952-
#[pyimpl(with(DictView, Comparable, Iterable))]
954+
impl ViewSetOps for PyDictItems {}
955+
#[pyimpl(with(DictView, Comparable, Iterable, ViewSetOps))]
953956
impl PyDictItems {
954-
#[pymethod(name = "__rxor__")]
955-
#[pymethod(magic)]
956-
fn xor(zelf: PyRef<Self>, other: ArgIterable, vm: &VirtualMachine) -> PyResult<PySet> {
957-
let zelf = Self::to_set(zelf, vm)?;
958-
let inner = zelf.symmetric_difference(other, vm)?;
959-
Ok(PySet { inner })
960-
}
961-
962-
#[pymethod(name = "__rand__")]
963-
#[pymethod(magic)]
964-
fn and(zelf: PyRef<Self>, other: ArgIterable, vm: &VirtualMachine) -> PyResult<PySet> {
965-
let zelf = Self::to_set(zelf, vm)?;
966-
let inner = zelf.intersection(other, vm)?;
967-
Ok(PySet { inner })
968-
}
969-
970-
#[pymethod(name = "__ror__")]
971-
#[pymethod(magic)]
972-
fn or(zelf: PyRef<Self>, other: ArgIterable, vm: &VirtualMachine) -> PyResult<PySet> {
973-
let zelf = Self::to_set(zelf, vm)?;
974-
let inner = zelf.union(other, vm)?;
975-
Ok(PySet { inner })
976-
}
977-
978-
#[pymethod(name = "__rsub__")]
979-
#[pymethod(magic)]
980-
fn sub(zelf: PyRef<Self>, other: ArgIterable, vm: &VirtualMachine) -> PyResult<PySet> {
981-
let zelf = Self::to_set(zelf, vm)?;
982-
let inner = zelf.difference(other, vm)?;
983-
Ok(PySet { inner })
984-
}
985-
986957
#[pymethod(magic)]
987958
fn contains(zelf: PyRef<Self>, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult<bool> {
988959
let needle = match_class! {
@@ -1004,6 +975,9 @@ impl PyDictItems {
1004975
}
1005976
}
1006977

978+
#[pyimpl(with(DictView, Comparable, Iterable))]
979+
impl PyDictValues {}
980+
1007981
pub(crate) fn init(context: &PyContext) {
1008982
PyDict::extend_class(context, &context.types.dict_type);
1009983
PyDictKeys::extend_class(context, &context.types.dict_keys_type);

0 commit comments

Comments
 (0)