this repo has no description
at trunk 1479 lines 47 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "builtins-module.h" 3 4#include "gtest/gtest.h" 5 6#include "builtins.h" 7#include "dict-builtins.h" 8#include "module-builtins.h" 9#include "runtime.h" 10#include "str-builtins.h" 11#include "test-utils.h" 12#include "trampolines.h" 13 14namespace py { 15namespace testing { 16 17using BuiltinsModuleTest = RuntimeFixture; 18using BuiltinsModuleDeathTest = RuntimeFixture; 19 20TEST_F(BuiltinsModuleTest, BuiltinCallableOnTypeReturnsTrue) { 21 ASSERT_FALSE(runFromCStr(runtime_, R"( 22class Foo: 23 pass 24 25a = callable(Foo) 26 )") 27 .isError()); 28 HandleScope scope(thread_); 29 Bool a(&scope, mainModuleAt(runtime_, "a")); 30 EXPECT_TRUE(a.value()); 31} 32 33TEST_F(BuiltinsModuleTest, BuiltinCallableOnMethodReturnsTrue) { 34 ASSERT_FALSE(runFromCStr(runtime_, R"( 35class Foo: 36 def bar(): 37 return None 38 39a = callable(Foo.bar) 40b = callable(Foo().bar) 41 )") 42 .isError()); 43 HandleScope scope(thread_); 44 Bool a(&scope, mainModuleAt(runtime_, "a")); 45 Bool b(&scope, mainModuleAt(runtime_, "b")); 46 EXPECT_TRUE(a.value()); 47 EXPECT_TRUE(b.value()); 48} 49 50TEST_F(BuiltinsModuleTest, BuiltinCallableOnNonCallableReturnsFalse) { 51 ASSERT_FALSE(runFromCStr(runtime_, R"( 52a = callable(1) 53b = callable("hello") 54 )") 55 .isError()); 56 HandleScope scope(thread_); 57 Bool a(&scope, mainModuleAt(runtime_, "a")); 58 Bool b(&scope, mainModuleAt(runtime_, "b")); 59 EXPECT_FALSE(a.value()); 60 EXPECT_FALSE(b.value()); 61} 62 63TEST_F(BuiltinsModuleTest, BuiltinCallableOnObjectWithCallOnTypeReturnsTrue) { 64 ASSERT_FALSE(runFromCStr(runtime_, R"( 65class Foo: 66 def __call__(self): 67 pass 68 69f = Foo() 70a = callable(f) 71 )") 72 .isError()); 73 HandleScope scope(thread_); 74 Bool a(&scope, mainModuleAt(runtime_, "a")); 75 EXPECT_TRUE(a.value()); 76} 77 78TEST_F(BuiltinsModuleTest, 79 BuiltinCallableOnObjectWithInstanceCallButNoTypeCallReturnsFalse) { 80 ASSERT_FALSE(runFromCStr(runtime_, R"( 81class Foo: 82 pass 83 84def fakecall(): 85 pass 86 87f = Foo() 88f.__call__ = fakecall 89a = callable(f) 90 )") 91 .isError()); 92 HandleScope scope(thread_); 93 Bool a(&scope, mainModuleAt(runtime_, "a")); 94 EXPECT_FALSE(a.value()); 95} 96 97TEST_F(BuiltinsModuleTest, DirCallsDunderDirReturnsSortedList) { 98 HandleScope scope(thread_); 99 ASSERT_FALSE(runFromCStr(runtime_, R"( 100class C: 101 def __dir__(self): 102 return ["B", "A"] 103c = C() 104d = dir(c) 105)") 106 .isError()); 107 Object d_obj(&scope, mainModuleAt(runtime_, "d")); 108 ASSERT_TRUE(d_obj.isList()); 109 List d(&scope, *d_obj); 110 ASSERT_EQ(d.numItems(), 2); 111 EXPECT_TRUE(isStrEqualsCStr(d.at(0), "A")); 112 EXPECT_TRUE(isStrEqualsCStr(d.at(1), "B")); 113} 114 115TEST_F(BuiltinsModuleTest, EllipsisMatchesEllipsis) { 116 EXPECT_EQ(moduleAtByCStr(runtime_, "builtins", "Ellipsis"), 117 runtime_->ellipsis()); 118} 119 120TEST_F(BuiltinsModuleTest, IdReturnsInt) { 121 HandleScope scope(thread_); 122 Object obj(&scope, runtime_->newInt(12345)); 123 EXPECT_TRUE(runBuiltin(FUNC(builtins, id), obj).isInt()); 124} 125 126TEST_F(BuiltinsModuleTest, IdDoesNotChangeAfterGC) { 127 HandleScope scope(thread_); 128 Object obj(&scope, runtime_->newStrFromCStr("hello world foobar")); 129 Object id_before(&scope, runBuiltin(FUNC(builtins, id), obj)); 130 runtime_->collectGarbage(); 131 Object id_after(&scope, runBuiltin(FUNC(builtins, id), obj)); 132 EXPECT_EQ(*id_before, *id_after); 133} 134 135TEST_F(BuiltinsModuleTest, IdReturnsDifferentValueForDifferentObject) { 136 HandleScope scope(thread_); 137 Object obj1(&scope, runtime_->newStrFromCStr("hello world foobar")); 138 Object obj2(&scope, runtime_->newStrFromCStr("hello world foobarbaz")); 139 EXPECT_NE(runBuiltin(FUNC(builtins, id), obj1), 140 runBuiltin(FUNC(builtins, id), obj2)); 141} 142 143TEST_F(BuiltinsModuleTest, BuiltinLenGetLenFromDict) { 144 ASSERT_FALSE(runFromCStr(runtime_, R"( 145len0 = len({}) 146len1 = len({'one': 1}) 147len5 = len({'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5}) 148)") 149 .isError()); 150 151 HandleScope scope(thread_); 152 Object len0(&scope, mainModuleAt(runtime_, "len0")); 153 EXPECT_EQ(*len0, SmallInt::fromWord(0)); 154 Object len1(&scope, mainModuleAt(runtime_, "len1")); 155 EXPECT_EQ(*len1, SmallInt::fromWord(1)); 156 Object len5(&scope, mainModuleAt(runtime_, "len5")); 157 EXPECT_EQ(*len5, SmallInt::fromWord(5)); 158} 159 160TEST_F(BuiltinsModuleTest, BuiltinLenGetLenFromList) { 161 ASSERT_FALSE(runFromCStr(runtime_, R"( 162len0 = len([]) 163len1 = len([1]) 164len5 = len([1,2,3,4,5]) 165)") 166 .isError()); 167 168 HandleScope scope(thread_); 169 Object len0(&scope, mainModuleAt(runtime_, "len0")); 170 EXPECT_EQ(*len0, SmallInt::fromWord(0)); 171 Object len1(&scope, mainModuleAt(runtime_, "len1")); 172 EXPECT_EQ(*len1, SmallInt::fromWord(1)); 173 Object len5(&scope, mainModuleAt(runtime_, "len5")); 174 EXPECT_EQ(*len5, SmallInt::fromWord(5)); 175} 176 177TEST_F(BuiltinsModuleTest, BuiltinLenGetLenFromSet) { 178 ASSERT_FALSE(runFromCStr(runtime_, R"( 179len1 = len({1}) 180len5 = len({1,2,3,4,5}) 181)") 182 .isError()); 183 184 HandleScope scope(thread_); 185 // TODO(cshapiro): test the empty set when we have builtins.set defined. 186 Object len1(&scope, mainModuleAt(runtime_, "len1")); 187 EXPECT_EQ(*len1, SmallInt::fromWord(1)); 188 Object len5(&scope, mainModuleAt(runtime_, "len5")); 189 EXPECT_EQ(*len5, SmallInt::fromWord(5)); 190} 191 192TEST_F(BuiltinsModuleTest, BuiltinOrd) { 193 HandleScope scope(thread_); 194 Str str(&scope, runtime_->newStrFromCStr("A")); 195 EXPECT_TRUE(isIntEqualsWord(runBuiltin(FUNC(builtins, ord), str), 65)); 196 Int one(&scope, SmallInt::fromWord(1)); 197 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(builtins, ord), one), 198 LayoutId::kTypeError, 199 "Unsupported type in builtin 'ord'")); 200} 201 202TEST_F(BuiltinsModuleTest, BuiltinOrdWithBytearray) { 203 ASSERT_FALSE(runFromCStr(runtime_, R"( 204a_bytearray = bytearray(b'A') 205)") 206 .isError()); 207 HandleScope scope(thread_); 208 Object a_bytearray(&scope, mainModuleAt(runtime_, "a_bytearray")); 209 EXPECT_TRUE( 210 isIntEqualsWord(runBuiltin(FUNC(builtins, ord), a_bytearray), 65)); 211} 212 213TEST_F(BuiltinsModuleTest, BuiltinOrdWithEmptyBytearrayRaisesTypeError) { 214 ASSERT_FALSE(runFromCStr(runtime_, R"( 215a_bytearray = bytearray(b'') 216)") 217 .isError()); 218 HandleScope scope(thread_); 219 Object empty(&scope, mainModuleAt(runtime_, "a_bytearray")); 220 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(builtins, ord), empty), 221 LayoutId::kTypeError, 222 "Builtin 'ord' expects string of length 1")); 223} 224 225TEST_F(BuiltinsModuleTest, BuiltinOrdWithLongBytearrayRaisesTypeError) { 226 ASSERT_FALSE(runFromCStr(runtime_, R"( 227a_bytearray = bytearray(b'AB') 228)") 229 .isError()); 230 HandleScope scope(thread_); 231 Object not_a_char(&scope, mainModuleAt(runtime_, "a_bytearray")); 232 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(builtins, ord), not_a_char), 233 LayoutId::kTypeError, 234 "Builtin 'ord' expects string of length 1")); 235} 236 237TEST_F(BuiltinsModuleTest, BuiltinOrdWithBytes) { 238 unsigned char bytes[] = {'A'}; 239 HandleScope scope(thread_); 240 Object a_bytes(&scope, runtime_->newBytesWithAll(bytes)); 241 EXPECT_TRUE(isIntEqualsWord(runBuiltin(FUNC(builtins, ord), a_bytes), 65)); 242} 243 244TEST_F(BuiltinsModuleTest, BuiltinOrdWithEmptyBytesRaisesTypeError) { 245 HandleScope scope(thread_); 246 Object empty(&scope, Bytes::empty()); 247 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(builtins, ord), empty), 248 LayoutId::kTypeError, 249 "Builtin 'ord' expects string of length 1")); 250} 251 252TEST_F(BuiltinsModuleTest, BuiltinOrdWithLongBytesRaisesTypeError) { 253 unsigned char bytes[] = {'A', 'B'}; 254 HandleScope scope(thread_); 255 Object too_many_bytes(&scope, runtime_->newBytesWithAll(bytes)); 256 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(builtins, ord), too_many_bytes), 257 LayoutId::kTypeError, 258 "Builtin 'ord' expects string of length 1")); 259} 260 261TEST_F(BuiltinsModuleTest, BuiltinOrdWithStrSubclass) { 262 ASSERT_FALSE(runFromCStr(runtime_, R"( 263class MyStr(str): pass 264a_str = MyStr("A") 265)") 266 .isError()); 267 HandleScope scope(thread_); 268 Object a_str(&scope, mainModuleAt(runtime_, "a_str")); 269 EXPECT_TRUE(isIntEqualsWord(runBuiltin(FUNC(builtins, ord), a_str), 65)); 270} 271 272TEST_F(BuiltinsModuleTest, BuiltinOrdSupportNonASCII) { 273 HandleScope scope(thread_); 274 Str two_bytes(&scope, runtime_->newStrFromCStr("\xC3\xA9")); 275 Object two_ord(&scope, runBuiltin(FUNC(builtins, ord), two_bytes)); 276 EXPECT_TRUE(isIntEqualsWord(*two_ord, 0xE9)); 277 278 Str three_bytes(&scope, runtime_->newStrFromCStr("\xE2\xB3\x80")); 279 Object three_ord(&scope, runBuiltin(FUNC(builtins, ord), three_bytes)); 280 EXPECT_TRUE(isIntEqualsWord(*three_ord, 0x2CC0)); 281 282 Str four_bytes(&scope, runtime_->newStrFromCStr("\xF0\x9F\x86\x92")); 283 Object four_ord(&scope, runBuiltin(FUNC(builtins, ord), four_bytes)); 284 EXPECT_TRUE(isIntEqualsWord(*four_ord, 0x1F192)); 285} 286 287TEST_F(BuiltinsModuleTest, BuiltinOrdWithEmptyStrRaisesTypeError) { 288 HandleScope scope(thread_); 289 Object empty(&scope, Str::empty()); 290 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(builtins, ord), empty), 291 LayoutId::kTypeError, 292 "Builtin 'ord' expects string of length 1")); 293} 294 295TEST_F(BuiltinsModuleTest, BuiltinOrdWithEmptyStrSubclassRaisesTypeError) { 296 ASSERT_FALSE(runFromCStr(runtime_, R"( 297class MyStr(str): pass 298empty = MyStr("") 299)") 300 .isError()); 301 HandleScope scope(thread_); 302 Object empty(&scope, mainModuleAt(runtime_, "empty")); 303 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(builtins, ord), empty), 304 LayoutId::kTypeError, 305 "Builtin 'ord' expects string of length 1")); 306} 307 308TEST_F(BuiltinsModuleTest, BuiltinOrdStrWithManyCodePointsRaisesTypeError) { 309 HandleScope scope(thread_); 310 Object two_chars(&scope, runtime_->newStrFromCStr("ab")); 311 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(builtins, ord), two_chars), 312 LayoutId::kTypeError, 313 "Builtin 'ord' expects string of length 1")); 314} 315 316TEST_F(BuiltinsModuleTest, 317 BuiltinOrdStrSubclassWithManyCodePointsRaiseTypeError) { 318 ASSERT_FALSE(runFromCStr(runtime_, R"( 319class MyStr(str): pass 320two_code_points = MyStr("ab") 321)") 322 .isError()); 323 HandleScope scope(thread_); 324 Object two_code_points(&scope, mainModuleAt(runtime_, "two_code_points")); 325 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(builtins, ord), two_code_points), 326 LayoutId::kTypeError, 327 "Builtin 'ord' expects string of length 1")); 328} 329 330TEST_F(BuiltinsModuleTest, BuiltInReprOnUserTypeWithDunderRepr) { 331 ASSERT_FALSE(runFromCStr(runtime_, R"( 332class Foo: 333 def __repr__(self): 334 return "foo" 335 336a = repr(Foo()) 337)") 338 .isError()); 339 HandleScope scope(thread_); 340 Object a(&scope, mainModuleAt(runtime_, "a")); 341 EXPECT_TRUE(isStrEqualsCStr(*a, "foo")); 342} 343 344TEST_F(BuiltinsModuleTest, BuiltInReprOnClass) { 345 ASSERT_FALSE(runFromCStr(runtime_, "result = repr(int)").isError()); 346 HandleScope scope(thread_); 347 Object result(&scope, mainModuleAt(runtime_, "result")); 348 EXPECT_TRUE(isStrEqualsCStr(*result, "<class 'int'>")); 349} 350 351TEST_F(BuiltinsModuleTest, BuiltInAsciiCallsDunderRepr) { 352 ASSERT_FALSE(runFromCStr(runtime_, R"( 353class Foo: 354 def __repr__(self): 355 return "foo" 356 357a = ascii(Foo()) 358)") 359 .isError()); 360 HandleScope scope(thread_); 361 Object a(&scope, mainModuleAt(runtime_, "a")); 362 EXPECT_TRUE(isStrEqualsCStr(*a, "foo")); 363} 364 365TEST_F(BuiltinsModuleTest, DunderBuildClassWithNonFunctionRaisesTypeError) { 366 HandleScope scope(thread_); 367 Object body(&scope, NoneType::object()); 368 Object name(&scope, runtime_->newStrFromCStr("a")); 369 Object metaclass(&scope, Unbound::object()); 370 Object bootstrap(&scope, Bool::falseObj()); 371 Object bases(&scope, runtime_->emptyTuple()); 372 Object kwargs(&scope, runtime_->newDict()); 373 EXPECT_TRUE(raisedWithStr( 374 runBuiltin(FUNC(builtins, __build_class__), body, name, metaclass, 375 bootstrap, bases, kwargs), 376 LayoutId::kTypeError, "__build_class__: func must be a function")); 377} 378 379TEST_F(BuiltinsModuleTest, DunderBuildClassWithNonStringRaisesTypeError) { 380 HandleScope scope(thread_); 381 ASSERT_FALSE(runFromCStr(runtime_, "def f(): pass").isError()); 382 Object body(&scope, mainModuleAt(runtime_, "f")); 383 Object name(&scope, NoneType::object()); 384 Object metaclass(&scope, Unbound::object()); 385 Object bootstrap(&scope, Bool::falseObj()); 386 Object bases(&scope, runtime_->emptyTuple()); 387 Object kwargs(&scope, runtime_->newDict()); 388 EXPECT_TRUE(raisedWithStr( 389 runBuiltin(FUNC(builtins, __build_class__), body, name, metaclass, 390 bootstrap, bases, kwargs), 391 LayoutId::kTypeError, "__build_class__: name is not a string")); 392} 393 394TEST_F(BuiltinsModuleTest, DunderBuildClassCallsMetaclass) { 395 HandleScope scope(thread_); 396 ASSERT_FALSE(runFromCStr(runtime_, R"( 397class Meta(type): 398 def __new__(mcls, name, bases, namespace, *args, **kwargs): 399 return (mcls, name, bases, namespace, args, kwargs) 400class C(int, float, metaclass=Meta, hello="world"): 401 x = 42 402)") 403 .isError()); 404 Object meta(&scope, mainModuleAt(runtime_, "Meta")); 405 Object c_obj(&scope, mainModuleAt(runtime_, "C")); 406 ASSERT_TRUE(c_obj.isTuple()); 407 Tuple c(&scope, *c_obj); 408 ASSERT_EQ(c.length(), 6); 409 EXPECT_EQ(c.at(0), meta); 410 EXPECT_TRUE(isStrEqualsCStr(c.at(1), "C")); 411 412 ASSERT_TRUE(c.at(2).isTuple()); 413 Tuple c_bases(&scope, c.at(2)); 414 ASSERT_EQ(c_bases.length(), 2); 415 EXPECT_EQ(c_bases.at(0), runtime_->typeAt(LayoutId::kInt)); 416 EXPECT_EQ(c_bases.at(1), runtime_->typeAt(LayoutId::kFloat)); 417 418 ASSERT_TRUE(c.at(3).isDict()); 419 Dict c_namespace(&scope, c.at(3)); 420 Str x(&scope, runtime_->newStrFromCStr("x")); 421 EXPECT_EQ(dictIncludes(thread_, c_namespace, x, strHash(thread_, *x)), 422 Bool::trueObj()); 423 ASSERT_TRUE(c.at(4).isTuple()); 424 EXPECT_EQ(Tuple::cast(c.at(4)).length(), 0); 425 Str hello(&scope, runtime_->newStrFromCStr("hello")); 426 ASSERT_TRUE(c.at(5).isDict()); 427 Dict c_kwargs(&scope, c.at(5)); 428 EXPECT_EQ(c_kwargs.numItems(), 1); 429 EXPECT_TRUE(isStrEqualsCStr(dictAtByStr(thread_, c_kwargs, hello), "world")); 430} 431 432TEST_F(BuiltinsModuleTest, DunderBuildClassCalculatesMostSpecificMetaclass) { 433 HandleScope scope(thread_); 434 ASSERT_FALSE(runFromCStr(runtime_, R"( 435class Meta(type): pass 436class C1(int, metaclass=Meta): pass 437class C2(C1, metaclass=type): pass 438t1 = type(C1) 439t2 = type(C2) 440)") 441 .isError()); 442 Object meta(&scope, mainModuleAt(runtime_, "Meta")); 443 Object t1(&scope, mainModuleAt(runtime_, "t1")); 444 Object t2(&scope, mainModuleAt(runtime_, "t2")); 445 ASSERT_TRUE(t1.isType()); 446 ASSERT_TRUE(t2.isType()); 447 EXPECT_EQ(t1, meta); 448 EXPECT_EQ(t2, meta); 449} 450 451TEST_F(BuiltinsModuleTest, 452 DunderBuildClassWithIncompatibleMetaclassesRaisesTypeError) { 453 EXPECT_TRUE(raisedWithStr( 454 runFromCStr(runtime_, R"( 455class M1(type): pass 456class M2(type): pass 457class C1(metaclass=M1): pass 458class C2(C1, metaclass=M2): pass 459)"), 460 LayoutId::kTypeError, 461 "metaclass conflict: the metaclass of a derived class must be a " 462 "(non-strict) subclass of the metaclasses of all its bases")); 463} 464 465TEST_F(BuiltinsModuleTest, DunderBuildClassWithMeetMetaclassUsesMeet) { 466 HandleScope scope(thread_); 467 ASSERT_FALSE(runFromCStr(runtime_, R"( 468class M1(type): pass 469class M2(type): pass 470class M3(M1, M2): pass 471class C1(metaclass=M1): pass 472class C2(metaclass=M2): pass 473class C3(C1, C2, metaclass=M3): pass 474t1 = type(C1) 475t2 = type(C2) 476t3 = type(C3) 477)") 478 .isError()); 479 Object m1(&scope, mainModuleAt(runtime_, "M1")); 480 Object m2(&scope, mainModuleAt(runtime_, "M2")); 481 Object m3(&scope, mainModuleAt(runtime_, "M3")); 482 Object t1(&scope, mainModuleAt(runtime_, "t1")); 483 Object t2(&scope, mainModuleAt(runtime_, "t2")); 484 Object t3(&scope, mainModuleAt(runtime_, "t3")); 485 ASSERT_TRUE(t1.isType()); 486 ASSERT_TRUE(t2.isType()); 487 ASSERT_TRUE(t3.isType()); 488 EXPECT_EQ(t1, m1); 489 EXPECT_EQ(t2, m2); 490 EXPECT_EQ(t3, m3); 491} 492 493TEST_F(BuiltinsModuleTest, DunderBuildClassPropagatesDunderPrepareError) { 494 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 495class Meta(type): 496 @classmethod 497 def __prepare__(cls, *args, **kwds): 498 raise IndentationError("foo") 499class C(metaclass=Meta): 500 pass 501)"), 502 LayoutId::kIndentationError, "foo")); 503} 504 505TEST_F(BuiltinsModuleTest, DunderBuildClassWithNonDictPrepareRaisesTypeError) { 506 EXPECT_TRUE( 507 raisedWithStr(runFromCStr(runtime_, R"( 508class Meta(type): 509 @classmethod 510 def __prepare__(cls, *args, **kwds): 511 return 42 512class C(metaclass=Meta): 513 pass 514)"), 515 LayoutId::kTypeError, 516 "Meta.__prepare__() must return a mapping, not int")); 517} 518 519TEST_F(BuiltinsModuleTest, 520 DunderBuildClassWithNonTypeMetaclassAndNonDictPrepareRaisesTypeError) { 521 EXPECT_TRUE(raisedWithStr( 522 runFromCStr(runtime_, R"( 523class Meta: 524 def __prepare__(self, *args, **kwds): 525 return 42 526class C(metaclass=Meta()): 527 pass 528)"), 529 LayoutId::kTypeError, 530 "<metaclass>.__prepare__() must return a mapping, not int")); 531} 532 533TEST_F(BuiltinsModuleTest, DunderBuildClassUsesDunderPrepareForClassDict) { 534 HandleScope scope(thread_); 535 ASSERT_FALSE(runFromCStr(runtime_, R"( 536class Meta(type): 537 @classmethod 538 def __prepare__(cls, *args, **kwds): 539 return {"foo": 42} 540class C(metaclass=Meta): 541 pass 542result = C.foo 543)") 544 .isError()); 545 Object result(&scope, mainModuleAt(runtime_, "result")); 546 EXPECT_TRUE(isIntEqualsWord(*result, 42)); 547} 548 549TEST_F(BuiltinsModuleTest, DunderBuildClassPassesNameBasesAndKwargsToPrepare) { 550 HandleScope scope(thread_); 551 ASSERT_FALSE(runFromCStr(runtime_, R"( 552class Meta(type): 553 def __init__(metacls, name, bases, namespace, **kwargs): 554 pass 555 def __new__(metacls, name, bases, namespace, **kwargs): 556 return super().__new__(metacls, name, bases, namespace) 557 @classmethod 558 def __prepare__(metacls, name, bases, **kwargs): 559 return {"foo": name, "bar": bases[0], "baz": kwargs["answer"]} 560class C(int, metaclass=Meta, answer=42): 561 pass 562name = C.foo 563base = C.bar 564answer = C.baz 565)") 566 .isError()); 567 Object name(&scope, mainModuleAt(runtime_, "name")); 568 Object base(&scope, mainModuleAt(runtime_, "base")); 569 Object answer(&scope, mainModuleAt(runtime_, "answer")); 570 EXPECT_TRUE(isStrEqualsCStr(*name, "C")); 571 EXPECT_EQ(base, runtime_->typeAt(LayoutId::kInt)); 572 EXPECT_TRUE(isIntEqualsWord(*answer, 42)); 573} 574 575TEST_F(BuiltinsModuleTest, DunderBuildClassWithRaisingBodyPropagatesException) { 576 EXPECT_TRUE(raised(runFromCStr(runtime_, R"( 577class C: 578 raise UserWarning() 579)"), 580 LayoutId::kUserWarning)); 581} 582 583TEST_F(BuiltinsModuleTest, DunderImportWithBuiltinReturnsModule) { 584 HandleScope scope(thread_); 585 Object name(&scope, runtime_->newStrFromCStr("_io")); 586 Object globals(&scope, NoneType::object()); 587 Object locals(&scope, NoneType::object()); 588 Object fromlist(&scope, runtime_->emptyTuple()); 589 Object level(&scope, runtime_->newInt(0)); 590 Object result_obj(&scope, runBuiltin(FUNC(builtins, __import__), name, 591 globals, locals, fromlist, level)); 592 ASSERT_TRUE(result_obj.isModule()); 593 Module result(&scope, *result_obj); 594 EXPECT_TRUE(isStrEqualsCStr(result.name(), "_io")); 595} 596 597TEST_F(BuiltinsModuleTest, DunderImportWithExtensionModuleReturnsModule) { 598 HandleScope scope(thread_); 599 Object name(&scope, runtime_->newStrFromCStr("errno")); 600 Object globals(&scope, NoneType::object()); 601 Object locals(&scope, NoneType::object()); 602 Object fromlist(&scope, runtime_->emptyTuple()); 603 Object level(&scope, runtime_->newInt(0)); 604 Object result_obj(&scope, runBuiltin(FUNC(builtins, __import__), name, 605 globals, locals, fromlist, level)); 606 ASSERT_TRUE(result_obj.isModule()); 607 Module result(&scope, *result_obj); 608 EXPECT_TRUE(isStrEqualsCStr(result.name(), "errno")); 609} 610 611TEST_F(BuiltinsModuleTest, DunderImportRaisesImportError) { 612 HandleScope scope(thread_); 613 // The minimal implementation should not open files. 614 Object name(&scope, runtime_->newStrFromCStr("antigravity")); 615 Object globals(&scope, NoneType::object()); 616 Object locals(&scope, NoneType::object()); 617 Object fromlist(&scope, runtime_->emptyTuple()); 618 Object level(&scope, runtime_->newInt(0)); 619 EXPECT_TRUE( 620 raisedWithStr(runBuiltin(FUNC(builtins, __import__), name, globals, 621 locals, fromlist, level), 622 LayoutId::kImportError, 623 "failed to import antigravity (bootstrap importer)")); 624} 625 626TEST_F(BuiltinsModuleTest, GetAttrFromClassReturnsValue) { 627 const char* src = R"( 628class Foo: 629 bar = 1 630obj = getattr(Foo, 'bar') 631)"; 632 HandleScope scope(thread_); 633 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 634 Object obj(&scope, mainModuleAt(runtime_, "obj")); 635 EXPECT_EQ(*obj, SmallInt::fromWord(1)); 636} 637 638TEST_F(BuiltinsModuleTest, GetAttrFromInstanceReturnsValue) { 639 const char* src = R"( 640class Foo: 641 bar = 1 642obj = getattr(Foo(), 'bar') 643)"; 644 HandleScope scope(thread_); 645 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 646 Object obj(&scope, mainModuleAt(runtime_, "obj")); 647 EXPECT_EQ(*obj, SmallInt::fromWord(1)); 648} 649 650TEST_F(BuiltinsModuleTest, GetAttrFromInstanceWithMissingAttrReturnsDefault) { 651 const char* src = R"( 652class Foo: pass 653obj = getattr(Foo(), 'bar', 2) 654)"; 655 HandleScope scope(thread_); 656 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 657 Object obj(&scope, mainModuleAt(runtime_, "obj")); 658 EXPECT_EQ(*obj, SmallInt::fromWord(2)); 659} 660 661TEST_F(BuiltinsModuleTest, GetAttrWithNonStringAttrRaisesTypeError) { 662 const char* src = R"( 663class Foo: pass 664getattr(Foo(), 1) 665)"; 666 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, src), LayoutId::kTypeError, 667 "attribute name must be string, not 'int'")); 668} 669 670TEST_F(BuiltinsModuleTest, GetAttrWithNonStringAttrAndDefaultRaisesTypeError) { 671 const char* src = R"( 672class Foo: pass 673getattr(Foo(), 1, 2) 674)"; 675 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, src), LayoutId::kTypeError, 676 "attribute name must be string, not 'int'")); 677} 678 679TEST_F(BuiltinsModuleTest, 680 GetAttrFromClassMissingAttrWithoutDefaultRaisesAttributeError) { 681 const char* src = R"( 682class Foo: 683 bar = 1 684getattr(Foo, 'foo') 685)"; 686 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, src), 687 LayoutId::kAttributeError, 688 "type object 'Foo' has no attribute 'foo'")); 689} 690 691TEST_F(BuiltinsModuleTest, 692 HashWithObjectWithNotCallableDunderHashRaisesTypeError) { 693 const char* src = R"( 694class C: 695 __hash__ = None 696 697hash(C()) 698)"; 699 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, src), LayoutId::kTypeError, 700 "unhashable type: 'C'")); 701} 702 703TEST_F(BuiltinsModuleTest, HashWithObjectReturningNonIntRaisesTypeError) { 704 const char* src = R"( 705class C: 706 def __hash__(self): return "10" 707 708hash(C()) 709)"; 710 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, src), LayoutId::kTypeError, 711 "__hash__ method should return an integer")); 712} 713 714TEST_F(BuiltinsModuleTest, HashWithObjectReturnsObjectDunderHashValue) { 715 ASSERT_FALSE(runFromCStr(runtime_, R"( 716class C: 717 def __hash__(self): return 10 718 719h = hash(C()) 720)") 721 .isError()); 722 EXPECT_EQ(mainModuleAt(runtime_, "h"), SmallInt::fromWord(10)); 723} 724 725TEST_F(BuiltinsModuleTest, 726 HashWithObjectWithModifiedDunderHashReturnsClassDunderHashValue) { 727 ASSERT_FALSE(runFromCStr(runtime_, R"( 728class C: 729 def __hash__(self): return 10 730 731def fake_hash(): return 0 732c = C() 733c.__hash__ = fake_hash 734h = hash(c) 735)") 736 .isError()); 737 EXPECT_EQ(mainModuleAt(runtime_, "h"), SmallInt::fromWord(10)); 738} 739 740TEST_F(BuiltinsModuleTest, BuiltInSetAttr) { 741 const char* src = R"( 742class Foo: 743 bar = 1 744a = setattr(Foo, 'foo', 2) 745b = Foo.foo 746)"; 747 HandleScope scope(thread_); 748 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 749 Object a(&scope, mainModuleAt(runtime_, "a")); 750 Object b(&scope, mainModuleAt(runtime_, "b")); 751 EXPECT_EQ(*a, NoneType::object()); 752 EXPECT_EQ(*b, SmallInt::fromWord(2)); 753} 754 755TEST_F(BuiltinsModuleTest, BuiltInSetAttrRaisesTypeError) { 756 const char* src = R"( 757class Foo: 758 bar = 1 759a = setattr(Foo, 2, 'foo') 760)"; 761 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, src), LayoutId::kTypeError, 762 "attribute name must be string, not 'int'")); 763} 764 765TEST_F(BuiltinsModuleTest, ModuleAttrReturnsBuiltinsName) { 766 // TODO(eelizondo): Parameterize test for all builtin types 767 const char* src = R"( 768a = hasattr(object, '__module__') 769b = getattr(object, '__module__') 770c = hasattr(list, '__module__') 771d = getattr(list, '__module__') 772)"; 773 HandleScope scope(thread_); 774 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 775 776 Object a(&scope, mainModuleAt(runtime_, "a")); 777 EXPECT_EQ(*a, Bool::trueObj()); 778 Object b(&scope, mainModuleAt(runtime_, "b")); 779 ASSERT_TRUE(b.isStr()); 780 EXPECT_TRUE(Str::cast(*b).equalsCStr("builtins")); 781 782 Object c(&scope, mainModuleAt(runtime_, "c")); 783 EXPECT_EQ(*c, Bool::trueObj()); 784 Object d(&scope, mainModuleAt(runtime_, "d")); 785 ASSERT_TRUE(d.isStr()); 786 EXPECT_TRUE(Str::cast(*b).equalsCStr("builtins")); 787} 788 789TEST_F(BuiltinsModuleTest, QualnameAttrReturnsTypeName) { 790 // TODO(eelizondo): Parameterize test for all builtin types 791 const char* src = R"( 792a = hasattr(object, '__qualname__') 793b = getattr(object, '__qualname__') 794c = hasattr(list, '__qualname__') 795d = getattr(list, '__qualname__') 796)"; 797 HandleScope scope(thread_); 798 ASSERT_FALSE(runFromCStr(runtime_, src).isError()); 799 800 Object a(&scope, mainModuleAt(runtime_, "a")); 801 EXPECT_EQ(*a, Bool::trueObj()); 802 Object b(&scope, mainModuleAt(runtime_, "b")); 803 ASSERT_TRUE(b.isStr()); 804 EXPECT_TRUE(Str::cast(*b).equalsCStr("object")); 805 806 Object c(&scope, mainModuleAt(runtime_, "c")); 807 EXPECT_EQ(*c, Bool::trueObj()); 808 Object d(&scope, mainModuleAt(runtime_, "d")); 809 ASSERT_TRUE(d.isStr()); 810 EXPECT_TRUE(Str::cast(*d).equalsCStr("list")); 811} 812 813TEST_F(BuiltinsModuleTest, BuiltinCompile) { 814 HandleScope scope(thread_); 815 ASSERT_FALSE( 816 runFromCStr( 817 runtime_, 818 R"(code = compile("a+b", "<string>", "eval", dont_inherit=True))") 819 .isError()); 820 Str filename(&scope, runtime_->newStrFromCStr("<string>")); 821 Code code(&scope, mainModuleAt(runtime_, "code")); 822 ASSERT_TRUE(code.filename().isStr()); 823 EXPECT_TRUE(Str::cast(code.filename()).equals(*filename)); 824 825 ASSERT_TRUE(code.names().isTuple()); 826 Tuple names(&scope, code.names()); 827 ASSERT_EQ(names.length(), 2); 828 ASSERT_TRUE(names.contains(runtime_->newStrFromCStr("a"))); 829 ASSERT_TRUE(names.contains(runtime_->newStrFromCStr("b"))); 830} 831 832TEST_F(BuiltinsModuleTest, BuiltinCompileBytes) { 833 HandleScope scope(thread_); 834 ASSERT_FALSE(runFromCStr(runtime_, R"( 835data = b'a+b' 836code = compile(data, "<string>", "eval", dont_inherit=True) 837)") 838 .isError()); 839 Code code(&scope, mainModuleAt(runtime_, "code")); 840 Object filename(&scope, code.filename()); 841 EXPECT_TRUE(isStrEqualsCStr(*filename, "<string>")); 842 843 ASSERT_TRUE(code.names().isTuple()); 844 Tuple names(&scope, code.names()); 845 ASSERT_EQ(names.length(), 2); 846 ASSERT_TRUE(names.contains(runtime_->newStrFromCStr("a"))); 847 ASSERT_TRUE(names.contains(runtime_->newStrFromCStr("b"))); 848} 849 850TEST_F(BuiltinsModuleTest, BuiltinCompileWithBytesSubclass) { 851 HandleScope scope(thread_); 852 ASSERT_FALSE(runFromCStr(runtime_, R"( 853class Foo(bytes): pass 854data = Foo(b"a+b") 855code = compile(data, "<string>", "eval", dont_inherit=True) 856)") 857 .isError()); 858 Code code(&scope, mainModuleAt(runtime_, "code")); 859 Object filename(&scope, code.filename()); 860 EXPECT_TRUE(isStrEqualsCStr(*filename, "<string>")); 861 862 ASSERT_TRUE(code.names().isTuple()); 863 Tuple names(&scope, code.names()); 864 ASSERT_EQ(names.length(), 2); 865 ASSERT_TRUE(names.contains(runtime_->newStrFromCStr("a"))); 866 ASSERT_TRUE(names.contains(runtime_->newStrFromCStr("b"))); 867} 868 869TEST_F(BuiltinsModuleTest, BuiltinCompileWithStrSubclass) { 870 HandleScope scope(thread_); 871 ASSERT_FALSE(runFromCStr(runtime_, R"( 872class Foo(str): pass 873data = Foo("a+b") 874code = compile(data, "<string>", "eval", dont_inherit=True) 875)") 876 .isError()); 877 Code code(&scope, mainModuleAt(runtime_, "code")); 878 Object filename(&scope, code.filename()); 879 EXPECT_TRUE(isStrEqualsCStr(*filename, "<string>")); 880 881 ASSERT_TRUE(code.names().isTuple()); 882 Tuple names(&scope, code.names()); 883 ASSERT_EQ(names.length(), 2); 884 ASSERT_TRUE(names.contains(runtime_->newStrFromCStr("a"))); 885 ASSERT_TRUE(names.contains(runtime_->newStrFromCStr("b"))); 886} 887 888TEST_F(BuiltinsModuleDeathTest, BuiltinCompileRaisesTypeErrorGivenTooFewArgs) { 889 EXPECT_TRUE( 890 raisedWithStr(runFromCStr(runtime_, "compile(1)"), LayoutId::kTypeError, 891 "'compile' takes min 3 positional arguments but 1 given")); 892} 893 894TEST_F(BuiltinsModuleDeathTest, BuiltinCompileRaisesTypeErrorGivenTooManyArgs) { 895 EXPECT_TRUE( 896 raisedWithStr(runFromCStr(runtime_, "compile(1, 2, 3, 4, 5, 6, 7, 8, 9)"), 897 LayoutId::kTypeError, 898 "'compile' takes max 6 positional arguments but 9 given")); 899} 900 901TEST_F(BuiltinsModuleTest, BuiltinCompileRaisesTypeErrorGivenBadMode) { 902 EXPECT_TRUE(raisedWithStr( 903 runFromCStr(runtime_, 904 "compile('hello', 'hello', 'hello', dont_inherit=True)"), 905 LayoutId::kValueError, 906 "compile() mode must be 'exec', 'eval' or 'single'")); 907} 908 909TEST_F(BuiltinsModuleTest, AllOnListWithOnlyTrueReturnsTrue) { 910 ASSERT_FALSE(runFromCStr(runtime_, R"( 911result = all([True, True]) 912 )") 913 .isError()); 914 HandleScope scope(thread_); 915 Bool result(&scope, mainModuleAt(runtime_, "result")); 916 EXPECT_TRUE(result.value()); 917} 918 919TEST_F(BuiltinsModuleTest, AllOnListWithFalseReturnsFalse) { 920 ASSERT_FALSE(runFromCStr(runtime_, R"( 921result = all([True, False, True]) 922 )") 923 .isError()); 924 HandleScope scope(thread_); 925 Bool result(&scope, mainModuleAt(runtime_, "result")); 926 EXPECT_FALSE(result.value()); 927} 928 929TEST_F(BuiltinsModuleTest, AnyOnListWithOnlyFalseReturnsFalse) { 930 ASSERT_FALSE(runFromCStr(runtime_, R"( 931result = any([False, False]) 932 )") 933 .isError()); 934 HandleScope scope(thread_); 935 Bool result(&scope, mainModuleAt(runtime_, "result")); 936 EXPECT_FALSE(result.value()); 937} 938 939TEST_F(BuiltinsModuleTest, AnyOnListWithTrueReturnsTrue) { 940 ASSERT_FALSE(runFromCStr(runtime_, R"( 941result = any([False, True, False]) 942 )") 943 .isError()); 944 HandleScope scope(thread_); 945 Bool result(&scope, mainModuleAt(runtime_, "result")); 946 EXPECT_TRUE(result.value()); 947} 948 949TEST_F(BuiltinsModuleTest, FilterWithNonIterableArgumentRaisesTypeError) { 950 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "filter(None, 1)"), 951 LayoutId::kTypeError, 952 "'int' object is not iterable")); 953} 954 955TEST_F(BuiltinsModuleTest, 956 FilterWithNoneFuncAndIterableReturnsItemsOfTrueBoolValue) { 957 ASSERT_FALSE(runFromCStr(runtime_, R"( 958f = filter(None, [1,0,2,0]) 959r0 = f.__next__() 960r1 = f.__next__() 961exhausted = False 962try: 963 f.__next__() 964except StopIteration: 965 exhausted = True 966)") 967 .isError()); 968 HandleScope scope(thread_); 969 Object r0(&scope, mainModuleAt(runtime_, "r0")); 970 Object r1(&scope, mainModuleAt(runtime_, "r1")); 971 Object exhausted(&scope, mainModuleAt(runtime_, "exhausted")); 972 EXPECT_TRUE(isIntEqualsWord(*r0, 1)); 973 EXPECT_TRUE(isIntEqualsWord(*r1, 2)); 974 EXPECT_EQ(*exhausted, Bool::trueObj()); 975} 976 977TEST_F( 978 BuiltinsModuleTest, 979 FilterWithFuncReturningBoolAndIterableReturnsItemsEvaluatedToTrueByFunc) { 980 ASSERT_FALSE(runFromCStr(runtime_, R"( 981def even(e): return e % 2 == 0 982 983f = filter(even, [1,2,3,4]) 984r0 = f.__next__() 985r1 = f.__next__() 986exhausted = False 987try: 988 f.__next__() 989except StopIteration: 990 exhausted = True 991)") 992 .isError()); 993 HandleScope scope(thread_); 994 Object r0(&scope, mainModuleAt(runtime_, "r0")); 995 Object r1(&scope, mainModuleAt(runtime_, "r1")); 996 Object exhausted(&scope, mainModuleAt(runtime_, "exhausted")); 997 EXPECT_TRUE(isIntEqualsWord(*r0, 2)); 998 EXPECT_TRUE(isIntEqualsWord(*r1, 4)); 999 EXPECT_EQ(*exhausted, Bool::trueObj()); 1000} 1001 1002TEST_F(BuiltinsModuleTest, FormatWithNonStrFmtSpecRaisesTypeError) { 1003 EXPECT_TRUE( 1004 raised(runFromCStr(runtime_, "format('hi', 1)"), LayoutId::kTypeError)); 1005} 1006 1007TEST_F(BuiltinsModuleTest, FormatCallsDunderFormat) { 1008 ASSERT_FALSE(runFromCStr(runtime_, R"( 1009class C: 1010 def __format__(self, fmt_spec): 1011 return "foobar" 1012result = format(C(), 'hi') 1013)") 1014 .isError()); 1015 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "result"), "foobar")); 1016} 1017 1018TEST_F(BuiltinsModuleTest, FormatRaisesWhenDunderFormatReturnsNonStr) { 1019 ASSERT_FALSE(runFromCStr(runtime_, R"( 1020class C: 1021 def __format__(self, fmt_spec): 1022 return 1 1023)") 1024 .isError()); 1025 EXPECT_TRUE( 1026 raised(runFromCStr(runtime_, "format(C(), 'hi')"), LayoutId::kTypeError)); 1027} 1028 1029TEST_F(BuiltinsModuleTest, IterWithIterableCallsDunderIter) { 1030 ASSERT_FALSE(runFromCStr(runtime_, R"( 1031l = list(iter([1, 2, 3])) 1032)") 1033 .isError()); 1034 HandleScope scope(thread_); 1035 Object l(&scope, mainModuleAt(runtime_, "l")); 1036 EXPECT_PYLIST_EQ(l, {1, 2, 3}); 1037} 1038 1039TEST_F(BuiltinsModuleTest, IterWithNonIterableRaisesTypeError) { 1040 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1041iter(None) 1042)"), 1043 LayoutId::kTypeError, 1044 "'NoneType' object is not iterable")); 1045} 1046 1047TEST_F(BuiltinsModuleTest, IterWithRaisingDunderIterPropagatesException) { 1048 EXPECT_TRUE(raised(runFromCStr(runtime_, R"( 1049class C: 1050 def __iter__(self): 1051 raise UserWarning() 1052iter(C()) 1053)"), 1054 LayoutId::kUserWarning)); 1055} 1056 1057TEST_F(BuiltinsModuleTest, NextWithoutIteratorRaisesTypeError) { 1058 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1059class C: 1060 pass 1061next(C()) 1062)"), 1063 LayoutId::kTypeError, 1064 "'C' object is not iterable")); 1065} 1066 1067TEST_F(BuiltinsModuleTest, NextWithIteratorFetchesNextItem) { 1068 ASSERT_FALSE(runFromCStr(runtime_, R"( 1069class C: 1070 def __iter__(self): 1071 self.a = 1 1072 return self 1073 1074 def __next__(self): 1075 x = self.a 1076 self.a += 1 1077 return x 1078 1079itr = iter(C()) 1080c = next(itr) 1081d = next(itr) 1082)") 1083 .isError()); 1084 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "c"), 1)); 1085 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "d"), 2)); 1086} 1087 1088TEST_F(BuiltinsModuleTest, NextWithIteratorAndDefaultFetchesNextItem) { 1089 ASSERT_FALSE(runFromCStr(runtime_, R"( 1090class C: 1091 def __iter__(self): 1092 self.a = 1 1093 return self 1094 1095 def __next__(self): 1096 x = self.a 1097 self.a += 1 1098 return x 1099 1100itr = iter(C()) 1101c = next(itr, 0) 1102d = next(itr, 0) 1103)") 1104 .isError()); 1105 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "c"), 1)); 1106 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "d"), 2)); 1107} 1108 1109TEST_F(BuiltinsModuleTest, NextWithIteratorRaisesStopIteration) { 1110 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1111class C: 1112 def __iter__(self): 1113 return self 1114 1115 def __next__(self): 1116 raise StopIteration('stopit') 1117 1118itr = iter(C()) 1119next(itr) 1120)"), 1121 LayoutId::kStopIteration, "stopit")); 1122} 1123 1124TEST_F(BuiltinsModuleTest, NextWithIteratorAndDefaultReturnsDefault) { 1125 ASSERT_FALSE(runFromCStr(runtime_, R"( 1126class C: 1127 def __iter__(self): 1128 return self 1129 1130 def __next__(self): 1131 raise StopIteration('stopit') 1132itr = iter(C()) 1133c = next(itr, None) 1134)") 1135 .isError()); 1136 EXPECT_TRUE(mainModuleAt(runtime_, "c").isNoneType()); 1137} 1138 1139TEST_F(BuiltinsModuleTest, SortedReturnsSortedList) { 1140 ASSERT_FALSE(runFromCStr(runtime_, R"( 1141unsorted = [5, 7, 8, 6] 1142result = sorted(unsorted) 1143)") 1144 .isError()); 1145 1146 HandleScope scope(thread_); 1147 Object unsorted_obj(&scope, mainModuleAt(runtime_, "unsorted")); 1148 ASSERT_TRUE(unsorted_obj.isList()); 1149 Object result_obj(&scope, mainModuleAt(runtime_, "result")); 1150 ASSERT_TRUE(result_obj.isList()); 1151 EXPECT_NE(*unsorted_obj, *result_obj); 1152 1153 List unsorted(&scope, *unsorted_obj); 1154 ASSERT_EQ(unsorted.numItems(), 4); 1155 EXPECT_EQ(unsorted.at(0), SmallInt::fromWord(5)); 1156 EXPECT_EQ(unsorted.at(1), SmallInt::fromWord(7)); 1157 EXPECT_EQ(unsorted.at(2), SmallInt::fromWord(8)); 1158 EXPECT_EQ(unsorted.at(3), SmallInt::fromWord(6)); 1159 1160 List result(&scope, *result_obj); 1161 ASSERT_EQ(result.numItems(), 4); 1162 EXPECT_EQ(result.at(0), SmallInt::fromWord(5)); 1163 EXPECT_EQ(result.at(1), SmallInt::fromWord(6)); 1164 EXPECT_EQ(result.at(2), SmallInt::fromWord(7)); 1165 EXPECT_EQ(result.at(3), SmallInt::fromWord(8)); 1166} 1167 1168TEST_F(BuiltinsModuleTest, SortedWithReverseReturnsReverseSortedList) { 1169 ASSERT_FALSE(runFromCStr(runtime_, R"( 1170unsorted = [1, 2, 3, 4] 1171result = sorted(unsorted, reverse=True) 1172)") 1173 .isError()); 1174 1175 HandleScope scope(thread_); 1176 Object unsorted_obj(&scope, mainModuleAt(runtime_, "unsorted")); 1177 ASSERT_TRUE(unsorted_obj.isList()); 1178 Object result_obj(&scope, mainModuleAt(runtime_, "result")); 1179 ASSERT_TRUE(result_obj.isList()); 1180 EXPECT_NE(*unsorted_obj, *result_obj); 1181 1182 List unsorted(&scope, *unsorted_obj); 1183 ASSERT_EQ(unsorted.numItems(), 4); 1184 EXPECT_EQ(unsorted.at(0), SmallInt::fromWord(1)); 1185 EXPECT_EQ(unsorted.at(1), SmallInt::fromWord(2)); 1186 EXPECT_EQ(unsorted.at(2), SmallInt::fromWord(3)); 1187 EXPECT_EQ(unsorted.at(3), SmallInt::fromWord(4)); 1188 1189 List result(&scope, *result_obj); 1190 ASSERT_EQ(result.numItems(), 4); 1191 EXPECT_EQ(result.at(0), SmallInt::fromWord(4)); 1192 EXPECT_EQ(result.at(1), SmallInt::fromWord(3)); 1193 EXPECT_EQ(result.at(2), SmallInt::fromWord(2)); 1194 EXPECT_EQ(result.at(3), SmallInt::fromWord(1)); 1195} 1196 1197TEST_F(BuiltinsModuleTest, MaxWithEmptyIterableRaisesValueError) { 1198 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "max([])"), 1199 LayoutId::kValueError, 1200 "max() arg is an empty sequence")); 1201} 1202 1203TEST_F(BuiltinsModuleTest, MaxWithMultipleArgsReturnsMaximum) { 1204 ASSERT_FALSE(runFromCStr(runtime_, "result = max(1, 3, 5, 2, -1)").isError()); 1205 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 5)); 1206} 1207 1208TEST_F(BuiltinsModuleTest, MaxWithNoArgsRaisesTypeError) { 1209 EXPECT_TRUE( 1210 raisedWithStr(runFromCStr(runtime_, "max()"), LayoutId::kTypeError, 1211 "'max' takes min 1 positional arguments but 0 given")); 1212} 1213 1214TEST_F(BuiltinsModuleTest, MaxWithIterableReturnsMaximum) { 1215 ASSERT_FALSE( 1216 runFromCStr(runtime_, "result = max((1, 3, 5, 2, -1))").isError()); 1217 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 5)); 1218} 1219 1220TEST_F(BuiltinsModuleTest, MaxWithEmptyIterableAndDefaultReturnsDefault) { 1221 ASSERT_FALSE(runFromCStr(runtime_, "result = max([], default=42)").isError()); 1222 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 42)); 1223} 1224 1225TEST_F(BuiltinsModuleTest, MaxWithKeyOrdersByKeyFunction) { 1226 ASSERT_FALSE(runFromCStr(runtime_, R"( 1227result = max((1, 2, 3), key=lambda x: -x) 1228)") 1229 .isError()); 1230 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 1)); 1231} 1232 1233TEST_F(BuiltinsModuleTest, MaxWithEmptyIterableAndKeyAndDefaultReturnsDefault) { 1234 ASSERT_FALSE(runFromCStr(runtime_, R"( 1235result = max((), key=lambda x: x, default='empty') 1236)") 1237 .isError()); 1238 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "result"), "empty")); 1239} 1240 1241TEST_F(BuiltinsModuleTest, MaxWithMultipleArgsAndDefaultRaisesTypeError) { 1242 EXPECT_TRUE(raisedWithStr( 1243 runFromCStr(runtime_, "max(1, 2, default=0)"), LayoutId::kTypeError, 1244 "Cannot specify a default for max() with multiple positional arguments")); 1245} 1246 1247TEST_F(BuiltinsModuleTest, MaxWithKeyReturnsFirstOccuranceOfEqualValues) { 1248 ASSERT_FALSE(runFromCStr(runtime_, R"( 1249class A: 1250 pass 1251 1252first = A() 1253second = A() 1254result = max(first, second, key=lambda x: 1) is first 1255)") 1256 .isError()); 1257 EXPECT_EQ(mainModuleAt(runtime_, "result"), Bool::trueObj()); 1258} 1259 1260TEST_F(BuiltinsModuleTest, MaxWithoutKeyReturnsFirstOccuranceOfEqualValues) { 1261 ASSERT_FALSE(runFromCStr(runtime_, R"( 1262class A(): 1263 def __gt__(self, _): 1264 return False 1265 1266first = A() 1267second = A() 1268result = max(first, second) is first 1269)") 1270 .isError()); 1271 EXPECT_EQ(mainModuleAt(runtime_, "result"), Bool::trueObj()); 1272} 1273 1274TEST_F(BuiltinsModuleTest, MinWithEmptyIterableRaisesValueError) { 1275 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "min([])"), 1276 LayoutId::kValueError, 1277 "min() arg is an empty sequence")); 1278} 1279 1280TEST_F(BuiltinsModuleTest, MinWithMultipleArgsReturnsMinimum) { 1281 ASSERT_FALSE(runFromCStr(runtime_, "result = min(4, 3, 1, 2, 5)").isError()); 1282 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 1)); 1283} 1284 1285TEST_F(BuiltinsModuleTest, MinWithNoArgsRaisesTypeError) { 1286 EXPECT_TRUE( 1287 raisedWithStr(runFromCStr(runtime_, "min()"), LayoutId::kTypeError, 1288 "'min' takes min 1 positional arguments but 0 given")); 1289} 1290 1291TEST_F(BuiltinsModuleTest, MinWithIterableReturnsMinimum) { 1292 ASSERT_FALSE( 1293 runFromCStr(runtime_, "result = min((4, 3, 1, 2, 5))").isError()); 1294 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 1)); 1295} 1296 1297TEST_F(BuiltinsModuleTest, MinWithEmptyIterableAndDefaultReturnsDefault) { 1298 ASSERT_FALSE(runFromCStr(runtime_, "result = min([], default=42)").isError()); 1299 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 42)); 1300} 1301 1302TEST_F(BuiltinsModuleTest, MinWithKeyOrdersByKeyFunction) { 1303 ASSERT_FALSE(runFromCStr(runtime_, R"( 1304result = min((1, 2, 3), key=lambda x: -x) 1305)") 1306 .isError()); 1307 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 3)); 1308} 1309 1310TEST_F(BuiltinsModuleTest, MinWithEmptyIterableAndKeyAndDefaultReturnsDefault) { 1311 ASSERT_FALSE(runFromCStr(runtime_, R"( 1312result = min((), key=lambda x: x, default='empty') 1313)") 1314 .isError()); 1315 EXPECT_TRUE(isStrEqualsCStr(mainModuleAt(runtime_, "result"), "empty")); 1316} 1317 1318TEST_F(BuiltinsModuleTest, MinWithMultipleArgsAndDefaultRaisesTypeError) { 1319 EXPECT_TRUE(raisedWithStr( 1320 runFromCStr(runtime_, "min(1, 2, default=0)"), LayoutId::kTypeError, 1321 "Cannot specify a default for min() with multiple positional arguments")); 1322} 1323 1324TEST_F(BuiltinsModuleTest, MinReturnsFirstOccuranceOfEqualValues) { 1325 ASSERT_FALSE(runFromCStr(runtime_, R"( 1326class A: 1327 pass 1328 1329first = A() 1330second = A() 1331result = min(first, second, key=lambda x: 1) is first 1332)") 1333 .isError()); 1334 EXPECT_EQ(mainModuleAt(runtime_, "result"), Bool::trueObj()); 1335} 1336 1337TEST_F(BuiltinsModuleTest, MinWithoutKeyReturnsFirstOccuranceOfEqualValues) { 1338 ASSERT_FALSE(runFromCStr(runtime_, R"( 1339class A(): 1340 def __lt__(self, _): 1341 return False 1342 1343first = A() 1344second = A() 1345result = min(first, second) is first 1346)") 1347 .isError()); 1348 EXPECT_EQ(mainModuleAt(runtime_, "result"), Bool::trueObj()); 1349} 1350 1351TEST_F(BuiltinsModuleTest, MapWithNonIterableArgumentRaisesTypeError) { 1352 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "map(1,1)"), 1353 LayoutId::kTypeError, 1354 "'int' object is not iterable")); 1355} 1356 1357TEST_F(BuiltinsModuleTest, 1358 MapWithIterableDunderNextReturnsFuncAppliedElementsSequentially) { 1359 ASSERT_FALSE(runFromCStr(runtime_, R"( 1360def inc(e): 1361 return e + 1 1362 1363m = map(inc, [1,2]) 1364r0 = m.__next__() 1365r1 = m.__next__() 1366)") 1367 .isError()); 1368 EXPECT_EQ(mainModuleAt(runtime_, "r0"), SmallInt::fromWord(2)); 1369 EXPECT_EQ(mainModuleAt(runtime_, "r1"), SmallInt::fromWord(3)); 1370} 1371 1372TEST_F( 1373 BuiltinsModuleTest, 1374 MapWithMultipleIterablesDunderNextReturnsFuncAppliedElementsSequentially) { 1375 ASSERT_FALSE(runFromCStr(runtime_, R"( 1376def inc(e0, e1): 1377 return e0 + e1 1378 1379m = map(inc, [1,2], [100,200]) 1380r0 = m.__next__() 1381r1 = m.__next__() 1382)") 1383 .isError()); 1384 EXPECT_EQ(mainModuleAt(runtime_, "r0"), SmallInt::fromWord(101)); 1385 EXPECT_EQ(mainModuleAt(runtime_, "r1"), SmallInt::fromWord(202)); 1386} 1387 1388TEST_F(BuiltinsModuleTest, MapDunderNextFinishesByRaisingStopIteration) { 1389 ASSERT_FALSE(runFromCStr(runtime_, R"( 1390def inc(e): 1391 return e + 1 1392 1393m = map(inc, [1,2]) 1394m.__next__() 1395m.__next__() 1396exc_raised = False 1397try: 1398 m.__next__() 1399except StopIteration: 1400 exc_raised = True 1401)") 1402 .isError()); 1403 EXPECT_EQ(mainModuleAt(runtime_, "exc_raised"), Bool::trueObj()); 1404} 1405 1406TEST_F( 1407 BuiltinsModuleTest, 1408 MapWithMultipleIterablesDunderNextFinishesByRaisingStopIterationOnShorterOne) { 1409 ASSERT_FALSE(runFromCStr(runtime_, R"( 1410def inc(e0, e1): 1411 return e0, e1 1412 1413m = map(inc, [1,2], [100]) 1414m.__next__() 1415exc_raised = False 1416try: 1417 m.__next__() 1418except StopIteration: 1419 exc_raised = True 1420)") 1421 .isError()); 1422 EXPECT_EQ(mainModuleAt(runtime_, "exc_raised"), Bool::trueObj()); 1423} 1424 1425TEST_F(BuiltinsModuleTest, EnumerateWithNonIterableRaisesTypeError) { 1426 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, "enumerate(1.0)"), 1427 LayoutId::kTypeError, 1428 "'float' object is not iterable")); 1429} 1430 1431TEST_F(BuiltinsModuleTest, EnumerateReturnsEnumeratedTuples) { 1432 ASSERT_FALSE(runFromCStr(runtime_, R"( 1433e = enumerate([7, 3]) 1434res1 = e.__next__() 1435res2 = e.__next__() 1436exhausted = False 1437try: 1438 e.__next__() 1439except StopIteration: 1440 exhausted = True 1441)") 1442 .isError()); 1443 HandleScope scope(thread_); 1444 Object res1(&scope, mainModuleAt(runtime_, "res1")); 1445 ASSERT_TRUE(res1.isTuple()); 1446 EXPECT_EQ(Tuple::cast(*res1).at(0), SmallInt::fromWord(0)); 1447 EXPECT_EQ(Tuple::cast(*res1).at(1), SmallInt::fromWord(7)); 1448 Object res2(&scope, mainModuleAt(runtime_, "res2")); 1449 ASSERT_TRUE(res2.isTuple()); 1450 EXPECT_EQ(Tuple::cast(*res2).at(0), SmallInt::fromWord(1)); 1451 EXPECT_EQ(Tuple::cast(*res2).at(1), SmallInt::fromWord(3)); 1452 EXPECT_EQ(mainModuleAt(runtime_, "exhausted"), Bool::trueObj()); 1453} 1454 1455TEST_F(BuiltinsModuleTest, AbsReturnsAbsoluteValue) { 1456 ASSERT_FALSE(runFromCStr(runtime_, R"( 1457res1 = abs(10) 1458res2 = abs(-10) 1459)") 1460 .isError()); 1461 1462 HandleScope scope(thread_); 1463 Object res1(&scope, mainModuleAt(runtime_, "res1")); 1464 EXPECT_TRUE(isIntEqualsWord(*res1, 10)); 1465 Object res2(&scope, mainModuleAt(runtime_, "res2")); 1466 EXPECT_TRUE(isIntEqualsWord(*res2, 10)); 1467} 1468 1469TEST_F(BuiltinsModuleTest, AbsWithoutDunderAbsRaisesTypeError) { 1470 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1471class Foo(): pass 1472res1 = abs(Foo()) 1473)"), 1474 LayoutId::kTypeError, 1475 "bad operand type for abs(): 'Foo'")); 1476} 1477 1478} // namespace testing 1479} // namespace py