Skip to content

Commit 76e3113

Browse files
committed
Fix: set.is(super|sub)set must accept arbitrary iterables.
1 parent 8d25d7a commit 76e3113

File tree

2 files changed

+47
-65
lines changed

2 files changed

+47
-65
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_set.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,23 @@ def test_sub_and_super():
187187
assert not set('cbs').issuperset('a')
188188

189189

190-
def test_superset_list():
191-
set = {1, 2, 3, 4}
192-
list = [1, 2, 3, 4]
193-
visited= False
194-
if set.issuperset(list):
195-
visited = True
196-
assert visited
190+
def test_superset_subset():
191+
l = [1, 2, 3, 4]
192+
s = set(l)
193+
t = tuple(l)
194+
assert s.issuperset(s)
195+
assert s.issuperset(l)
196+
assert s.issuperset(t)
197+
assert s >= s
198+
assert_raises(TypeError, lambda: s >= l)
199+
assert_raises(TypeError, lambda: s >= t)
200+
201+
assert s.issubset(s)
202+
assert s.issubset(l)
203+
assert s.issubset(t)
204+
assert s <= s
205+
assert_raises(TypeError, lambda: s <= l)
206+
assert_raises(TypeError, lambda: s <= t)
197207

198208

199209
def test_intersection():

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/FrozenSetBuiltins.java

Lines changed: 30 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
import com.oracle.graal.python.builtins.objects.PNone;
4949
import com.oracle.graal.python.builtins.objects.PNotImplemented;
5050
import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage;
51-
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
5251
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
5352
import com.oracle.graal.python.builtins.objects.common.HashingStorage.Equivalence;
5453
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes;
@@ -72,7 +71,6 @@
7271
import com.oracle.graal.python.runtime.PythonContext;
7372
import com.oracle.graal.python.runtime.exception.PException;
7473
import com.oracle.graal.python.runtime.exception.PythonErrorType;
75-
import com.oracle.graal.python.runtime.sequence.PSequence;
7674
import com.oracle.truffle.api.CompilerDirectives;
7775
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
7876
import com.oracle.truffle.api.dsl.Cached;
@@ -140,29 +138,6 @@ PNotImplemented doGeneric(Object self, Object other) {
140138
}
141139
}
142140

143-
@Builtin(name = __LE__, minNumOfPositionalArgs = 2)
144-
@GenerateNodeFactory
145-
abstract static class LeNode extends PythonBinaryBuiltinNode {
146-
@Child private HashingStorageNodes.ContainsKeyNode containsKeyNode = HashingStorageNodes.ContainsKeyNode.create();
147-
148-
@Specialization
149-
Object run(VirtualFrame frame, PBaseSet self, PBaseSet other,
150-
@Cached HashingCollectionNodes.LenNode selfLen,
151-
@Cached HashingCollectionNodes.LenNode otherLen) {
152-
if (selfLen.execute(self) > otherLen.execute(other)) {
153-
return false;
154-
}
155-
156-
for (Object value : self.values()) {
157-
if (!containsKeyNode.execute(frame, other.getDictStorage(), value)) {
158-
return false;
159-
}
160-
}
161-
162-
return true;
163-
}
164-
}
165-
166141
@Builtin(name = __AND__, minNumOfPositionalArgs = 2)
167142
@GenerateNodeFactory
168143
abstract static class AndNode extends PythonBinaryBuiltinNode {
@@ -467,14 +442,14 @@ public static BinaryUnionNode create() {
467442
abstract static class IsSubsetNode extends PythonBinaryBuiltinNode {
468443
@Specialization
469444
boolean isSubSet(VirtualFrame frame, PBaseSet self, PBaseSet other,
470-
@Cached("create()") HashingStorageNodes.KeysIsSubsetNode isSubsetNode) {
445+
@Cached HashingStorageNodes.KeysIsSubsetNode isSubsetNode) {
471446
return isSubsetNode.execute(frame, self.getDictStorage(), other.getDictStorage());
472447
}
473448

474-
@Specialization
475-
boolean isSubSet(VirtualFrame frame, PBaseSet self, String other,
476-
@Cached("create()") SetNodes.ConstructSetNode constructSetNode,
477-
@Cached("create()") HashingStorageNodes.KeysIsSubsetNode isSubsetNode) {
449+
@Specialization(replaces = "isSubSet")
450+
boolean isSubSetGeneric(VirtualFrame frame, PBaseSet self, Object other,
451+
@Cached SetNodes.ConstructSetNode constructSetNode,
452+
@Cached HashingStorageNodes.KeysIsSubsetNode isSubsetNode) {
478453
PSet otherSet = constructSetNode.executeWith(frame, other);
479454
return isSubsetNode.execute(frame, self.getDictStorage(), otherSet.getDictStorage());
480455
}
@@ -485,52 +460,49 @@ boolean isSubSet(VirtualFrame frame, PBaseSet self, String other,
485460
abstract static class IsSupersetNode extends PythonBinaryBuiltinNode {
486461
@Specialization
487462
boolean isSuperSet(VirtualFrame frame, PBaseSet self, PBaseSet other,
488-
@Cached("create()") HashingStorageNodes.KeysIsSupersetNode isSupersetNode) {
463+
@Cached HashingStorageNodes.KeysIsSupersetNode isSupersetNode) {
489464
return isSupersetNode.execute(frame, self.getDictStorage(), other.getDictStorage());
490465
}
491466

492-
@Specialization
493-
boolean isSuperSetPSequence(VirtualFrame frame, PBaseSet self, PSequence other,
494-
@Cached("create()") SetNodes.ConstructSetNode constructSetNode,
495-
@Cached("create()") HashingStorageNodes.KeysIsSupersetNode isSupersetNode) {
467+
@Specialization(replaces = "isSuperSet")
468+
boolean isSuperSetGeneric(VirtualFrame frame, PBaseSet self, Object other,
469+
@Cached SetNodes.ConstructSetNode constructSetNode,
470+
@Cached HashingStorageNodes.KeysIsSupersetNode isSupersetNode) {
496471
PSet otherSet = constructSetNode.executeWith(frame, other);
497472
return isSupersetNode.execute(frame, self.getDictStorage(), otherSet.getDictStorage());
498473
}
499474

500-
@Specialization
501-
boolean isSuperSetString(VirtualFrame frame, PBaseSet self, String other,
502-
@Cached("create()") SetNodes.ConstructSetNode constructSetNode,
503-
@Cached("create()") HashingStorageNodes.KeysIsSupersetNode isSupersetNode) {
504-
PSet otherSet = constructSetNode.executeWith(frame, other);
505-
return isSupersetNode.execute(frame, self.getDictStorage(), otherSet.getDictStorage());
506-
}
507475
}
508476

509477
@Builtin(name = __LE__, minNumOfPositionalArgs = 2)
510478
@GenerateNodeFactory
511-
abstract static class LessEqualNode extends IsSubsetNode {
479+
abstract static class LessEqualNode extends PythonBinaryBuiltinNode {
512480
@Specialization
513-
Object isLessEqual(VirtualFrame frame, PBaseSet self, Object other,
514-
@Cached("create(__GE__)") LookupAndCallBinaryNode lookupAndCallBinaryNode) {
515-
Object result = lookupAndCallBinaryNode.executeObject(frame, other, self);
516-
if (result != PNone.NO_VALUE) {
517-
return result;
518-
}
519-
throw raise(PythonErrorType.TypeError, "unorderable types: %p <= %p", self, other);
481+
boolean doLE(VirtualFrame frame, PBaseSet self, PBaseSet other,
482+
@Cached HashingStorageNodes.KeysIsSubsetNode isSubsetNode) {
483+
return isSubsetNode.execute(frame, self.getDictStorage(), other.getDictStorage());
484+
}
485+
486+
@Fallback
487+
@SuppressWarnings("unused")
488+
PNotImplemented doNotImplemented(Object self, Object other) {
489+
return PNotImplemented.NOT_IMPLEMENTED;
520490
}
521491
}
522492

523493
@Builtin(name = __GE__, minNumOfPositionalArgs = 2)
524494
@GenerateNodeFactory
525-
abstract static class GreaterEqualNode extends IsSupersetNode {
495+
abstract static class GreaterEqualNode extends PythonBinaryBuiltinNode {
526496
@Specialization
527-
Object isGreaterEqual(VirtualFrame frame, PBaseSet self, Object other,
528-
@Cached("create(__LE__)") LookupAndCallBinaryNode lookupAndCallBinaryNode) {
529-
Object result = lookupAndCallBinaryNode.executeObject(frame, other, self);
530-
if (result != PNone.NO_VALUE) {
531-
return result;
532-
}
533-
throw raise(PythonErrorType.TypeError, "unorderable types: %p >= %p", self, other);
497+
boolean doGE(VirtualFrame frame, PBaseSet self, PBaseSet other,
498+
@Cached HashingStorageNodes.KeysIsSupersetNode isSupersetNode) {
499+
return isSupersetNode.execute(frame, self.getDictStorage(), other.getDictStorage());
500+
}
501+
502+
@Fallback
503+
@SuppressWarnings("unused")
504+
PNotImplemented doNotImplemented(Object self, Object other) {
505+
return PNotImplemented.NOT_IMPLEMENTED;
534506
}
535507
}
536508

0 commit comments

Comments
 (0)