this repo has no description
at trunk 1058 lines 33 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "list-builtins.h" 3 4#include "gtest/gtest.h" 5 6#include "builtins-module.h" 7#include "builtins.h" 8#include "objects.h" 9#include "runtime.h" 10#include "test-utils.h" 11 12namespace py { 13namespace testing { 14 15using ListBuiltinsTest = RuntimeFixture; 16using ListIteratorBuiltinsTest = RuntimeFixture; 17 18TEST_F(ListBuiltinsTest, CopyWithListReturnsNewInstance) { 19 ASSERT_FALSE(runFromCStr(runtime_, R"( 20l = [1, 2, 3] 21result = list.copy(l) 22)") 23 .isError()); 24 HandleScope scope(thread_); 25 Object list(&scope, mainModuleAt(runtime_, "l")); 26 EXPECT_TRUE(list.isList()); 27 Object result_obj(&scope, mainModuleAt(runtime_, "result")); 28 EXPECT_TRUE(result_obj.isList()); 29 List result(&scope, *result_obj); 30 EXPECT_NE(*list, *result); 31 EXPECT_EQ(result.numItems(), 3); 32} 33 34TEST_F(ListBuiltinsTest, DunderEqReturnsTrue) { 35 ASSERT_FALSE(runFromCStr(runtime_, R"( 36result = list.__eq__([1, 2, 3], [1, 2, 3]) 37)") 38 .isError()); 39 EXPECT_EQ(mainModuleAt(runtime_, "result"), RawBool::trueObj()); 40} 41 42TEST_F(ListBuiltinsTest, DunderEqWithSameListReturnsTrue) { 43 ASSERT_FALSE(runFromCStr(runtime_, R"( 44class Foo: 45 def __eq__(self, other): 46 return False 47a = [1, 2, 3] 48result = list.__eq__(a, a) 49)") 50 .isError()); 51 EXPECT_EQ(mainModuleAt(runtime_, "result"), RawBool::trueObj()); 52} 53 54TEST_F(ListBuiltinsTest, DunderEqWithSameIdentityElementsReturnsTrue) { 55 ASSERT_FALSE(runFromCStr(runtime_, R"( 56nan = float("nan") 57result = list.__eq__([nan], [nan]) 58)") 59 .isError()); 60 EXPECT_EQ(mainModuleAt(runtime_, "result"), RawBool::trueObj()); 61} 62 63TEST_F(ListBuiltinsTest, DunderEqWithEqualElementsReturnsTrue) { 64 ASSERT_FALSE(runFromCStr(runtime_, R"( 65class Foo: 66 def __init__(self, value): 67 self.value = value 68 def __eq__(self, other): 69 return type(self.value).__eq__(self.value, other.value) 70a = Foo(1) 71b = Foo(1) 72result = list.__eq__([a], [b]) 73)") 74 .isError()); 75 EXPECT_EQ(mainModuleAt(runtime_, "result"), RawBool::trueObj()); 76} 77 78TEST_F(ListBuiltinsTest, DunderEqWithDifferentSizeReturnsFalse) { 79 ASSERT_FALSE(runFromCStr(runtime_, R"( 80result = list.__eq__([1, 2, 3], [1, 2]) 81)") 82 .isError()); 83 EXPECT_EQ(mainModuleAt(runtime_, "result"), RawBool::falseObj()); 84} 85 86TEST_F(ListBuiltinsTest, DunderEqWithDifferentValuesReturnsFalse) { 87 ASSERT_FALSE(runFromCStr(runtime_, R"( 88result = list.__eq__([1, 2, 3], [1, 2, 4]) 89)") 90 .isError()); 91 EXPECT_EQ(mainModuleAt(runtime_, "result"), RawBool::falseObj()); 92} 93 94TEST_F(ListBuiltinsTest, DunderEqWithNonListRhsReturnsNotImplemented) { 95 ASSERT_FALSE(runFromCStr(runtime_, R"( 96result = list.__eq__([1, 2, 3], (1, 2, 3)); 97)") 98 .isError()); 99 EXPECT_TRUE(mainModuleAt(runtime_, "result").isNotImplementedType()); 100} 101 102TEST_F(ListBuiltinsTest, DunderInitFromList) { 103 ASSERT_FALSE(runFromCStr(runtime_, R"( 104a = list([1, 2]) 105)") 106 .isError()); 107 HandleScope scope(thread_); 108 List a(&scope, mainModuleAt(runtime_, "a")); 109 ASSERT_EQ(a.numItems(), 2); 110 EXPECT_TRUE(isIntEqualsWord(a.at(0), 1)); 111 EXPECT_TRUE(isIntEqualsWord(a.at(1), 2)); 112} 113 114TEST_F(ListBuiltinsTest, NewListIsNotASingleton) { 115 ASSERT_FALSE(runFromCStr(runtime_, R"( 116a = list() is not list() 117b = list([1, 2]) is not list([1, 2]) 118)") 119 .isError()); 120 HandleScope scope(thread_); 121 Bool a(&scope, mainModuleAt(runtime_, "a")); 122 Bool b(&scope, mainModuleAt(runtime_, "b")); 123 EXPECT_TRUE(a.value()); 124 EXPECT_TRUE(b.value()); 125} 126 127TEST_F(ListBuiltinsTest, AddToNonEmptyList) { 128 HandleScope scope(thread_); 129 130 ASSERT_FALSE(runFromCStr(runtime_, R"( 131a = [1, 2] 132b = [3, 4, 5] 133c = a + b 134)") 135 .isError()); 136 Object c(&scope, mainModuleAt(runtime_, "c")); 137 ASSERT_TRUE(c.isList()); 138 List list(&scope, List::cast(*c)); 139 EXPECT_TRUE(isIntEqualsWord(list.at(0), 1)); 140 EXPECT_TRUE(isIntEqualsWord(list.at(1), 2)); 141 EXPECT_TRUE(isIntEqualsWord(list.at(2), 3)); 142 EXPECT_TRUE(isIntEqualsWord(list.at(3), 4)); 143 EXPECT_TRUE(isIntEqualsWord(list.at(4), 5)); 144} 145 146TEST_F(ListBuiltinsTest, AddToEmptyList) { 147 HandleScope scope(thread_); 148 149 ASSERT_FALSE(runFromCStr(runtime_, R"( 150a = [] 151b = [1, 2, 3] 152c = a + b 153)") 154 .isError()); 155 Object c(&scope, mainModuleAt(runtime_, "c")); 156 ASSERT_TRUE(c.isList()); 157 List list(&scope, List::cast(*c)); 158 EXPECT_TRUE(isIntEqualsWord(list.at(0), 1)); 159 EXPECT_TRUE(isIntEqualsWord(list.at(1), 2)); 160 EXPECT_TRUE(isIntEqualsWord(list.at(2), 3)); 161} 162 163TEST_F(ListBuiltinsTest, AddWithListSubclassReturnsList) { 164 HandleScope scope(thread_); 165 ASSERT_FALSE(runFromCStr(runtime_, R"( 166class C(list): 167 pass 168a = [] 169b = C([1, 2, 3]) 170c = a + b 171)") 172 .isError()); 173 Object c(&scope, mainModuleAt(runtime_, "c")); 174 EXPECT_PYLIST_EQ(c, {1, 2, 3}); 175} 176 177TEST_F(ListBuiltinsTest, AddListToTupleRaisesTypeError) { 178 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 179a = [1, 2, 3] 180b = (4, 5, 6) 181c = a + b 182)"), 183 LayoutId::kTypeError, 184 "can only concatenate list to list")); 185} 186 187TEST_F(ListBuiltinsTest, DunderContainsWithContainedElementReturnsTrue) { 188 HandleScope scope(thread_); 189 Int value0(&scope, runtime_->newInt(1)); 190 Bool value1(&scope, RawBool::falseObj()); 191 Str value2(&scope, runtime_->newStrFromCStr("hello")); 192 List list(&scope, runtime_->newList()); 193 runtime_->listAdd(thread_, list, value0); 194 runtime_->listAdd(thread_, list, value1); 195 runtime_->listAdd(thread_, list, value2); 196 EXPECT_EQ(runBuiltin(METH(list, __contains__), list, value0), 197 RawBool::trueObj()); 198 EXPECT_EQ(runBuiltin(METH(list, __contains__), list, value1), 199 RawBool::trueObj()); 200 EXPECT_EQ(runBuiltin(METH(list, __contains__), list, value2), 201 RawBool::trueObj()); 202} 203 204TEST_F(ListBuiltinsTest, DunderContainsWithUncontainedElementReturnsFalse) { 205 HandleScope scope(thread_); 206 Int value0(&scope, runtime_->newInt(7)); 207 NoneType value1(&scope, RawNoneType::object()); 208 List list(&scope, runtime_->newList()); 209 runtime_->listAdd(thread_, list, value0); 210 runtime_->listAdd(thread_, list, value1); 211 Int value2(&scope, runtime_->newInt(42)); 212 Bool value3(&scope, RawBool::trueObj()); 213 EXPECT_EQ(runBuiltin(METH(list, __contains__), list, value2), 214 RawBool::falseObj()); 215 EXPECT_EQ(runBuiltin(METH(list, __contains__), list, value3), 216 RawBool::falseObj()); 217} 218 219TEST_F(ListBuiltinsTest, DunderContainsWithIdenticalObjectReturnsTrue) { 220 HandleScope scope(thread_); 221 ASSERT_FALSE(runFromCStr(runtime_, R"( 222class Foo: 223 def __eq__(self, other): 224 return False 225value = Foo() 226list = [value] 227)") 228 .isError()); 229 Object value(&scope, mainModuleAt(runtime_, "value")); 230 List list(&scope, mainModuleAt(runtime_, "list")); 231 EXPECT_EQ(runBuiltin(METH(list, __contains__), list, value), 232 RawBool::trueObj()); 233} 234 235TEST_F(ListBuiltinsTest, 236 DunderContainsWithNonIdenticalEqualKeyObjectReturnsTrue) { 237 HandleScope scope(thread_); 238 ASSERT_FALSE(runFromCStr(runtime_, R"( 239class Foo: 240 def __eq__(self, other): 241 return True 242value = Foo() 243list = [None] 244)") 245 .isError()); 246 Object value(&scope, mainModuleAt(runtime_, "value")); 247 List list(&scope, mainModuleAt(runtime_, "list")); 248 EXPECT_EQ(runBuiltin(METH(list, __contains__), list, value), 249 RawBool::trueObj()); 250} 251 252TEST_F(ListBuiltinsTest, 253 DunderContainsWithNonIdenticalEqualListObjectReturnsFalse) { 254 HandleScope scope(thread_); 255 ASSERT_FALSE(runFromCStr(runtime_, R"( 256class Foo: 257 def __eq__(self, other): 258 return True 259class Bar: 260 def __eq__(self, other): 261 return False 262value0 = Foo() 263value1 = Bar() 264list = [value0] 265)") 266 .isError()); 267 Object value1(&scope, mainModuleAt(runtime_, "value1")); 268 List list(&scope, mainModuleAt(runtime_, "list")); 269 EXPECT_EQ(runBuiltin(METH(list, __contains__), list, value1), 270 RawBool::falseObj()); 271} 272 273TEST_F(ListBuiltinsTest, DunderContainsWithRaisingEqPropagatesException) { 274 HandleScope scope(thread_); 275 ASSERT_FALSE(runFromCStr(runtime_, R"( 276class Foo: 277 def __eq__(self, other): 278 raise UserWarning("") 279value = Foo() 280list = [None] 281)") 282 .isError()); 283 Object value(&scope, mainModuleAt(runtime_, "value")); 284 List list(&scope, mainModuleAt(runtime_, "list")); 285 Object result(&scope, runBuiltin(METH(list, __contains__), list, value)); 286 EXPECT_TRUE(raised(*result, LayoutId::kUserWarning)); 287} 288 289TEST_F(ListBuiltinsTest, 290 DunderContainsWithRaisingDunderBoolPropagatesException) { 291 HandleScope scope(thread_); 292 ASSERT_FALSE(runFromCStr(runtime_, R"( 293class Foo: 294 def __bool__(self): 295 raise UserWarning("") 296class Bar: 297 def __eq__(self, other): 298 return Foo() 299value = Bar() 300list = [None] 301)") 302 .isError()); 303 Object value(&scope, mainModuleAt(runtime_, "value")); 304 List list(&scope, mainModuleAt(runtime_, "list")); 305 EXPECT_TRUE(raised(runBuiltin(METH(list, __contains__), list, value), 306 LayoutId::kUserWarning)); 307} 308 309TEST_F(ListBuiltinsTest, DunderContainsWithNonListSelfRaisesTypeError) { 310 HandleScope scope(thread_); 311 Int i(&scope, SmallInt::fromWord(3)); 312 Object result(&scope, runBuiltin(METH(list, __contains__), i, i)); 313 EXPECT_TRUE(raised(*result, LayoutId::kTypeError)); 314} 315 316TEST_F(ListBuiltinsTest, ListInsertWithMissingArgumentsRaisesTypeError) { 317 EXPECT_TRUE(raisedWithStr( 318 runFromCStr(runtime_, "[1, 2].insert()"), LayoutId::kTypeError, 319 "'list.insert' takes min 3 positional arguments but 1 given")); 320} 321 322TEST_F(ListBuiltinsTest, ListInsertWithNonIntIndexRaisesTypeError) { 323 EXPECT_TRUE(raisedWithStr( 324 runFromCStr(runtime_, "[1, 2].insert({}, 3)"), LayoutId::kTypeError, 325 "'dict' object cannot be interpreted as an integer")); 326} 327 328TEST_F(ListBuiltinsTest, ListInsertWithLargeIntIndexRaisesTypeError) { 329 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "[1, 2].insert(2 ** 63, 1)"), 330 LayoutId::kOverflowError, 331 "Python int too large to convert to C ssize_t")); 332} 333 334TEST_F(ListBuiltinsTest, ListInsertWithBoolIndexInsertsAtInt) { 335 HandleScope scope(thread_); 336 List self(&scope, runtime_->newList()); 337 Object value(&scope, SmallInt::fromWord(3)); 338 runtime_->listAdd(thread_, self, value); 339 runtime_->listAdd(thread_, self, value); 340 Object fals(&scope, Bool::falseObj()); 341 Object tru(&scope, Bool::trueObj()); 342 Object result(&scope, runBuiltin(METH(list, insert), self, tru, tru)); 343 EXPECT_EQ(result, NoneType::object()); 344 result = runBuiltin(METH(list, insert), self, fals, fals); 345 EXPECT_EQ(result, NoneType::object()); 346 ASSERT_EQ(self.numItems(), 4); 347 EXPECT_EQ(self.at(0), fals); 348 EXPECT_EQ(self.at(1), value); 349 EXPECT_EQ(self.at(2), tru); 350 EXPECT_EQ(self.at(3), value); 351} 352 353TEST_F(ListBuiltinsTest, ListInsertWithIntSubclassInsertsAtInt) { 354 ASSERT_FALSE(runFromCStr(runtime_, R"( 355class N(int): 356 pass 357a = [0, 0, 0, 0, 0] 358b = N(3) 359)") 360 .isError()); 361 HandleScope scope(thread_); 362 List self(&scope, mainModuleAt(runtime_, "a")); 363 Object index(&scope, mainModuleAt(runtime_, "b")); 364 Object value(&scope, SmallInt::fromWord(1)); 365 Object result(&scope, runBuiltin(METH(list, insert), self, index, value)); 366 EXPECT_EQ(result, NoneType::object()); 367 EXPECT_EQ(self.numItems(), 6); 368 EXPECT_EQ(self.at(3), value); 369} 370 371TEST_F(ListBuiltinsTest, ListRemove) { 372 ASSERT_FALSE(runFromCStr(runtime_, R"( 373a = [5, 4, 3, 2, 1] 374a.remove(2) 375a.remove(5) 376)") 377 .isError()); 378 HandleScope scope(thread_); 379 Object a(&scope, mainModuleAt(runtime_, "a")); 380 EXPECT_PYLIST_EQ(a, {4, 3, 1}); 381} 382 383TEST_F(ListBuiltinsTest, ListRemoveWithDuplicateItemsRemovesFirstMatchingItem) { 384 HandleScope scope(thread_); 385 Int value0(&scope, runtime_->newInt(0)); 386 Int value1(&scope, runtime_->newInt(1)); 387 Int value2(&scope, runtime_->newInt(2)); 388 List list(&scope, runtime_->newList()); 389 runtime_->listAdd(thread_, list, value0); 390 runtime_->listAdd(thread_, list, value1); 391 runtime_->listAdd(thread_, list, value2); 392 runtime_->listAdd(thread_, list, value1); 393 runtime_->listAdd(thread_, list, value0); 394 395 EXPECT_EQ(list.numItems(), 5); 396 runBuiltin(METH(list, remove), list, value1); 397 ASSERT_EQ(list.numItems(), 4); 398 EXPECT_EQ(list.at(0), value0); 399 EXPECT_EQ(list.at(1), value2); 400 EXPECT_EQ(list.at(2), value1); 401 EXPECT_EQ(list.at(3), value0); 402} 403 404TEST_F(ListBuiltinsTest, ListRemoveWithIdenticalObjectGetsRemoved) { 405 HandleScope scope(thread_); 406 ASSERT_FALSE(runFromCStr(runtime_, R"( 407class C: 408 def __eq__(self, other): 409 return False 410value = C() 411list = [value] 412)") 413 .isError()); 414 Object value(&scope, mainModuleAt(runtime_, "value")); 415 List list(&scope, mainModuleAt(runtime_, "list")); 416 EXPECT_EQ(list.numItems(), 1); 417 runBuiltin(METH(list, remove), list, value); 418 EXPECT_EQ(list.numItems(), 0); 419} 420 421TEST_F(ListBuiltinsTest, 422 ListRemoveWithNonIdenticalEqualObjectInListGetsRemoved) { 423 HandleScope scope(thread_); 424 ASSERT_FALSE(runFromCStr(runtime_, R"( 425class C: 426 def __eq__(self, other): 427 return True 428list = [C()] 429)") 430 .isError()); 431 Object value(&scope, NoneType::object()); 432 List list(&scope, mainModuleAt(runtime_, "list")); 433 EXPECT_EQ(list.numItems(), 1); 434 runBuiltin(METH(list, remove), list, value); 435 EXPECT_EQ(list.numItems(), 0); 436} 437 438TEST_F(ListBuiltinsTest, 439 ListRemoveWithNonIdenticalEqualObjectAsKeyRaisesValueError) { 440 HandleScope scope(thread_); 441 ASSERT_FALSE(runFromCStr(runtime_, R"( 442class C: 443 def __eq__(self, other): 444 return True 445class D: 446 def __eq__(self, other): 447 return False 448value = C() 449list = [D()] 450)") 451 .isError()); 452 Object value(&scope, mainModuleAt(runtime_, "value")); 453 List list(&scope, mainModuleAt(runtime_, "list")); 454 Object result(&scope, runBuiltin(METH(list, remove), list, value)); 455 EXPECT_TRUE(raised(*result, LayoutId::kValueError)); 456} 457 458TEST_F(ListBuiltinsTest, ListRemoveWithRaisingDunderEqualPropagatesException) { 459 HandleScope scope(thread_); 460 ASSERT_FALSE(runFromCStr(runtime_, R"( 461class Foo: 462 def __eq__(self, other): 463 raise UserWarning('') 464value = Foo() 465list = [None] 466)") 467 .isError()); 468 Object value(&scope, mainModuleAt(runtime_, "value")); 469 List list(&scope, mainModuleAt(runtime_, "list")); 470 Object result(&scope, runBuiltin(METH(list, remove), list, value)); 471 EXPECT_TRUE(raised(*result, LayoutId::kUserWarning)); 472} 473 474TEST_F(ListBuiltinsTest, ListRemoveWithRaisingDunderBoolPropagatesException) { 475 HandleScope scope(thread_); 476 ASSERT_FALSE(runFromCStr(runtime_, R"( 477class C: 478 def __bool__(self): 479 raise UserWarning('foo') 480class D: 481 def __eq__(self, other): 482 return C() 483value = D() 484list = [None] 485)") 486 .isError()); 487 Object value(&scope, mainModuleAt(runtime_, "value")); 488 List list(&scope, mainModuleAt(runtime_, "list")); 489 EXPECT_TRUE(raisedWithStr(runBuiltin(METH(list, remove), list, value), 490 LayoutId::kUserWarning, "foo")); 491} 492 493TEST_F(ListBuiltinsTest, ReplicateList) { 494 ASSERT_FALSE(runFromCStr(runtime_, R"( 495result = [1, 2, 3] * 3 496)") 497 .isError()); 498 HandleScope scope(thread_); 499 Object result(&scope, mainModuleAt(runtime_, "result")); 500 EXPECT_PYLIST_EQ(result, {1, 2, 3, 1, 2, 3, 1, 2, 3}); 501} 502 503TEST_F(ListBuiltinsTest, ReplicateListWithNegativeRhsReturnsEmptyList) { 504 ASSERT_FALSE(runFromCStr(runtime_, R"( 505result = [1, 2, 3] * -3 506)") 507 .isError()); 508 HandleScope scope(thread_); 509 Object result(&scope, mainModuleAt(runtime_, "result")); 510 EXPECT_PYLIST_EQ(result, {}); 511} 512 513TEST_F(ListBuiltinsTest, SliceWithPositiveStepReturnsForwardsList) { 514 HandleScope scope(thread_); 515 List list1(&scope, listFromRange(1, 6)); 516 517 // Test [2:] 518 List test(&scope, listSlice(thread_, list1, 2, 5, 1)); 519 ASSERT_EQ(test.numItems(), 3); 520 EXPECT_TRUE(isIntEqualsWord(test.at(0), 3)); 521 EXPECT_TRUE(isIntEqualsWord(test.at(1), 4)); 522 EXPECT_TRUE(isIntEqualsWord(test.at(2), 5)); 523} 524 525TEST_F(ListBuiltinsTest, SliceWithNegativeStepReturnsBackwardsList) { 526 HandleScope scope(thread_); 527 List list1(&scope, listFromRange(1, 6)); 528 529 // Test [::-2] 530 List test(&scope, listSlice(thread_, list1, 4, -1, -2)); 531 ASSERT_EQ(test.numItems(), 3); 532 EXPECT_TRUE(isIntEqualsWord(test.at(0), 5)); 533 EXPECT_TRUE(isIntEqualsWord(test.at(1), 3)); 534 EXPECT_TRUE(isIntEqualsWord(test.at(2), 1)); 535} 536 537TEST_F(ListBuiltinsTest, IdenticalSliceIsCopy) { 538 HandleScope scope(thread_); 539 List list1(&scope, listFromRange(1, 6)); 540 541 // Test: t[::] is t 542 List test(&scope, listSlice(thread_, list1, 0, 5, 1)); 543 ASSERT_EQ(test.numItems(), 5); 544 EXPECT_TRUE(isIntEqualsWord(test.at(0), 1)); 545 EXPECT_TRUE(isIntEqualsWord(test.at(4), 5)); 546 ASSERT_NE(*test, *list1); 547} 548 549TEST_F(ListBuiltinsTest, DelitemWithInvalidNegativeIndexRaisesIndexError) { 550 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 551l = [1, 2, 3] 552del l[-4] 553)"), 554 LayoutId::kIndexError, 555 "list assignment index out of range")); 556} 557 558TEST_F(ListBuiltinsTest, DelitemWithInvalidIndexRaisesIndexError) { 559 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 560l = [1, 2, 3] 561del l[5] 562)"), 563 LayoutId::kIndexError, 564 "list assignment index out of range")); 565} 566 567TEST_F(ListBuiltinsTest, DelitemWithTooFewArgumentsRaisesTypeError) { 568 EXPECT_TRUE(raisedWithStr( 569 runFromCStr(runtime_, R"( 570[].__delitem__() 571)"), 572 LayoutId::kTypeError, 573 "'list.__delitem__' takes min 2 positional arguments but 1 given")); 574} 575 576TEST_F(ListBuiltinsTest, DelitemWithTooManyArgumentsRaisesTypeError) { 577 EXPECT_TRUE(raisedWithStr( 578 runFromCStr(runtime_, R"( 579[].__delitem__(1, 2) 580)"), 581 LayoutId::kTypeError, 582 "'list.__delitem__' takes max 2 positional arguments but 3 given")); 583} 584 585TEST_F(ListBuiltinsTest, DelitemWithNonIntegralIndexRaisesTypeError) { 586 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 587[].__delitem__("test") 588)"), 589 LayoutId::kTypeError, 590 "list indices must be integers or slices")); 591} 592 593TEST_F(ListBuiltinsTest, NonTypeInDunderNew) { 594 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 595list.__new__(1) 596)"), 597 LayoutId::kTypeError, "not a type object")); 598} 599 600TEST_F(ListBuiltinsTest, NonSubclassInDunderNew) { 601 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 602class Foo: pass 603list.__new__(Foo) 604)"), 605 LayoutId::kTypeError, "not a subtype of list")); 606} 607 608TEST_F(ListBuiltinsTest, SubclassList) { 609 HandleScope scope(thread_); 610 ASSERT_FALSE(runFromCStr(runtime_, R"( 611class Foo(): 612 def __init__(self): 613 self.a = "a" 614class Bar(Foo, list): pass 615a = Bar() 616a.append(1) 617test1, test2 = a[0], a.a 618a.insert(0, 2) 619test3, test4 = a[0], a[1] 620a.pop() 621test5 = a[0] 622a.remove(2) 623test6 = len(a) 624)") 625 .isError()); 626 Object test1(&scope, mainModuleAt(runtime_, "test1")); 627 Object test2(&scope, mainModuleAt(runtime_, "test2")); 628 Object test3(&scope, mainModuleAt(runtime_, "test3")); 629 Object test4(&scope, mainModuleAt(runtime_, "test4")); 630 Object test5(&scope, mainModuleAt(runtime_, "test5")); 631 Object test6(&scope, mainModuleAt(runtime_, "test6")); 632 EXPECT_EQ(*test1, SmallInt::fromWord(1)); 633 EXPECT_EQ(*test2, SmallStr::fromCStr("a")); 634 EXPECT_EQ(*test3, SmallInt::fromWord(2)); 635 EXPECT_EQ(*test4, SmallInt::fromWord(1)); 636 EXPECT_EQ(*test5, SmallInt::fromWord(2)); 637 EXPECT_EQ(*test6, SmallInt::fromWord(0)); 638} 639 640TEST_F(ListBuiltinsTest, Delitem) { 641 HandleScope scope(thread_); 642 ASSERT_FALSE(runFromCStr(runtime_, R"( 643a = [42,'foo', 'bar'] 644del a[2] 645del a[0] 646l = len(a) 647e = a[0] 648)") 649 .isError()); 650 Object len(&scope, mainModuleAt(runtime_, "l")); 651 Object element(&scope, mainModuleAt(runtime_, "e")); 652 EXPECT_EQ(*len, SmallInt::fromWord(1)); 653 EXPECT_EQ(*element, SmallStr::fromCStr("foo")); 654} 655 656TEST_F(ListBuiltinsTest, DunderIterReturnsListIter) { 657 HandleScope scope(thread_); 658 List empty_list(&scope, listFromRange(0, 0)); 659 Object iter(&scope, runBuiltin(METH(list, __iter__), empty_list)); 660 ASSERT_TRUE(iter.isListIterator()); 661} 662 663TEST_F(ListIteratorBuiltinsTest, CallDunderNext) { 664 HandleScope scope(thread_); 665 List empty_list(&scope, listFromRange(0, 2)); 666 Object iter(&scope, runBuiltin(METH(list, __iter__), empty_list)); 667 ASSERT_TRUE(iter.isListIterator()); 668 669 Object item1(&scope, runBuiltin(METH(list_iterator, __next__), iter)); 670 EXPECT_TRUE(isIntEqualsWord(*item1, 0)); 671 672 Object item2(&scope, runBuiltin(METH(list_iterator, __next__), iter)); 673 EXPECT_TRUE(isIntEqualsWord(*item2, 1)); 674} 675 676TEST_F(ListIteratorBuiltinsTest, DunderIterReturnsSelf) { 677 HandleScope scope(thread_); 678 List empty_list(&scope, listFromRange(0, 0)); 679 Object iter(&scope, runBuiltin(METH(list, __iter__), empty_list)); 680 ASSERT_TRUE(iter.isListIterator()); 681 682 // Now call __iter__ on the iterator object 683 Object result(&scope, runBuiltin(METH(list_iterator, __iter__), iter)); 684 ASSERT_EQ(*result, *iter); 685} 686 687TEST_F(ListIteratorBuiltinsTest, DunderLengthHintOnEmptyListIterator) { 688 HandleScope scope(thread_); 689 List empty_list(&scope, listFromRange(0, 0)); 690 Object iter(&scope, runBuiltin(METH(list, __iter__), empty_list)); 691 ASSERT_TRUE(iter.isListIterator()); 692 693 Object length_hint(&scope, 694 runBuiltin(METH(list_iterator, __length_hint__), iter)); 695 EXPECT_TRUE(isIntEqualsWord(*length_hint, 0)); 696} 697 698TEST_F(ListIteratorBuiltinsTest, DunderLengthHintOnConsumedListIterator) { 699 HandleScope scope(thread_); 700 List list(&scope, listFromRange(0, 1)); 701 Object iter(&scope, runBuiltin(METH(list, __iter__), list)); 702 ASSERT_TRUE(iter.isListIterator()); 703 704 Object length_hint1(&scope, 705 runBuiltin(METH(list_iterator, __length_hint__), iter)); 706 EXPECT_TRUE(isIntEqualsWord(*length_hint1, 1)); 707 708 // Consume the iterator 709 Object item1(&scope, runBuiltin(METH(list_iterator, __next__), iter)); 710 EXPECT_TRUE(isIntEqualsWord(*item1, 0)); 711 712 Object length_hint2(&scope, 713 runBuiltin(METH(list_iterator, __length_hint__), iter)); 714 EXPECT_TRUE(isIntEqualsWord(*length_hint2, 0)); 715} 716 717TEST_F(ListBuiltinsTest, InsertToList) { 718 HandleScope scope(thread_); 719 List list(&scope, runtime_->newList()); 720 721 for (int i = 0; i < 9; i++) { 722 if (i == 1 || i == 6) { 723 continue; 724 } 725 Object value(&scope, SmallInt::fromWord(i)); 726 runtime_->listAdd(thread_, list, value); 727 } 728 EXPECT_FALSE(isIntEqualsWord(list.at(1), 1)); 729 EXPECT_FALSE(isIntEqualsWord(list.at(6), 6)); 730 731 Object value2(&scope, SmallInt::fromWord(1)); 732 listInsert(thread_, list, value2, 1); 733 Object value12(&scope, SmallInt::fromWord(6)); 734 listInsert(thread_, list, value12, 6); 735 736 EXPECT_PYLIST_EQ(list, {0, 1, 2, 3, 4, 5, 6, 7, 8}); 737} 738 739TEST_F(ListBuiltinsTest, InsertToListBounds) { 740 HandleScope scope(thread_); 741 List list(&scope, runtime_->newList()); 742 for (int i = 0; i < 10; i++) { 743 Object value(&scope, SmallInt::fromWord(i)); 744 runtime_->listAdd(thread_, list, value); 745 } 746 ASSERT_EQ(list.numItems(), 10); 747 748 Object value100(&scope, SmallInt::fromWord(100)); 749 listInsert(thread_, list, value100, 100); 750 ASSERT_EQ(list.numItems(), 11); 751 EXPECT_TRUE(isIntEqualsWord(list.at(10), 100)); 752 753 Object value0(&scope, SmallInt::fromWord(400)); 754 listInsert(thread_, list, value0, 0); 755 ASSERT_EQ(list.numItems(), 12); 756 EXPECT_TRUE(isIntEqualsWord(list.at(0), 400)); 757 758 Object value_n(&scope, SmallInt::fromWord(-10)); 759 listInsert(thread_, list, value_n, -10); 760 ASSERT_EQ(list.numItems(), 13); 761 EXPECT_TRUE(isIntEqualsWord(list.at(2), -10)); 762} 763 764TEST_F(ListBuiltinsTest, PopList) { 765 HandleScope scope(thread_); 766 List list(&scope, runtime_->newList()); 767 for (int i = 0; i < 16; i++) { 768 Object value(&scope, SmallInt::fromWord(i)); 769 runtime_->listAdd(thread_, list, value); 770 } 771 ASSERT_EQ(list.numItems(), 16); 772 773 // Pop from the end 774 RawObject res1 = listPop(thread_, list, 15); 775 ASSERT_EQ(list.numItems(), 15); 776 EXPECT_TRUE(isIntEqualsWord(list.at(14), 14)); 777 EXPECT_TRUE(isIntEqualsWord(res1, 15)); 778 779 // Pop elements from 5 - 10 780 for (int i = 0; i < 5; i++) { 781 RawObject res5 = listPop(thread_, list, 5); 782 EXPECT_TRUE(isIntEqualsWord(res5, i + 5)); 783 } 784 ASSERT_EQ(list.numItems(), 10); 785 for (int i = 0; i < 5; i++) { 786 EXPECT_TRUE(isIntEqualsWord(list.at(i), i)); 787 } 788 for (int i = 5; i < 10; i++) { 789 EXPECT_TRUE(isIntEqualsWord(list.at(i), i + 5)); 790 } 791 792 // Pop element 0 793 RawObject res0 = listPop(thread_, list, 0); 794 ASSERT_EQ(list.numItems(), 9); 795 EXPECT_TRUE(isIntEqualsWord(list.at(0), 1)); 796 EXPECT_TRUE(isIntEqualsWord(res0, 0)); 797} 798 799TEST_F(ListBuiltinsTest, ExtendTuple) { 800 HandleScope scope(thread_); 801 List list(&scope, runtime_->newList()); 802 Tuple object_array0(&scope, runtime_->emptyTuple()); 803 804 for (int i = 0; i < 4; i++) { 805 Object value(&scope, SmallInt::fromWord(i)); 806 runtime_->listAdd(thread_, list, value); 807 } 808 listExtend(Thread::current(), list, object_array0, 0); 809 EXPECT_EQ(list.numItems(), 4); 810 811 Object none(&scope, NoneType::object()); 812 Tuple object_array1(&scope, runtime_->newTupleWith1(none)); 813 listExtend(Thread::current(), list, object_array1, 1); 814 ASSERT_GE(list.numItems(), 5); 815 ASSERT_TRUE(list.at(4).isNoneType()); 816 817 MutableTuple object_array16(&scope, runtime_->newMutableTuple(16)); 818 for (word i = 0; i < 4; i++) { 819 object_array16.atPut(i, SmallInt::fromWord(i)); 820 } 821 Tuple object_array_immutable(&scope, object_array16.becomeImmutable()); 822 823 listExtend(Thread::current(), list, object_array_immutable, 4); 824 ASSERT_GE(list.numItems(), 9); 825 EXPECT_EQ(list.at(5), SmallInt::fromWord(0)); 826 EXPECT_EQ(list.at(6), SmallInt::fromWord(1)); 827 EXPECT_EQ(list.at(7), SmallInt::fromWord(2)); 828 EXPECT_EQ(list.at(8), SmallInt::fromWord(3)); 829} 830 831TEST_F(ListBuiltinsTest, SortEmptyListSucceeds) { 832 HandleScope scope(thread_); 833 List empty(&scope, runtime_->newList()); 834 ASSERT_EQ(listSort(thread_, empty), NoneType::object()); 835} 836 837TEST_F(ListBuiltinsTest, SortSingleElementListSucceeds) { 838 HandleScope scope(thread_); 839 List list(&scope, runtime_->newList()); 840 Object elt(&scope, SmallInt::fromWord(5)); 841 runtime_->listAdd(thread_, list, elt); 842 ASSERT_EQ(listSort(thread_, list), NoneType::object()); 843 EXPECT_EQ(list.numItems(), 1); 844 EXPECT_EQ(list.at(0), *elt); 845} 846 847TEST_F(ListBuiltinsTest, SortMultiElementListSucceeds) { 848 HandleScope scope(thread_); 849 List list(&scope, runtime_->newList()); 850 Object elt3(&scope, SmallInt::fromWord(3)); 851 runtime_->listAdd(thread_, list, elt3); 852 Object elt2(&scope, SmallInt::fromWord(2)); 853 runtime_->listAdd(thread_, list, elt2); 854 Object elt1(&scope, SmallInt::fromWord(1)); 855 runtime_->listAdd(thread_, list, elt1); 856 ASSERT_EQ(listSort(thread_, list), NoneType::object()); 857 EXPECT_EQ(list.numItems(), 3); 858 EXPECT_PYLIST_EQ(list, {1, 2, 3}); 859} 860 861TEST_F(ListBuiltinsTest, SortMultiElementListSucceeds2) { 862 HandleScope scope(thread_); 863 List list(&scope, runtime_->newList()); 864 Object elt3(&scope, SmallInt::fromWord(1)); 865 runtime_->listAdd(thread_, list, elt3); 866 Object elt2(&scope, SmallInt::fromWord(3)); 867 runtime_->listAdd(thread_, list, elt2); 868 Object elt1(&scope, SmallInt::fromWord(2)); 869 runtime_->listAdd(thread_, list, elt1); 870 ASSERT_EQ(listSort(thread_, list), NoneType::object()); 871 EXPECT_EQ(list.numItems(), 3); 872 EXPECT_PYLIST_EQ(list, {1, 2, 3}); 873} 874 875TEST_F(ListBuiltinsTest, SortIsStable) { 876 HandleScope scope(thread_); 877 List list(&scope, runtime_->newList()); 878 Object elt4(&scope, runtime_->newStrFromCStr("q")); 879 runtime_->listAdd(thread_, list, elt4); 880 Object elt3(&scope, runtime_->newStrFromCStr("world")); 881 runtime_->listAdd(thread_, list, elt3); 882 Object elt2(&scope, runtime_->newStrFromCStr("hello")); 883 runtime_->listAdd(thread_, list, elt2); 884 Object elt1(&scope, runtime_->newStrFromCStr("hello")); 885 runtime_->listAdd(thread_, list, elt1); 886 ASSERT_EQ(listSort(thread_, list), NoneType::object()); 887 EXPECT_EQ(list.numItems(), 4); 888 EXPECT_EQ(list.at(0), *elt2); 889 EXPECT_EQ(list.at(1), *elt1); 890 EXPECT_EQ(list.at(2), *elt4); 891 EXPECT_EQ(list.at(3), *elt3); 892} 893 894TEST_F(ListBuiltinsTest, ListExtendSelfDuplicatesElements) { 895 ASSERT_FALSE(runFromCStr(runtime_, R"( 896a = [1, 2, 3] 897a.extend(a) 898)") 899 .isError()); 900 HandleScope scope(thread_); 901 List a(&scope, mainModuleAt(runtime_, "a")); 902 ASSERT_EQ(a.numItems(), 6); 903 EXPECT_PYLIST_EQ(a, {1, 2, 3, 1, 2, 3}); 904} 905 906TEST_F(ListBuiltinsTest, ListExtendListSubclassFallsBackToIter) { 907 ASSERT_FALSE(runFromCStr(runtime_, R"( 908class C(list): 909 def __iter__(self): 910 return [4, 5, 6].__iter__() 911a = [1, 2, 3] 912a.extend(C([1,2,3])) 913)") 914 .isError()); 915 HandleScope scope(thread_); 916 List a(&scope, mainModuleAt(runtime_, "a")); 917 ASSERT_EQ(a.numItems(), 6); 918 EXPECT_PYLIST_EQ(a, {1, 2, 3, 4, 5, 6}); 919} 920 921TEST_F(ListBuiltinsTest, ReverseEmptyListDoesNothing) { 922 ASSERT_FALSE(runFromCStr(runtime_, R"( 923result = [] 924result.reverse() 925)") 926 .isError()); 927 HandleScope scope(thread_); 928 Object result(&scope, mainModuleAt(runtime_, "result")); 929 ASSERT_TRUE(result.isList()); 930 EXPECT_EQ(List::cast(*result).numItems(), 0); 931} 932 933TEST_F(ListBuiltinsTest, ReverseOneElementListDoesNothing) { 934 ASSERT_FALSE(runFromCStr(runtime_, R"( 935result = [2] 936result.reverse() 937)") 938 .isError()); 939 HandleScope scope(thread_); 940 Object result(&scope, mainModuleAt(runtime_, "result")); 941 ASSERT_TRUE(result.isList()); 942 EXPECT_EQ(List::cast(*result).numItems(), 1); 943 EXPECT_EQ(List::cast(*result).at(0), SmallInt::fromWord(2)); 944} 945 946TEST_F(ListBuiltinsTest, ReverseOddManyElementListReversesList) { 947 ASSERT_FALSE(runFromCStr(runtime_, R"( 948result = [1, 2, 3] 949result.reverse() 950)") 951 .isError()); 952 HandleScope scope(thread_); 953 Object result(&scope, mainModuleAt(runtime_, "result")); 954 EXPECT_PYLIST_EQ(result, {3, 2, 1}); 955} 956 957TEST_F(ListBuiltinsTest, ReverseEvenManyElementListReversesList) { 958 ASSERT_FALSE(runFromCStr(runtime_, R"( 959result = [1, 2, 3, 4] 960result.reverse() 961)") 962 .isError()); 963 HandleScope scope(thread_); 964 Object result(&scope, mainModuleAt(runtime_, "result")); 965 EXPECT_PYLIST_EQ(result, {4, 3, 2, 1}); 966} 967 968TEST_F(ListBuiltinsTest, ReverseWithListSubclassDoesNotCallSubclassMethods) { 969 ASSERT_FALSE(runFromCStr(runtime_, R"( 970class C(list): 971 def __getitem__(self, key): 972 raise Exception("hi") 973 def __setitem__(self, key, val): 974 raise Exception("hi") 975result = C([1, 2, 3, 4]) 976result.reverse() 977)") 978 .isError()); 979 EXPECT_FALSE(Thread::current()->hasPendingException()); 980} 981 982TEST_F(ListBuiltinsTest, SortWithMultiElementListSortsElements) { 983 ASSERT_FALSE(runFromCStr(runtime_, R"( 984ls = [3, 2, 1] 985ls.sort() 986)") 987 .isError()); 988 HandleScope scope(thread_); 989 Object ls(&scope, mainModuleAt(runtime_, "ls")); 990 EXPECT_PYLIST_EQ(ls, {1, 2, 3}); 991} 992 993TEST_F(ListBuiltinsTest, SortWithNonCallableKeyRaisesException) { 994 EXPECT_TRUE(raised(runFromCStr(runtime_, R"( 995ls = [3, 2, 1] 996ls.sort(key=5) 997)"), 998 LayoutId::kTypeError)); 999 ; 1000} 1001 1002TEST_F(ListBuiltinsTest, SortWithKeySortsAccordingToKey) { 1003 ASSERT_FALSE(runFromCStr(runtime_, R"( 1004ls = [2, 3, 1] 1005ls.sort(key=lambda x: -x) 1006)") 1007 .isError()); 1008 HandleScope scope(thread_); 1009 Object ls(&scope, mainModuleAt(runtime_, "ls")); 1010 EXPECT_PYLIST_EQ(ls, {3, 2, 1}); 1011} 1012 1013TEST_F(ListBuiltinsTest, SortReverseReversesSortedList) { 1014 ASSERT_FALSE(runFromCStr(runtime_, R"( 1015ls = [2, 3, 1] 1016ls.sort(reverse=True) 1017)") 1018 .isError()); 1019 HandleScope scope(thread_); 1020 Object ls(&scope, mainModuleAt(runtime_, "ls")); 1021 EXPECT_PYLIST_EQ(ls, {3, 2, 1}); 1022} 1023 1024TEST_F(ListBuiltinsTest, ClearRemovesElements) { 1025 ASSERT_FALSE(runFromCStr(runtime_, R"( 1026ls = [2, 3, 1] 1027list.clear(ls) 1028)") 1029 .isError()); 1030 HandleScope scope(thread_); 1031 Object ls(&scope, mainModuleAt(runtime_, "ls")); 1032 EXPECT_PYLIST_EQ(ls, {}); 1033} 1034 1035TEST_F(ListBuiltinsTest, ClearRemovesAllElements) { 1036 ASSERT_FALSE(runFromCStr(runtime_, R"( 1037class C: 1038 pass 1039l = [C()] 1040)") 1041 .isError()); 1042 1043 HandleScope scope(thread_); 1044 List list(&scope, mainModuleAt(runtime_, "l")); 1045 Object ref_obj(&scope, NoneType::object()); 1046 { 1047 Object c(&scope, list.at(0)); 1048 ref_obj = runtime_->newWeakRef(thread_, c); 1049 } 1050 WeakRef ref(&scope, *ref_obj); 1051 EXPECT_NE(ref.referent(), NoneType::object()); 1052 runBuiltin(METH(list, clear), list); 1053 runtime_->collectGarbage(); 1054 EXPECT_EQ(ref.referent(), NoneType::object()); 1055} 1056 1057} // namespace testing 1058} // namespace py