this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include "set-builtins.h"
3
4#include "gtest/gtest.h"
5
6#include "builtins.h"
7#include "runtime.h"
8#include "test-utils.h"
9
10namespace py {
11namespace testing {
12
13using FrozenSetBuiltinsTest = RuntimeFixture;
14using SetBuiltinsTest = RuntimeFixture;
15using SetIteratorBuiltinsTest = RuntimeFixture;
16
17TEST_F(SetBuiltinsTest, SetPopException) {
18 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"(
19s = {1}
20s.pop()
21s.pop()
22)"),
23 LayoutId::kKeyError, "pop from an empty set"));
24}
25
26TEST_F(SetBuiltinsTest, SetPop) {
27 HandleScope scope(thread_);
28 ASSERT_FALSE(runFromCStr(runtime_, R"(
29s = {1}
30a = s.pop()
31b = len(s)
32)")
33 .isError());
34 Object a(&scope, mainModuleAt(runtime_, "a"));
35 Object b(&scope, mainModuleAt(runtime_, "b"));
36 EXPECT_TRUE(isIntEqualsWord(*a, 1));
37 EXPECT_TRUE(isIntEqualsWord(*b, 0));
38}
39
40TEST_F(SetBuiltinsTest, InitializeByTypeCall) {
41 HandleScope scope(thread_);
42 ASSERT_FALSE(runFromCStr(runtime_, R"(
43s = set()
44)")
45 .isError());
46 Object s(&scope, mainModuleAt(runtime_, "s"));
47 EXPECT_TRUE(s.isSet());
48 EXPECT_EQ(Set::cast(*s).numItems(), 0);
49}
50
51TEST_F(SetBuiltinsTest, SetAdd) {
52 Thread* thread = Thread::current();
53 HandleScope scope(thread);
54 ASSERT_FALSE(runFromCStr(runtime_, R"(
55s = set()
56s.add(1)
57s.add("Hello, World")
58)")
59 .isError());
60 Set s(&scope, mainModuleAt(runtime_, "s"));
61 Object one(&scope, runtime_->newInt(1));
62 Object hello_world(&scope, runtime_->newStrFromCStr("Hello, World"));
63 EXPECT_EQ(s.numItems(), 2);
64 EXPECT_TRUE(setIncludes(thread, s, one));
65 EXPECT_TRUE(setIncludes(thread, s, hello_world));
66}
67
68TEST_F(SetBuiltinsTest, DunderIterReturnsSetIterator) {
69 Thread* thread = Thread::current();
70 HandleScope scope(thread);
71 Set empty_set(&scope, runtime_->newSet());
72 Object iter(&scope, runBuiltin(METH(set, __iter__), empty_set));
73 ASSERT_TRUE(iter.isSetIterator());
74}
75
76TEST_F(SetBuiltinsTest, DunderAnd) {
77 Thread* thread = Thread::current();
78 HandleScope scope(thread);
79
80 Set set1(&scope, runtime_->newSet());
81 Set set2(&scope, runtime_->newSet());
82 Object result(&scope, runBuiltin(METH(set, __and__), set1, set2));
83 ASSERT_TRUE(result.isSet());
84 EXPECT_EQ(Set::cast(*result).numItems(), 0);
85
86 Object key(&scope, SmallInt::fromWord(1));
87 setHashAndAdd(thread, set1, key);
88 key = SmallInt::fromWord(2);
89 setHashAndAdd(thread, set1, key);
90 Object result1(&scope, runBuiltin(METH(set, __and__), set1, set2));
91 ASSERT_TRUE(result1.isSet());
92 EXPECT_EQ(Set::cast(*result1).numItems(), 0);
93
94 key = SmallInt::fromWord(1);
95 setHashAndAdd(thread, set2, key);
96 Object result2(&scope, runBuiltin(METH(set, __and__), set1, set2));
97 ASSERT_TRUE(result2.isSet());
98 Set set(&scope, *result2);
99 EXPECT_EQ(set.numItems(), 1);
100 EXPECT_TRUE(setIncludes(thread, set, key));
101}
102
103TEST_F(SetBuiltinsTest, DunderAndWithNonSet) {
104 Thread* thread = Thread::current();
105 HandleScope scope(thread);
106
107 Object empty_set(&scope, runtime_->newSet());
108 Object none(&scope, NoneType::object());
109 Object result(&scope, runBuiltin(METH(set, __and__), empty_set, none));
110 ASSERT_TRUE(result.isNotImplementedType());
111}
112
113TEST_F(SetBuiltinsTest, DunderIand) {
114 Thread* thread = Thread::current();
115 HandleScope scope(thread);
116
117 Set set1(&scope, runtime_->newSet());
118 Set set2(&scope, runtime_->newSet());
119 Object key(&scope, NoneType::object());
120 Object result(&scope, runBuiltin(METH(set, __iand__), set1, set2));
121 ASSERT_TRUE(result.isSet());
122 EXPECT_EQ(*result, *set1);
123 EXPECT_EQ(Set::cast(*result).numItems(), 0);
124
125 key = SmallInt::fromWord(1);
126 setHashAndAdd(thread, set1, key);
127 key = SmallInt::fromWord(2);
128 setHashAndAdd(thread, set1, key);
129 Object result1(&scope, runBuiltin(METH(set, __iand__), set1, set2));
130 ASSERT_TRUE(result1.isSet());
131 EXPECT_EQ(*result1, *set1);
132 EXPECT_EQ(Set::cast(*result1).numItems(), 0);
133
134 set1 = runtime_->newSet();
135 key = SmallInt::fromWord(1);
136 setHashAndAdd(thread, set1, key);
137 key = SmallInt::fromWord(2);
138 setHashAndAdd(thread, set1, key);
139 setHashAndAdd(thread, set2, key);
140 Object result2(&scope, runBuiltin(METH(set, __iand__), set1, set2));
141 ASSERT_TRUE(result2.isSet());
142 EXPECT_EQ(*result2, *set1);
143 Set set(&scope, *result2);
144 EXPECT_EQ(set.numItems(), 1);
145 EXPECT_TRUE(setIncludes(thread, set, key));
146}
147
148TEST_F(SetBuiltinsTest, DunderIandWithNonSet) {
149 Thread* thread = Thread::current();
150 HandleScope scope(thread);
151
152 Object empty_set(&scope, runtime_->newSet());
153 Object none(&scope, NoneType::object());
154 Object result(&scope, runBuiltin(METH(set, __iand__), empty_set, none));
155 ASSERT_TRUE(result.isNotImplementedType());
156}
157
158TEST_F(SetBuiltinsTest, SetIntersectionWithOneArgumentReturnsIntersection) {
159 Thread* thread = Thread::current();
160 HandleScope scope(thread);
161 Set set(&scope, setFromRange(0, 3));
162 Set set1(&scope, setFromRange(0, 2));
163
164 // set.intersect() with 1 argument
165 Object result(&scope, runBuiltin(METH(set, intersection), set, set1));
166 ASSERT_TRUE(result.isSet());
167 EXPECT_NE(*result, *set);
168 set = *result;
169 EXPECT_EQ(set.numItems(), 2);
170 Object key(&scope, SmallInt::fromWord(0));
171 key = SmallInt::fromWord(0);
172 EXPECT_TRUE(setIncludes(thread, set, key));
173 key = SmallInt::fromWord(1);
174 EXPECT_TRUE(setIncludes(thread, set, key));
175}
176
177TEST_F(SetBuiltinsTest, SetIntersectionWithEmptySetReturnsEmptySet) {
178 Thread* thread = Thread::current();
179 HandleScope scope(thread);
180 Set set(&scope, setFromRange(0, 3));
181 Set set1(&scope, runtime_->newSet());
182
183 // set.intersect() with 2 arguments
184 Object result(&scope, runBuiltin(METH(set, intersection), set, set1));
185 ASSERT_TRUE(result.isSet());
186 EXPECT_NE(*result, *set);
187 EXPECT_EQ(Set::cast(*result).numItems(), 0);
188}
189
190TEST_F(SetBuiltinsTest, SetIntersectionWithEmptyIterableReturnsEmptySet) {
191 HandleScope scope(thread_);
192 Set set(&scope, setFromRange(0, 3));
193 List list(&scope, runtime_->newList());
194 Object result(&scope, runBuiltin(METH(set, intersection), set, list));
195 ASSERT_TRUE(result.isSet());
196 EXPECT_EQ(Set::cast(*result).numItems(), 0);
197}
198
199TEST_F(SetBuiltinsTest, SetIntersectionWithIterableReturnsIntersection) {
200 Thread* thread = Thread::current();
201 HandleScope scope(thread);
202 Set set(&scope, setFromRange(0, 3));
203 List list(&scope, runtime_->newList());
204 Object key(&scope, SmallInt::fromWord(4));
205 runtime_->listAdd(thread, list, key);
206 key = SmallInt::fromWord(0);
207 runtime_->listAdd(thread, list, key);
208 Object result(&scope, runBuiltin(METH(set, intersection), set, list));
209 ASSERT_TRUE(result.isSet());
210 EXPECT_EQ(Set::cast(*result).numItems(), 1);
211 set = *result;
212 EXPECT_TRUE(setIncludes(thread, set, key));
213}
214
215TEST_F(SetBuiltinsTest, SetIntersectionWithFrozenSetReturnsSet) {
216 Thread* thread = Thread::current();
217 HandleScope scope(thread);
218 Set set(&scope, runtime_->newSet());
219 FrozenSet frozen_set(&scope, runtime_->emptyFrozenSet());
220 Object result(&scope, runBuiltin(METH(set, intersection), set, frozen_set));
221 ASSERT_TRUE(result.isSet());
222}
223
224TEST_F(SetBuiltinsTest, FrozenSetIntersectionWithSetReturnsFrozenSet) {
225 Thread* thread = Thread::current();
226 HandleScope scope(thread);
227 FrozenSet frozen_set(&scope, runtime_->emptyFrozenSet());
228 Set set(&scope, runtime_->newSet());
229 Object result(&scope, runBuiltin(METH(set, intersection), frozen_set, set));
230 ASSERT_TRUE(result.isFrozenSet());
231}
232
233TEST_F(SetBuiltinsTest, SetAndWithFrozenSetReturnsSet) {
234 Thread* thread = Thread::current();
235 HandleScope scope(thread);
236 Set set(&scope, runtime_->newSet());
237 FrozenSet frozen_set(&scope, runtime_->emptyFrozenSet());
238 Object result(&scope, runBuiltin(METH(set, __and__), set, frozen_set));
239 ASSERT_TRUE(result.isSet());
240}
241
242TEST_F(SetBuiltinsTest, FrozenSetAndWithSetReturnsFrozenSet) {
243 Thread* thread = Thread::current();
244 HandleScope scope(thread);
245 FrozenSet frozen_set(&scope, runtime_->emptyFrozenSet());
246 Set set(&scope, runtime_->newSet());
247 Object result(&scope, runBuiltin(METH(frozenset, __and__), frozen_set, set));
248 ASSERT_TRUE(result.isFrozenSet());
249}
250
251TEST_F(SetIteratorBuiltinsTest, CallDunderNext) {
252 Thread* thread = Thread::current();
253 HandleScope scope(thread);
254 Set set(&scope, runtime_->newSet());
255 Object value(&scope, SmallInt::fromWord(0));
256 setHashAndAdd(thread, set, value);
257 value = SmallInt::fromWord(1);
258 setHashAndAdd(thread, set, value);
259
260 Object iter(&scope, runBuiltin(METH(set, __iter__), set));
261 ASSERT_TRUE(iter.isSetIterator());
262
263 Object item1(&scope, runBuiltin(METH(set_iterator, __next__), iter));
264 EXPECT_TRUE(isIntEqualsWord(*item1, 0));
265
266 Object item2(&scope, runBuiltin(METH(set_iterator, __next__), iter));
267 EXPECT_TRUE(isIntEqualsWord(*item2, 1));
268
269 Object item3(&scope, runBuiltin(METH(set_iterator, __next__), iter));
270 ASSERT_TRUE(item3.isError());
271}
272
273TEST_F(SetIteratorBuiltinsTest, CallDunderNextWithEmptySet) {
274 Thread* thread = Thread::current();
275 HandleScope scope(thread);
276 Set set(&scope, runtime_->newSet());
277 Object iter(&scope, runBuiltin(METH(set, __iter__), set));
278 ASSERT_TRUE(iter.isSetIterator());
279
280 Object result(&scope, runBuiltin(METH(set_iterator, __next__), iter));
281 ASSERT_TRUE(result.isError());
282}
283
284TEST_F(SetIteratorBuiltinsTest, DunderIterReturnsSelf) {
285 Thread* thread = Thread::current();
286 HandleScope scope(thread);
287 Set empty_set(&scope, runtime_->newSet());
288 Object iter(&scope, runBuiltin(METH(set, __iter__), empty_set));
289 ASSERT_TRUE(iter.isSetIterator());
290
291 // Now call __iter__ on the iterator object
292 Object result(&scope, runBuiltin(METH(set_iterator, __iter__), iter));
293 ASSERT_EQ(*result, *iter);
294}
295
296TEST_F(SetIteratorBuiltinsTest, DunderLengthHintOnEmptySetReturnsZero) {
297 Thread* thread = Thread::current();
298 HandleScope scope(thread);
299 Set empty_set(&scope, runtime_->newSet());
300 Object iter(&scope, runBuiltin(METH(set, __iter__), empty_set));
301 ASSERT_TRUE(iter.isSetIterator());
302
303 Object length_hint(&scope,
304 runBuiltin(METH(set_iterator, __length_hint__), iter));
305 EXPECT_TRUE(isIntEqualsWord(*length_hint, 0));
306}
307
308TEST_F(SetIteratorBuiltinsTest, DunderLengthHintOnConsumedSetReturnsZero) {
309 Thread* thread = Thread::current();
310 HandleScope scope(thread);
311 Set one_element_set(&scope, runtime_->newSet());
312 Object zero(&scope, SmallInt::fromWord(0));
313 setHashAndAdd(thread, one_element_set, zero);
314
315 Object iter(&scope, runBuiltin(METH(set, __iter__), one_element_set));
316 ASSERT_TRUE(iter.isSetIterator());
317
318 Object length_hint1(&scope,
319 runBuiltin(METH(set_iterator, __length_hint__), iter));
320 EXPECT_TRUE(isIntEqualsWord(*length_hint1, 1));
321
322 // Consume the iterator
323 Object item1(&scope, runBuiltin(METH(set_iterator, __next__), iter));
324 EXPECT_TRUE(isIntEqualsWord(*item1, 0));
325
326 Object length_hint2(&scope,
327 runBuiltin(METH(set_iterator, __length_hint__), iter));
328 EXPECT_TRUE(isIntEqualsWord(*length_hint2, 0));
329}
330
331TEST_F(SetBuiltinsTest, IsdisjointWithNonIterableArg) {
332 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"(
333s = {1}
334s.isdisjoint(None)
335)"),
336 LayoutId::kTypeError, "object is not iterable"));
337}
338
339TEST_F(SetBuiltinsTest, IsdisjointWithSetArg) {
340 Thread* thread = Thread::current();
341 HandleScope scope(thread);
342
343 Set set(&scope, runtime_->newSet());
344 Set other(&scope, runtime_->newSet());
345 Object value(&scope, NoneType::object());
346
347 // set().isdisjoint(set())
348 Object result(&scope, runBuiltin(METH(set, isdisjoint), set, other));
349 ASSERT_TRUE(result.isBool());
350 EXPECT_EQ(*result, Bool::trueObj());
351
352 // set().isdisjoint({None})
353 setHashAndAdd(thread, other, value);
354 Object result1(&scope, runBuiltin(METH(set, isdisjoint), set, other));
355 ASSERT_TRUE(result1.isBool());
356 EXPECT_EQ(*result1, Bool::trueObj());
357
358 // {None}.isdisjoint({None})
359 setHashAndAdd(thread, set, value);
360 Object result2(&scope, runBuiltin(METH(set, isdisjoint), set, other));
361 ASSERT_TRUE(result2.isBool());
362 EXPECT_EQ(*result2, Bool::falseObj());
363
364 // {None}.isdisjoint({1})
365 other = runtime_->newSet();
366 value = SmallInt::fromWord(1);
367 setHashAndAdd(thread, other, value);
368 Object result3(&scope, runBuiltin(METH(set, isdisjoint), set, other));
369 ASSERT_TRUE(result3.isBool());
370 EXPECT_EQ(*result3, Bool::trueObj());
371}
372
373TEST_F(SetBuiltinsTest, IsdisjointWithIterableArg) {
374 Thread* thread = Thread::current();
375 HandleScope scope(thread);
376
377 Set set(&scope, runtime_->newSet());
378 List other(&scope, runtime_->newList());
379 Object value(&scope, NoneType::object());
380
381 // set().isdisjoint([])
382 Object result(&scope, runBuiltin(METH(set, isdisjoint), set, other));
383 ASSERT_TRUE(result.isBool());
384 EXPECT_EQ(*result, Bool::trueObj());
385
386 // set().isdisjoint([None])
387 runtime_->listAdd(thread, other, value);
388 Object result1(&scope, runBuiltin(METH(set, isdisjoint), set, other));
389 ASSERT_TRUE(result1.isBool());
390 EXPECT_EQ(*result1, Bool::trueObj());
391
392 // {None}.isdisjoint([None])
393 setHashAndAdd(thread, set, value);
394 Object result2(&scope, runBuiltin(METH(set, isdisjoint), set, other));
395 ASSERT_TRUE(result2.isBool());
396 EXPECT_EQ(*result2, Bool::falseObj());
397
398 // {None}.isdisjoint([1])
399 other = runtime_->newList();
400 value = SmallInt::fromWord(1);
401 runtime_->listAdd(thread, other, value);
402 Object result3(&scope, runBuiltin(METH(set, isdisjoint), set, other));
403 ASSERT_TRUE(result3.isBool());
404 EXPECT_EQ(*result3, Bool::trueObj());
405}
406
407TEST_F(SetBuiltinsTest, DunderEqWithSetSubclass) {
408 ASSERT_FALSE(runFromCStr(runtime_, R"(
409class Bar(set): pass
410
411a = set()
412a1 = {1}
413b = Bar()
414cmp = (a == b)
415cmp1 = (a1 == b)
416cmp2 = (b == a)
417cmp3 = (b == a1)
418cmp4 = (b == b)
419)")
420 .isError());
421 EXPECT_EQ(mainModuleAt(runtime_, "cmp"), Bool::trueObj());
422 EXPECT_EQ(mainModuleAt(runtime_, "cmp1"), Bool::falseObj());
423 EXPECT_EQ(mainModuleAt(runtime_, "cmp2"), Bool::trueObj());
424 EXPECT_EQ(mainModuleAt(runtime_, "cmp3"), Bool::falseObj());
425 EXPECT_EQ(mainModuleAt(runtime_, "cmp4"), Bool::trueObj());
426}
427
428TEST_F(SetBuiltinsTest, DunderNeWithSetSubclass) {
429 ASSERT_FALSE(runFromCStr(runtime_, R"(
430class Bar(set): pass
431
432a = set()
433a1 = {1}
434b = Bar()
435cmp = (a != b)
436cmp1 = (a1 != b)
437cmp2 = (b != a)
438cmp3 = (b != a1)
439cmp4 = (b != b)
440)")
441 .isError());
442 EXPECT_EQ(mainModuleAt(runtime_, "cmp"), Bool::falseObj());
443 EXPECT_EQ(mainModuleAt(runtime_, "cmp1"), Bool::trueObj());
444 EXPECT_EQ(mainModuleAt(runtime_, "cmp2"), Bool::falseObj());
445 EXPECT_EQ(mainModuleAt(runtime_, "cmp3"), Bool::trueObj());
446 EXPECT_EQ(mainModuleAt(runtime_, "cmp4"), Bool::falseObj());
447}
448
449TEST_F(SetBuiltinsTest, DunderGeWithSetSubclass) {
450 ASSERT_FALSE(runFromCStr(runtime_, R"(
451class Bar(set): pass
452
453a = set()
454a1 = {1}
455b = Bar()
456cmp = (a >= b)
457cmp1 = (a1 >= b)
458cmp2 = (b >= a)
459cmp3 = (b >= a1)
460cmp4 = (b >= b)
461)")
462 .isError());
463 EXPECT_EQ(mainModuleAt(runtime_, "cmp"), Bool::trueObj());
464 EXPECT_EQ(mainModuleAt(runtime_, "cmp1"), Bool::trueObj());
465 EXPECT_EQ(mainModuleAt(runtime_, "cmp2"), Bool::trueObj());
466 EXPECT_EQ(mainModuleAt(runtime_, "cmp3"), Bool::falseObj());
467 EXPECT_EQ(mainModuleAt(runtime_, "cmp4"), Bool::trueObj());
468}
469
470TEST_F(SetBuiltinsTest, DunderGtWithSetSubclass) {
471 ASSERT_FALSE(runFromCStr(runtime_, R"(
472class Bar(set): pass
473
474a = set()
475a1 = {1}
476b = Bar()
477cmp = (a > b)
478cmp1 = (a1 > b)
479cmp2 = (b > a)
480cmp3 = (b > a1)
481cmp4 = (b > b)
482)")
483 .isError());
484 EXPECT_EQ(mainModuleAt(runtime_, "cmp"), Bool::falseObj());
485 EXPECT_EQ(mainModuleAt(runtime_, "cmp1"), Bool::trueObj());
486 EXPECT_EQ(mainModuleAt(runtime_, "cmp2"), Bool::falseObj());
487 EXPECT_EQ(mainModuleAt(runtime_, "cmp3"), Bool::falseObj());
488 EXPECT_EQ(mainModuleAt(runtime_, "cmp4"), Bool::falseObj());
489}
490
491TEST_F(SetBuiltinsTest, DunderLeWithSetSubclass) {
492 ASSERT_FALSE(runFromCStr(runtime_, R"(
493class Bar(set): pass
494
495a = set()
496a1 = {1}
497b = Bar()
498cmp = (a <= b)
499cmp1 = (a1 <= b)
500cmp2 = (b <= a)
501cmp3 = (b <= a1)
502cmp4 = (b <= b)
503)")
504 .isError());
505 EXPECT_EQ(mainModuleAt(runtime_, "cmp"), Bool::trueObj());
506 EXPECT_EQ(mainModuleAt(runtime_, "cmp1"), Bool::falseObj());
507 EXPECT_EQ(mainModuleAt(runtime_, "cmp2"), Bool::trueObj());
508 EXPECT_EQ(mainModuleAt(runtime_, "cmp3"), Bool::trueObj());
509 EXPECT_EQ(mainModuleAt(runtime_, "cmp4"), Bool::trueObj());
510}
511
512TEST_F(SetBuiltinsTest, DunderLtWithSetSubclass) {
513 ASSERT_FALSE(runFromCStr(runtime_, R"(
514class Bar(set): pass
515
516a = set()
517a1 = {1}
518b = Bar()
519cmp = (a < b)
520cmp1 = (a1 < b)
521cmp2 = (b < a)
522cmp3 = (b < a1)
523cmp4 = (b < b)
524)")
525 .isError());
526 EXPECT_EQ(mainModuleAt(runtime_, "cmp"), Bool::falseObj());
527 EXPECT_EQ(mainModuleAt(runtime_, "cmp1"), Bool::falseObj());
528 EXPECT_EQ(mainModuleAt(runtime_, "cmp2"), Bool::falseObj());
529 EXPECT_EQ(mainModuleAt(runtime_, "cmp3"), Bool::trueObj());
530 EXPECT_EQ(mainModuleAt(runtime_, "cmp4"), Bool::falseObj());
531}
532
533TEST_F(SetBuiltinsTest, DunderEqWithEmptySetsReturnsTrue) {
534 // (set() == set()) is True
535 Thread* thread = Thread::current();
536 HandleScope scope(thread);
537 Set set(&scope, runtime_->newSet());
538 Set set1(&scope, runtime_->newSet());
539 Object result(&scope, runBuiltin(METH(set, __eq__), set, set1));
540 ASSERT_EQ(*result, Bool::trueObj());
541}
542
543TEST_F(SetBuiltinsTest, DunderEqWithSameSetReturnsTrue) {
544 // s = {0, 1, 2}; (s == s) is True
545 HandleScope scope(thread_);
546 Set set(&scope, setFromRange(0, 3));
547 Object result(&scope, runBuiltin(METH(set, __eq__), set, set));
548 ASSERT_EQ(*result, Bool::trueObj());
549}
550
551TEST_F(SetBuiltinsTest, DunderEqWithEqualSetsReturnsTrue) {
552 // ({0, 1, 2) == {0, 1, 2}) is True
553 HandleScope scope(thread_);
554 Set set(&scope, setFromRange(0, 3));
555 Set set1(&scope, setFromRange(0, 3));
556 Object result(&scope, runBuiltin(METH(set, __eq__), set, set1));
557 ASSERT_EQ(*result, Bool::trueObj());
558}
559
560TEST_F(SetBuiltinsTest, DunderEqWithUnequalSetsReturnsFalse) {
561 // ({0, 1, 2} == {1, 2, 3}) is False
562 HandleScope scope(thread_);
563 Set set(&scope, setFromRange(0, 3));
564 Set set1(&scope, setFromRange(1, 4));
565 Object result(&scope, runBuiltin(METH(set, __eq__), set, set1));
566 ASSERT_EQ(*result, Bool::falseObj());
567}
568
569TEST_F(SetBuiltinsTest, DunderNeWithEmptySetsReturnsFalse) {
570 // (set() != set()) is True
571 Thread* thread = Thread::current();
572 HandleScope scope(thread);
573 Set set(&scope, runtime_->newSet());
574 Set set1(&scope, runtime_->newSet());
575 Object result(&scope, runBuiltin(METH(set, __ne__), set, set1));
576 ASSERT_EQ(*result, Bool::falseObj());
577}
578
579TEST_F(SetBuiltinsTest, DunderNeWithSameSetReturnsFalse) {
580 // s = {0, 1, 2}; (s != s) is False
581 HandleScope scope(thread_);
582 Set set(&scope, setFromRange(0, 3));
583 Object result(&scope, runBuiltin(METH(set, __ne__), set, set));
584 ASSERT_EQ(*result, Bool::falseObj());
585}
586
587TEST_F(SetBuiltinsTest, DunderNeWithEqualSetsReturnsFalse) {
588 // ({0, 1, 2} != {0, 1, 2}) is False
589 HandleScope scope(thread_);
590 Set set(&scope, setFromRange(0, 3));
591 Set set1(&scope, setFromRange(0, 3));
592 Object result(&scope, runBuiltin(METH(set, __ne__), set, set1));
593 ASSERT_EQ(*result, Bool::falseObj());
594}
595
596TEST_F(SetBuiltinsTest, DunderNeWithUnequalSetsReturnsTrue) {
597 // ({0, 1, 2} != {1, 2, 3}) is True
598 HandleScope scope(thread_);
599 Set set(&scope, setFromRange(0, 3));
600 Set set1(&scope, setFromRange(1, 4));
601 Object result(&scope, runBuiltin(METH(set, __ne__), set, set1));
602 ASSERT_EQ(*result, Bool::trueObj());
603}
604
605TEST_F(SetBuiltinsTest, DunderGeWithSameSetReturnsTrue) {
606 // s = {0, 1, 2}; (s >= s) is True
607 HandleScope scope(thread_);
608 Set set(&scope, setFromRange(0, 3));
609 Object result(&scope, runBuiltin(METH(set, __ge__), set, set));
610 ASSERT_EQ(*result, Bool::trueObj());
611}
612
613TEST_F(SetBuiltinsTest, DunderGeWithEqualSetsReturnsTrue) {
614 // ({0, 1, 2} >= {0, 1, 2}) is True
615 HandleScope scope(thread_);
616 Set set(&scope, setFromRange(0, 3));
617 Set set1(&scope, setFromRange(0, 3));
618 Object result(&scope, runBuiltin(METH(set, __ge__), set, set1));
619 ASSERT_EQ(*result, Bool::trueObj());
620}
621
622TEST_F(SetBuiltinsTest, DunderGeWithSupersetReturnsFalse) {
623 // ({0, 1, 2} >= {0, 1, 2, 3}) is False
624 HandleScope scope(thread_);
625 Set set(&scope, setFromRange(0, 3));
626 Set set1(&scope, setFromRange(0, 4));
627 Object result(&scope, runBuiltin(METH(set, __ge__), set, set1));
628 ASSERT_EQ(*result, Bool::falseObj());
629}
630
631TEST_F(SetBuiltinsTest, DunderGeWithEmptySetReturnsTrue) {
632 // ({0, 1, 2} >= set()) is True
633 Thread* thread = Thread::current();
634 HandleScope scope(thread);
635 Set set(&scope, setFromRange(0, 3));
636 Set set1(&scope, runtime_->newSet());
637 Object result(&scope, runBuiltin(METH(set, __ge__), set, set1));
638 ASSERT_EQ(*result, Bool::trueObj());
639}
640
641TEST_F(SetBuiltinsTest, DunderLeWithEmptySetReturnsTrue) {
642 // s = {0, 1, 2}; (s <= s) is True
643 Thread* thread = Thread::current();
644 HandleScope scope(thread);
645 Set set(&scope, runtime_->newSet());
646 Set set1(&scope, runtime_->newSet());
647 Object result(&scope, runBuiltin(METH(set, __le__), set, set1));
648 ASSERT_EQ(*result, Bool::trueObj());
649}
650
651TEST_F(SetBuiltinsTest, DunderLeWithEqualSetsReturnsTrue) {
652 // ({0, 1, 2} <= {0, 1, 2}) is True
653 HandleScope scope(thread_);
654 Set set(&scope, setFromRange(0, 3));
655 Set set1(&scope, setFromRange(0, 3));
656 Object result(&scope, runBuiltin(METH(set, __le__), set, set1));
657 ASSERT_EQ(*result, Bool::trueObj());
658}
659
660TEST_F(SetBuiltinsTest, DunderLeWithSubsetReturnsFalse) {
661 // ({0, 1, 2, 3} <= {0, 1, 2}) is False
662 HandleScope scope(thread_);
663 Set set(&scope, setFromRange(0, 4));
664 Set set1(&scope, setFromRange(0, 3));
665 Object result(&scope, runBuiltin(METH(set, __le__), set, set1));
666 ASSERT_EQ(*result, Bool::falseObj());
667}
668
669TEST_F(SetBuiltinsTest, DunderLeWithEmptySetReturnsFalse) {
670 // ({0, 1, 2} <= set()) is False
671 Thread* thread = Thread::current();
672 HandleScope scope(thread);
673 Set set(&scope, setFromRange(0, 3));
674 Set set1(&scope, runtime_->newSet());
675 Object result(&scope, runBuiltin(METH(set, __le__), set, set1));
676 ASSERT_EQ(*result, Bool::falseObj());
677}
678
679TEST_F(SetBuiltinsTest, DunderGtWithEqualSetsReturnsFalse) {
680 // ({0, 1, 2} > {0, 1, 2}) is False
681 HandleScope scope(thread_);
682 Set set(&scope, setFromRange(0, 3));
683 Set set1(&scope, setFromRange(0, 3));
684 Object result(&scope, runBuiltin(METH(set, __gt__), set, set1));
685 ASSERT_EQ(*result, Bool::falseObj());
686}
687
688TEST_F(SetBuiltinsTest, DunderGtWithSubsetReturnsTrue) {
689 // ({0, 1, 2, 3} > {0, 1, 2}) is True
690 HandleScope scope(thread_);
691 Set set(&scope, setFromRange(0, 4));
692 Set set1(&scope, setFromRange(0, 3));
693 Object result(&scope, runBuiltin(METH(set, __gt__), set, set1));
694 ASSERT_EQ(*result, Bool::trueObj());
695}
696
697TEST_F(SetBuiltinsTest, DunderGtWithSupersetReturnsFalse) {
698 // ({0, 1, 2} > {0, 1, 2, 3}) is False
699 HandleScope scope(thread_);
700 Set set(&scope, setFromRange(0, 3));
701 Set set1(&scope, setFromRange(0, 4));
702 Object result(&scope, runBuiltin(METH(set, __gt__), set, set1));
703 ASSERT_EQ(*result, Bool::falseObj());
704}
705
706TEST_F(SetBuiltinsTest, DunderLtWithEqualSetsReturnsFalse) {
707 // ({0, 1, 2} < {0, 1, 2}) is False
708 HandleScope scope(thread_);
709 Set set(&scope, setFromRange(0, 3));
710 Set set1(&scope, setFromRange(0, 3));
711 Object result(&scope, runBuiltin(METH(set, __lt__), set, set1));
712 ASSERT_EQ(*result, Bool::falseObj());
713}
714
715TEST_F(SetBuiltinsTest, DunderLtWithSupersetReturnsTrue) {
716 // ({0, 1, 2} < {0, 1, 2, 3}) is True
717 HandleScope scope(thread_);
718 Set set(&scope, setFromRange(0, 3));
719 Set set1(&scope, setFromRange(0, 4));
720 Object result(&scope, runBuiltin(METH(set, __lt__), set, set1));
721 ASSERT_EQ(*result, Bool::trueObj());
722}
723
724TEST_F(SetBuiltinsTest, DunderLtWithSubsetReturnsFalse) {
725 // ({0, 1, 2, 3} < {0, 1, 2}) is False
726 HandleScope scope(thread_);
727 Set set(&scope, setFromRange(0, 4));
728 Set set1(&scope, setFromRange(0, 3));
729 Object result(&scope, runBuiltin(METH(set, __lt__), set, set1));
730 ASSERT_EQ(*result, Bool::falseObj());
731}
732
733TEST_F(SetBuiltinsTest, DunderEqWithNonSetSecondArgReturnsNotImplemented) {
734 Thread* thread = Thread::current();
735 HandleScope scope(thread);
736 Set set(&scope, runtime_->newSet());
737 Object none(&scope, NoneType::object());
738 Object result(&scope, runBuiltin(METH(set, __eq__), set, none));
739 ASSERT_EQ(*result, NotImplementedType::object());
740}
741
742TEST_F(SetBuiltinsTest, DunderNeWithNonSetSecondArgReturnsNotImplemented) {
743 Thread* thread = Thread::current();
744 HandleScope scope(thread);
745 Set set(&scope, runtime_->newSet());
746 Object none(&scope, NoneType::object());
747 Object result(&scope, runBuiltin(METH(set, __ne__), set, none));
748 ASSERT_EQ(*result, NotImplementedType::object());
749}
750
751TEST_F(SetBuiltinsTest, DunderGeWithNonSetSecondArgReturnsNotImplemented) {
752 Thread* thread = Thread::current();
753 HandleScope scope(thread);
754 Set set(&scope, runtime_->newSet());
755 Object none(&scope, NoneType::object());
756 Object result(&scope, runBuiltin(METH(set, __ge__), set, none));
757 ASSERT_EQ(*result, NotImplementedType::object());
758}
759
760TEST_F(SetBuiltinsTest, DunderGtWithNonSetSecondArgReturnsNotImplemented) {
761 Thread* thread = Thread::current();
762 HandleScope scope(thread);
763 Set set(&scope, runtime_->newSet());
764 Object none(&scope, NoneType::object());
765 Object result(&scope, runBuiltin(METH(set, __gt__), set, none));
766 ASSERT_EQ(*result, NotImplementedType::object());
767}
768
769TEST_F(SetBuiltinsTest, DunderLeWithNonSetSecondArgReturnsNotImplemented) {
770 Thread* thread = Thread::current();
771 HandleScope scope(thread);
772 Set set(&scope, runtime_->newSet());
773 Object none(&scope, NoneType::object());
774 Object result(&scope, runBuiltin(METH(set, __le__), set, none));
775 ASSERT_EQ(*result, NotImplementedType::object());
776}
777
778TEST_F(SetBuiltinsTest, DunderLtWithNonSetSecondArgReturnsNotImplemented) {
779 Thread* thread = Thread::current();
780 HandleScope scope(thread);
781 Set set(&scope, runtime_->newSet());
782 Object none(&scope, NoneType::object());
783 Object result(&scope, runBuiltin(METH(set, __lt__), set, none));
784 ASSERT_EQ(*result, NotImplementedType::object());
785}
786
787TEST_F(SetBuiltinsTest, DunderInitWithNonIterableRaisesTypeError) {
788 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"(
789set.__init__(set(), None)
790)"),
791 LayoutId::kTypeError,
792 "'NoneType' object is not iterable"));
793}
794
795TEST_F(SetBuiltinsTest, DunderInitWithIteratorUpdatesSet) {
796 Thread* thread = Thread::current();
797 HandleScope scope(thread);
798 Set set(&scope, runtime_->newSet());
799 Set set1(&scope, setFromRange(0, 3));
800 Object result(&scope, runBuiltin(METH(set, __init__), set, set1));
801 ASSERT_TRUE(result.isNoneType());
802 EXPECT_EQ(set.numItems(), set1.numItems());
803 Object key(&scope, SmallInt::fromWord(0));
804 EXPECT_TRUE(setIncludes(thread, set, key));
805 key = SmallInt::fromWord(1);
806 EXPECT_TRUE(setIncludes(thread, set, key));
807 key = SmallInt::fromWord(2);
808 EXPECT_TRUE(setIncludes(thread, set, key));
809}
810
811TEST_F(SetBuiltinsTest, DunderInitWithSetSubclassUpdatesSet) {
812 Thread* thread = Thread::current();
813 HandleScope scope(thread);
814 ASSERT_FALSE(runFromCStr(runtime_, R"(
815class Set(set): pass
816
817s = Set([0, 1, 2])
818)")
819 .isError());
820 Object s(&scope, mainModuleAt(runtime_, "s"));
821 ASSERT_TRUE(runtime_->isInstanceOfSet(*s));
822 Object key(&scope, SmallInt::fromWord(0));
823 Set set(&scope, *s);
824 EXPECT_TRUE(setIncludes(thread, set, key));
825 key = SmallInt::fromWord(1);
826 EXPECT_TRUE(setIncludes(thread, set, key));
827 key = SmallInt::fromWord(2);
828 EXPECT_TRUE(setIncludes(thread, set, key));
829}
830
831TEST_F(SetBuiltinsTest, DunderLenWithSetSubclassReturnsLen) {
832 HandleScope scope(thread_);
833 ASSERT_FALSE(runFromCStr(runtime_, R"(
834class Set(set): pass
835
836s = Set([0, 1, 2])
837)")
838 .isError());
839 Object s(&scope, mainModuleAt(runtime_, "s"));
840 ASSERT_TRUE(runtime_->isInstanceOfSet(*s));
841
842 Object result(&scope, runBuiltin(METH(set, __len__), s));
843 EXPECT_TRUE(isIntEqualsWord(*result, 3));
844}
845
846TEST_F(SetBuiltinsTest, FrozenSetDunderNewReturnsSingleton) {
847 ASSERT_FALSE(
848 runFromCStr(runtime_, "result = frozenset.__new__(frozenset)").isError());
849 HandleScope scope(thread_);
850 Object result(&scope, mainModuleAt(runtime_, "result"));
851 EXPECT_TRUE(result.isFrozenSet());
852 EXPECT_EQ(*result, runtime_->emptyFrozenSet());
853}
854
855TEST_F(SetBuiltinsTest, SubclassOfFrozenSetDunderNewDoesNotReturnSingleton) {
856 ASSERT_FALSE(runFromCStr(runtime_, R"(
857class C(frozenset):
858 pass
859o = C()
860)")
861 .isError());
862 HandleScope scope(thread_);
863 Object o(&scope, mainModuleAt(runtime_, "o"));
864 EXPECT_NE(*o, runtime_->emptyFrozenSet());
865}
866
867TEST_F(SetBuiltinsTest, FrozenSetDunderNewFromEmptyIterableReturnsSingleton) {
868 HandleScope scope(thread_);
869 Type type(&scope, runtime_->typeAt(LayoutId::kFrozenSet));
870 List empty_iterable(&scope, runtime_->newList());
871 Object result(&scope,
872 runBuiltin(METH(frozenset, __new__), type, empty_iterable));
873 EXPECT_EQ(*result, runtime_->emptyFrozenSet());
874}
875
876TEST_F(SetBuiltinsTest, FrozenSetDunderNewFromFrozenSetIsIdempotent) {
877 Thread* thread = Thread::current();
878 HandleScope scope(thread);
879 Type type(&scope, runtime_->typeAt(LayoutId::kFrozenSet));
880 List nonempty_list(&scope, listFromRange(1, 5));
881 FrozenSet frozenset(&scope, runtime_->newFrozenSet());
882 frozenset = setUpdate(Thread::current(), frozenset, nonempty_list);
883 Object result(&scope, runBuiltin(METH(frozenset, __new__), type, frozenset));
884 EXPECT_EQ(*result, *frozenset);
885}
886
887TEST_F(SetBuiltinsTest,
888 FrozenSetDunderNewFromIterableContainsIterableElements) {
889 Thread* thread = Thread::current();
890 HandleScope scope(thread);
891 Type type(&scope, runtime_->typeAt(LayoutId::kFrozenSet));
892 List nonempty_list(&scope, listFromRange(1, 5));
893 Object result_obj(&scope,
894 runBuiltin(METH(frozenset, __new__), type, nonempty_list));
895 ASSERT_TRUE(result_obj.isFrozenSet());
896 FrozenSet result(&scope, *result_obj);
897 EXPECT_EQ(result.numItems(), 4);
898 Int one(&scope, SmallInt::fromWord(1));
899 EXPECT_TRUE(setIncludes(thread, result, one));
900 Int two(&scope, SmallInt::fromWord(2));
901 EXPECT_TRUE(setIncludes(thread, result, two));
902 Int three(&scope, SmallInt::fromWord(3));
903 EXPECT_TRUE(setIncludes(thread, result, three));
904 Int four(&scope, SmallInt::fromWord(4));
905 EXPECT_TRUE(setIncludes(thread, result, four));
906}
907
908TEST_F(SetBuiltinsTest, FrozenSetFromIterableIsNotSingleton) {
909 HandleScope scope(thread_);
910 Type type(&scope, runtime_->typeAt(LayoutId::kFrozenSet));
911 List nonempty_list(&scope, listFromRange(1, 5));
912 Object result1(&scope,
913 runBuiltin(METH(frozenset, __new__), type, nonempty_list));
914 ASSERT_TRUE(result1.isFrozenSet());
915 Object result2(&scope,
916 runBuiltin(METH(frozenset, __new__), type, nonempty_list));
917 ASSERT_TRUE(result2.isFrozenSet());
918 ASSERT_NE(*result1, *result2);
919}
920
921TEST_F(SetBuiltinsTest, FrozenSetDunderNewWithNonIterableRaisesTypeError) {
922 HandleScope scope(thread_);
923 Type type(&scope, runtime_->typeAt(LayoutId::kFrozenSet));
924 Object none(&scope, NoneType::object());
925 Object result(&scope, runBuiltin(METH(frozenset, __new__), type, none));
926 ASSERT_TRUE(result.isError());
927}
928
929TEST_F(SetBuiltinsTest, SetCopy) {
930 Thread* thread = Thread::current();
931 HandleScope scope(thread);
932 Set set(&scope, runtime_->newSet());
933 Object set_copy(&scope, setCopy(thread, set));
934 ASSERT_TRUE(set_copy.isSet());
935 EXPECT_EQ(Set::cast(*set_copy).numItems(), 0);
936
937 Object key(&scope, SmallInt::fromWord(0));
938 setHashAndAdd(thread, set, key);
939 key = SmallInt::fromWord(1);
940 setHashAndAdd(thread, set, key);
941 key = SmallInt::fromWord(2);
942 setHashAndAdd(thread, set, key);
943
944 Object set_copy1(&scope, setCopy(thread, set));
945 ASSERT_TRUE(set_copy1.isSet());
946 EXPECT_EQ(Set::cast(*set_copy1).numItems(), 3);
947 set = *set_copy1;
948 key = SmallInt::fromWord(0);
949 EXPECT_TRUE(setIncludes(thread, set, key));
950 key = SmallInt::fromWord(1);
951 EXPECT_TRUE(setIncludes(thread, set, key));
952 key = SmallInt::fromWord(2);
953 EXPECT_TRUE(setIncludes(thread, set, key));
954}
955
956TEST_F(SetBuiltinsTest, SetEqualsWithSameSetReturnsTrue) {
957 // s = {0, 1, 2}; (s == s) is True
958 Thread* thread = Thread::current();
959 HandleScope scope(thread);
960 Set set(&scope, setFromRange(0, 3));
961 ASSERT_TRUE(setEquals(thread, set, set));
962}
963
964TEST_F(SetBuiltinsTest, SetIsSubsetWithEmptySetsReturnsTrue) {
965 // (set() <= set()) is True
966 Thread* thread = Thread::current();
967 HandleScope scope(thread);
968 Set set(&scope, runtime_->newSet());
969 Set set1(&scope, runtime_->newSet());
970 ASSERT_TRUE(setIsSubset(thread, set, set1));
971}
972
973TEST_F(SetBuiltinsTest, SetIsSubsetWithEmptySetAndNonEmptySetReturnsTrue) {
974 // (set() <= {0, 1, 2}) is True
975 Thread* thread = Thread::current();
976 HandleScope scope(thread);
977 Set set(&scope, runtime_->newSet());
978 Set set1(&scope, setFromRange(0, 3));
979 ASSERT_TRUE(setIsSubset(thread, set, set1));
980}
981
982TEST_F(SetBuiltinsTest, SetIsSubsetWithEqualsetReturnsTrue) {
983 // ({0, 1, 2} <= {0, 1, 2}) is True
984 Thread* thread = Thread::current();
985 HandleScope scope(thread);
986 Set set(&scope, setFromRange(0, 3));
987 Set set1(&scope, setFromRange(0, 3));
988 ASSERT_TRUE(setIsSubset(thread, set, set1));
989}
990
991TEST_F(SetBuiltinsTest, SetIsSubsetWithSubsetReturnsTrue) {
992 // ({1, 2, 3} <= {1, 2, 3, 4}) is True
993 Thread* thread = Thread::current();
994 HandleScope scope(thread);
995 Set set(&scope, setFromRange(1, 4));
996 Set set1(&scope, setFromRange(1, 5));
997 ASSERT_TRUE(setIsSubset(thread, set, set1));
998}
999
1000TEST_F(SetBuiltinsTest, SetIsSubsetWithSupersetReturnsFalse) {
1001 // ({1, 2, 3, 4} <= {1, 2, 3}) is False
1002 Thread* thread = Thread::current();
1003 HandleScope scope(thread);
1004 Set set(&scope, setFromRange(1, 5));
1005 Set set1(&scope, setFromRange(1, 4));
1006 ASSERT_FALSE(setIsSubset(thread, set, set1));
1007}
1008
1009TEST_F(SetBuiltinsTest, SetIsSubsetWithSameSetReturnsTrue) {
1010 // s = {0, 1, 2}; (s <= s) is True
1011 Thread* thread = Thread::current();
1012 HandleScope scope(thread);
1013 Set set(&scope, setFromRange(0, 4));
1014 ASSERT_TRUE(setIsSubset(thread, set, set));
1015}
1016
1017TEST_F(SetBuiltinsTest, SetIsProperSubsetWithSupersetReturnsTrue) {
1018 // ({0, 1, 2, 3} < {0, 1, 2, 3, 4}) is True
1019 Thread* thread = Thread::current();
1020 HandleScope scope(thread);
1021 Set set(&scope, setFromRange(0, 4));
1022 Set set1(&scope, setFromRange(0, 5));
1023 ASSERT_TRUE(setIsProperSubset(thread, set, set1));
1024}
1025
1026TEST_F(SetBuiltinsTest, SetIsProperSubsetWithUnequalSetsReturnsFalse) {
1027 // ({1, 2, 3} < {0, 1, 2}) is False
1028 Thread* thread = Thread::current();
1029 HandleScope scope(thread);
1030 Set set(&scope, setFromRange(1, 4));
1031 Set set1(&scope, setFromRange(0, 3));
1032 ASSERT_FALSE(setIsProperSubset(thread, set, set1));
1033}
1034
1035TEST_F(SetBuiltinsTest, SetIsProperSubsetWithSameSetReturnsFalse) {
1036 // s = {0, 1, 2}; (s < s) is False
1037 Thread* thread = Thread::current();
1038 HandleScope scope(thread);
1039 Set set(&scope, setFromRange(0, 3));
1040 ASSERT_FALSE(setIsProperSubset(thread, set, set));
1041}
1042
1043TEST_F(SetBuiltinsTest, SetIsProperSubsetWithSubsetReturnsFalse) {
1044 // ({1, 2, 3, 4} < {1, 2, 3}) is False
1045 Thread* thread = Thread::current();
1046 HandleScope scope(thread);
1047 Set set(&scope, setFromRange(1, 5));
1048 Set set1(&scope, setFromRange(1, 4));
1049 ASSERT_FALSE(setIsProperSubset(thread, set, set1));
1050}
1051
1052TEST_F(SetBuiltinsTest, RecursiveSetPrintsEllipsis) {
1053 ASSERT_FALSE(runFromCStr(runtime_, R"(
1054class C:
1055 def __init__(self, obj):
1056 self.val = obj
1057 def __repr__(self):
1058 return self.val.__repr__()
1059 def __hash__(self):
1060 return 5
1061
1062s = set()
1063c = C(s)
1064s.add(c)
1065result = s.__repr__()
1066)")
1067 .isError());
1068 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "result"), "{set(...)}"));
1069}
1070
1071TEST_F(SetBuiltinsTest, CopyReturnsNewObject) {
1072 Thread* thread = Thread::current();
1073 HandleScope scope(thread);
1074 Set set(&scope, runtime_->newSet());
1075 Object result(&scope, runBuiltin(METH(set, copy), set));
1076 EXPECT_NE(*set, *result);
1077 EXPECT_TRUE(result.isSet());
1078}
1079
1080TEST_F(SetBuiltinsTest, CopyReturnsShallowCopy) {
1081 Thread* thread = Thread::current();
1082 HandleScope scope(thread);
1083 Set set(&scope, runtime_->newSet());
1084 Object obj(&scope, newTupleWithNone(5));
1085 setHashAndAdd(thread, set, obj);
1086 Set set2(&scope, runBuiltin(METH(set, copy), set));
1087 bool has_object = false;
1088 Object value(&scope, NoneType::object());
1089 for (word i = 0; setNextItem(set2, &i, &value);) {
1090 if (value == *obj) {
1091 has_object = true;
1092 break;
1093 }
1094 }
1095 EXPECT_TRUE(has_object);
1096}
1097
1098TEST_F(FrozenSetBuiltinsTest, CopyFrozenSetReturnsSameObject) {
1099 Thread* thread = Thread::current();
1100 HandleScope scope(thread);
1101 FrozenSet set(&scope, runtime_->newFrozenSet());
1102 Object result(&scope, runBuiltin(METH(frozenset, copy), set));
1103 EXPECT_EQ(*set, *result);
1104 EXPECT_TRUE(result.isFrozenSet());
1105}
1106
1107TEST_F(FrozenSetBuiltinsTest, CopyFrozenSetSubsetReturnsNewObject) {
1108 HandleScope scope(thread_);
1109 ASSERT_FALSE(runFromCStr(runtime_, R"(
1110class C(frozenset):
1111 pass
1112sub = C()
1113result = frozenset.copy(sub)
1114)")
1115 .isError());
1116 Object sub(&scope, mainModuleAt(runtime_, "sub"));
1117 Object result(&scope, mainModuleAt(runtime_, "result"));
1118 EXPECT_TRUE(runtime_->isInstanceOfFrozenSet(*sub));
1119 EXPECT_TRUE(runtime_->isInstanceOfFrozenSet(*result));
1120 EXPECT_FALSE(sub.isFrozenSet());
1121 EXPECT_TRUE(result.isFrozenSet());
1122 EXPECT_NE(sub, result);
1123}
1124
1125TEST_F(FrozenSetBuiltinsTest, CopyMakesShallowCopy) {
1126 Thread* thread = Thread::current();
1127 HandleScope scope(thread);
1128 FrozenSet set(&scope, runtime_->newFrozenSet());
1129 Object obj(&scope, newTupleWithNone(5));
1130 setHashAndAdd(thread, set, obj);
1131 FrozenSet set2(&scope, runBuiltin(METH(frozenset, copy), set));
1132 bool has_object = false;
1133 Object value(&scope, NoneType::object());
1134 for (word i = 0; setNextItem(set2, &i, &value);) {
1135 if (value == *obj) {
1136 has_object = true;
1137 break;
1138 }
1139 }
1140 EXPECT_TRUE(has_object);
1141}
1142
1143TEST_F(SetBuiltinsTest, UpdateWithNoArgsDoesNothing) {
1144 Thread* thread = Thread::current();
1145 HandleScope scope(thread);
1146 Set set(&scope, runtime_->newSet());
1147 Tuple starargs(&scope, runtime_->emptyTuple());
1148 Object result(&scope, runBuiltin(METH(set, update), set, starargs));
1149 EXPECT_TRUE(result.isNoneType());
1150 EXPECT_EQ(set.numItems(), 0);
1151}
1152
1153TEST_F(SetBuiltinsTest, UpdateWithNonIterableRaisesTypeError) {
1154 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"(
1155result = set()
1156result.update({5}, {6}, None)
1157)"),
1158 LayoutId::kTypeError,
1159 "'NoneType' object is not iterable"));
1160 HandleScope scope(thread_);
1161 Set result(&scope, mainModuleAt(runtime_, "result"));
1162 EXPECT_EQ(result.numItems(), 2);
1163}
1164
1165TEST_F(SetBuiltinsTest, UpdateWithSetAddsElements) {
1166 ASSERT_FALSE(runFromCStr(runtime_, R"(
1167result = set()
1168result.update({5})
1169)")
1170 .isError());
1171 HandleScope scope(thread_);
1172 Set result(&scope, mainModuleAt(runtime_, "result"));
1173 EXPECT_EQ(result.numItems(), 1);
1174}
1175
1176TEST_F(SetBuiltinsTest, UpdateWithMultipleSetsAddsAllElements) {
1177 ASSERT_FALSE(runFromCStr(runtime_, R"(
1178result = set()
1179result.update({5}, {6})
1180)")
1181 .isError());
1182 HandleScope scope(thread_);
1183 Set result(&scope, mainModuleAt(runtime_, "result"));
1184 EXPECT_EQ(result.numItems(), 2);
1185}
1186
1187TEST_F(SetBuiltinsTest, UpdateWithIterableAddsElements) {
1188 ASSERT_FALSE(runFromCStr(runtime_, R"(
1189result = set([1, 2])
1190result.update([5, 6])
1191)")
1192 .isError());
1193 HandleScope scope(thread_);
1194 Set result(&scope, mainModuleAt(runtime_, "result"));
1195 EXPECT_EQ(result.numItems(), 4);
1196}
1197
1198TEST_F(SetBuiltinsTest, DunderOrWithNonSetBaseOtherReturnsNotImplemented) {
1199 ASSERT_FALSE(
1200 runFromCStr(runtime_, "result = set.__or__(set(), None)").isError());
1201 EXPECT_EQ(mainModuleAt(runtime_, "result"), NotImplementedType::object());
1202}
1203
1204TEST_F(SetBuiltinsTest, DunderOrReturnsSetContainingUnionOfElements) {
1205 ASSERT_FALSE(
1206 runFromCStr(runtime_, "result = set.__or__({1, 2}, {2, 3})").isError());
1207 Thread* thread = Thread::current();
1208 HandleScope scope(thread);
1209 Object result_obj(&scope, mainModuleAt(runtime_, "result"));
1210 EXPECT_TRUE(result_obj.isSet());
1211 Set result(&scope, *result_obj);
1212 EXPECT_EQ(result.numItems(), 3);
1213 Object one(&scope, SmallInt::fromWord(1));
1214 EXPECT_TRUE(setIncludes(thread, result, one));
1215 Object two(&scope, SmallInt::fromWord(2));
1216 EXPECT_TRUE(setIncludes(thread, result, two));
1217 Object three(&scope, SmallInt::fromWord(3));
1218 EXPECT_TRUE(setIncludes(thread, result, three));
1219}
1220
1221} // namespace testing
1222} // namespace py