X Tutup
Skip to content

Commit 83a0dea

Browse files
authored
Fix set in-place operators with self argument (#6661)
Co-authored-by: Hugh <HueCodes@users.noreply.github.com>
1 parent b38cdaa commit 83a0dea

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

crates/vm/src/builtins/set.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use crate::{
2424
vm::VirtualMachine,
2525
};
2626
use alloc::fmt;
27+
use core::borrow::Borrow;
2728
use core::ops::Deref;
2829
use rustpython_common::{
2930
atomic::{Ordering, PyAtomic, Radium},
@@ -719,8 +720,10 @@ impl PySet {
719720
}
720721

721722
fn __iand__(zelf: PyRef<Self>, set: AnySet, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
722-
zelf.inner
723-
.intersection_update(core::iter::once(set.into_iterable(vm)?), vm)?;
723+
if !set.is(zelf.as_object()) {
724+
zelf.inner
725+
.intersection_update(core::iter::once(set.into_iterable(vm)?), vm)?;
726+
}
724727
Ok(zelf)
725728
}
726729

@@ -731,8 +734,12 @@ impl PySet {
731734
}
732735

733736
fn __isub__(zelf: PyRef<Self>, set: AnySet, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
734-
zelf.inner
735-
.difference_update(set.into_iterable_iter(vm)?, vm)?;
737+
if set.is(zelf.as_object()) {
738+
zelf.inner.clear();
739+
} else {
740+
zelf.inner
741+
.difference_update(set.into_iterable_iter(vm)?, vm)?;
742+
}
736743
Ok(zelf)
737744
}
738745

@@ -748,8 +755,12 @@ impl PySet {
748755
}
749756

750757
fn __ixor__(zelf: PyRef<Self>, set: AnySet, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
751-
zelf.inner
752-
.symmetric_difference_update(set.into_iterable_iter(vm)?, vm)?;
758+
if set.is(zelf.as_object()) {
759+
zelf.inner.clear();
760+
} else {
761+
zelf.inner
762+
.symmetric_difference_update(set.into_iterable_iter(vm)?, vm)?;
763+
}
753764
Ok(zelf)
754765
}
755766

@@ -1297,6 +1308,13 @@ struct AnySet {
12971308
object: PyObjectRef,
12981309
}
12991310

1311+
impl Borrow<PyObject> for AnySet {
1312+
#[inline(always)]
1313+
fn borrow(&self) -> &PyObject {
1314+
&self.object
1315+
}
1316+
}
1317+
13001318
impl AnySet {
13011319
/// Check if object is a set or frozenset (including subclasses)
13021320
/// Equivalent to CPython's PyAnySet_Check

extra_tests/snippets/builtin_set.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,18 @@ class S(set):
200200
with assert_raises(TypeError):
201201
a &= [1, 2, 3]
202202

203+
a = set([1, 2, 3])
204+
a &= a
205+
assert a == set([1, 2, 3])
206+
207+
a = set([1, 2, 3])
208+
a -= a
209+
assert a == set()
210+
211+
a = set([1, 2, 3])
212+
a ^= a
213+
assert a == set()
214+
203215
a = set([1, 2, 3])
204216
a.difference_update([3, 4, 5])
205217
assert a == set([1, 2])

0 commit comments

Comments
 (0)
X Tutup