Skip to content

Fix some set operation to compare self with args #3912

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

kth496
Copy link
Contributor

@kth496 kth496 commented Jul 18, 2022

Fix #3881

@kth496 kth496 force-pushed the improve-inplace-op branch from d5e969b to ada0063 Compare July 18, 2022 01:03
@youknowone youknowone added the z-ca-2022 Tag to track contrubution-academy 2022 label Jul 18, 2022
@youknowone
Copy link
Member

It is up to you, but you don't need to put everything in single PR. You can submit splat small PRs for each functions.

@@ -658,7 +658,11 @@ impl PySet {
}

#[pymethod(magic)]
fn iand(zelf: PyRef<Self>, set: AnySet, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
fn iand(zelf: PyRef<Self>, set: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
if zelf.get_id() == set.get_id() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if zelf.get_id() == set.get_id() {
if zelf.is(&set) {

Comment on lines 662 to 707
if zelf.get_id() == set.get_id() {
return Ok(zelf);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intersection_update also needs to have a check like this. As iand and intersection_update share the same PySetInner::intersection_update, we can do better 😊

@kth496
Copy link
Contributor Author

kth496 commented Jul 18, 2022

@youknowone I think these operations are related closely.
So some of the other implementation will be updated in this PR! 😃

@Snowapril Thanks for your advice! I'll try to improve it! 👍

@kth496 kth496 marked this pull request as draft July 19, 2022 14:16
@kth496 kth496 force-pushed the improve-inplace-op branch 3 times, most recently from 2da603f to b378f64 Compare July 19, 2022 17:11
@kth496 kth496 marked this pull request as ready for review July 20, 2022 12:12
@kth496 kth496 force-pushed the improve-inplace-op branch from b378f64 to 2930c84 Compare July 20, 2022 12:21
@kth496
Copy link
Contributor Author

kth496 commented Jul 20, 2022

@youknowone @Snowapril
All bugs described in the issue have been fixed. But I think there's another way to do this better. I'm not good at Rust. Could you please review the code?

I tried to remove duplicated codes. But there are some different constraints between inplace operation methods. (Please See NOTE below)

NOTE:

  1. iand

    • Only one argument with AnySet type. Need to check the type of argument.
  2. intersection_update

    • Variable arguments are allowed. (even 0)
    • All Iterable Types are allowed. (include AnySet)

Same issue on isub difference_update ixor ...

Copy link
Member

@youknowone youknowone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About your concern, I think your approach is reasonable enough.
Maybe there can be more room to do better, but current versions looks good enough to handle them in proper cost.

zelf.inner
.intersection_update(std::iter::once(set.into_iterable(vm)?), vm)?;
fn iand(zelf: PyRef<Self>, set: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
if !set.class().is(vm.ctx.types.set_type) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about frozenset? if frozenset is allowed, maybe AnySet check?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, frozen sets are allowed here. Similarly for isub and ixor.

Comment on lines +661 to +692
if let Some(iterable) = arguments.first() {
if zelf.is(iterable) {
return Ok(());
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check is not only adaptable for len() == 1 case but also do for every argument.

For example, how about s = set(['a']); s.intersection_update(s, s, s, s, s, s)?

.intersection_update(std::iter::once(set.into_iterable(vm)?), vm)?;
fn iand(zelf: PyRef<Self>, set: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
if !set.class().is(vm.ctx.types.set_type) {
return Err(vm.new_type_error("Type error".to_owned()));
Copy link
Member

@DimitrisJim DimitrisJim Nov 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be "unsupported operand type(s) for +=: 'type1' and 'type2'", similarly for the rest of the type errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
z-ca-2022 Tag to track contrubution-academy 2022
Projects
None yet
4 participants