this repo has no description
at trunk 1127 lines 36 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include <memory> 3 4#include "gtest/gtest.h" 5 6#include "dict-builtins.h" 7#include "frame.h" 8#include "function-builtins.h" 9#include "int-builtins.h" 10#include "modules.h" 11#include "runtime.h" 12#include "test-utils.h" 13 14namespace py { 15namespace testing { 16 17using CallTest = RuntimeFixture; 18using TrampolinesTest = RuntimeFixture; 19 20TEST_F(CallTest, CallBoundMethod) { 21 HandleScope scope(thread_); 22 ASSERT_FALSE(runFromCStr(runtime_, R"( 23def func(self): 24 return self 25 26def test(callable): 27 return callable() 28)") 29 .isError()); 30 31 Object function(&scope, mainModuleAt(runtime_, "func")); 32 ASSERT_TRUE(function.isFunction()); 33 34 Object self(&scope, SmallInt::fromWord(1111)); 35 BoundMethod method(&scope, runtime_->newBoundMethod(function, self)); 36 37 Object test(&scope, mainModuleAt(runtime_, "test")); 38 ASSERT_TRUE(test.isFunction()); 39 Function func(&scope, *test); 40 41 Object result(&scope, Interpreter::call1(thread_, func, method)); 42 EXPECT_TRUE(isIntEqualsWord(*result, 1111)); 43} 44 45TEST_F(CallTest, CallBoundMethodWithArgs) { 46 HandleScope scope(thread_); 47 ASSERT_FALSE(runFromCStr(runtime_, R"( 48def func(self, a, b): 49 return [self, a, b] 50 51def test(callable): 52 return callable(2222, 3333) 53)") 54 .isError()); 55 56 Object function(&scope, mainModuleAt(runtime_, "func")); 57 ASSERT_TRUE(function.isFunction()); 58 59 Object self(&scope, SmallInt::fromWord(1111)); 60 BoundMethod method(&scope, runtime_->newBoundMethod(function, self)); 61 62 Object test(&scope, mainModuleAt(runtime_, "test")); 63 ASSERT_TRUE(test.isFunction()); 64 Function func(&scope, *test); 65 66 Object result(&scope, Interpreter::call1(thread_, func, method)); 67 EXPECT_PYLIST_EQ(result, {1111, 2222, 3333}); 68} 69 70TEST_F(CallTest, CallBoundMethodKw) { 71 HandleScope scope(thread_); 72 ASSERT_FALSE(runFromCStr(runtime_, R"( 73result_self = None 74result_a = None 75result_b = None 76 77def func(self, a, b): 78 global result_self, result_a, result_b 79 result_self = self 80 result_a = a 81 result_b = b 82 83def test(callable): 84 return callable(a=2222, b=3333) 85)") 86 .isError()); 87 88 Object function(&scope, mainModuleAt(runtime_, "func")); 89 ASSERT_TRUE(function.isFunction()); 90 91 Object self(&scope, SmallInt::fromWord(1111)); 92 BoundMethod method(&scope, runtime_->newBoundMethod(function, self)); 93 94 Object test(&scope, mainModuleAt(runtime_, "test")); 95 ASSERT_TRUE(test.isFunction()); 96 Function func(&scope, *test); 97 Tuple args(&scope, runtime_->newTupleWith1(method)); 98 callFunction(func, args); 99 100 Object result_self(&scope, mainModuleAt(runtime_, "result_self")); 101 EXPECT_TRUE(isIntEqualsWord(*result_self, 1111)); 102 103 Object result_a(&scope, mainModuleAt(runtime_, "result_a")); 104 EXPECT_TRUE(isIntEqualsWord(*result_a, 2222)); 105 106 Object result_b(&scope, mainModuleAt(runtime_, "result_b")); 107 EXPECT_TRUE(isIntEqualsWord(*result_b, 3333)); 108} 109 110TEST_F(CallTest, CallBoundMethodExArgs) { 111 HandleScope scope(thread_); 112 ASSERT_FALSE(runFromCStr(runtime_, R"( 113result_self = None 114result_a = None 115result_b = None 116 117def func(self, a, b): 118 global result_self, result_a, result_b 119 result_self = self 120 result_a = a 121 result_b = b 122 123def test(callable): 124 args = (2222, 3333) 125 return callable(*args) 126)") 127 .isError()); 128 129 Object function(&scope, mainModuleAt(runtime_, "func")); 130 ASSERT_TRUE(function.isFunction()); 131 132 Object self(&scope, SmallInt::fromWord(1111)); 133 BoundMethod method(&scope, runtime_->newBoundMethod(function, self)); 134 135 Object test(&scope, mainModuleAt(runtime_, "test")); 136 ASSERT_TRUE(test.isFunction()); 137 Function func(&scope, *test); 138 Tuple args(&scope, runtime_->newTupleWith1(method)); 139 callFunction(func, args); 140 141 Object result_self(&scope, mainModuleAt(runtime_, "result_self")); 142 EXPECT_TRUE(isIntEqualsWord(*result_self, 1111)); 143 144 Object result_a(&scope, mainModuleAt(runtime_, "result_a")); 145 EXPECT_TRUE(isIntEqualsWord(*result_a, 2222)); 146 147 Object result_b(&scope, mainModuleAt(runtime_, "result_b")); 148 EXPECT_TRUE(isIntEqualsWord(*result_b, 3333)); 149} 150 151TEST_F(CallTest, CallBoundMethodExKwargs) { 152 HandleScope scope(thread_); 153 ASSERT_FALSE(runFromCStr(runtime_, R"( 154result_self = None 155result_a = None 156result_b = None 157 158def func(self, a, b): 159 global result_self, result_a, result_b 160 result_self = self 161 result_a = a 162 result_b = b 163 164def test(callable): 165 kwargs = {'a': 2222, 'b': 3333} 166 return callable(**kwargs) 167)") 168 .isError()); 169 170 Object function(&scope, mainModuleAt(runtime_, "func")); 171 ASSERT_TRUE(function.isFunction()); 172 173 Object self(&scope, SmallInt::fromWord(1111)); 174 BoundMethod method(&scope, runtime_->newBoundMethod(function, self)); 175 176 Object test(&scope, mainModuleAt(runtime_, "test")); 177 ASSERT_TRUE(test.isFunction()); 178 Function func(&scope, *test); 179 Tuple args(&scope, runtime_->newTupleWith1(method)); 180 callFunction(func, args); 181 182 Object result_self(&scope, mainModuleAt(runtime_, "result_self")); 183 EXPECT_TRUE(isIntEqualsWord(*result_self, 1111)); 184 185 Object result_a(&scope, mainModuleAt(runtime_, "result_a")); 186 EXPECT_TRUE(isIntEqualsWord(*result_a, 2222)); 187 188 Object result_b(&scope, mainModuleAt(runtime_, "result_b")); 189 EXPECT_TRUE(isIntEqualsWord(*result_b, 3333)); 190} 191 192TEST_F(CallTest, CallBoundMethodExArgsAndKwargs) { 193 HandleScope scope(thread_); 194 ASSERT_FALSE(runFromCStr(runtime_, R"( 195result_self = None 196result_a = None 197result_b = None 198 199def func(self, a, b): 200 global result_self, result_a, result_b 201 result_self = self 202 result_a = a 203 result_b = b 204 205def test(callable): 206 args = (2222,) 207 kwargs = {'b': 3333} 208 return callable(*args, **kwargs) 209)") 210 .isError()); 211 212 Object function(&scope, mainModuleAt(runtime_, "func")); 213 ASSERT_TRUE(function.isFunction()); 214 215 Object self(&scope, SmallInt::fromWord(1111)); 216 BoundMethod method(&scope, runtime_->newBoundMethod(function, self)); 217 218 Object test(&scope, mainModuleAt(runtime_, "test")); 219 ASSERT_TRUE(test.isFunction()); 220 Function func(&scope, *test); 221 Tuple args(&scope, runtime_->newTupleWith1(method)); 222 callFunction(func, args); 223 224 Object result_self(&scope, mainModuleAt(runtime_, "result_self")); 225 EXPECT_TRUE(isIntEqualsWord(*result_self, 1111)); 226 227 Object result_a(&scope, mainModuleAt(runtime_, "result_a")); 228 EXPECT_TRUE(isIntEqualsWord(*result_a, 2222)); 229 230 Object result_b(&scope, mainModuleAt(runtime_, "result_b")); 231 EXPECT_TRUE(isIntEqualsWord(*result_b, 3333)); 232} 233 234TEST_F(CallTest, CallDefaultArgs) { 235 ASSERT_FALSE(runFromCStr(runtime_, R"( 236def foo(a=1, b=2, c=3): 237 return [a, b, c] 238 239result0 = foo(33, 22, 11) 240result1 = foo() 241result2 = foo(1001) 242result3 = foo(1001, 1002) 243result4 = foo(1001, 1002, 1003) 244)") 245 .isError()); 246 HandleScope scope(thread_); 247 Object result0(&scope, mainModuleAt(runtime_, "result0")); 248 EXPECT_PYLIST_EQ(result0, {33, 22, 11}); 249 Object result1(&scope, mainModuleAt(runtime_, "result1")); 250 EXPECT_PYLIST_EQ(result1, {1, 2, 3}); 251 Object result2(&scope, mainModuleAt(runtime_, "result2")); 252 EXPECT_PYLIST_EQ(result2, {1001, 2, 3}); 253 Object result3(&scope, mainModuleAt(runtime_, "result3")); 254 EXPECT_PYLIST_EQ(result3, {1001, 1002, 3}); 255 Object result4(&scope, mainModuleAt(runtime_, "result4")); 256 EXPECT_PYLIST_EQ(result4, {1001, 1002, 1003}); 257} 258 259TEST_F(CallTest, CallMethodMixPosDefaultArgs) { 260 ASSERT_FALSE(runFromCStr(runtime_, R"( 261def foo(a, b=2): 262 return [a, b] 263result = foo(1) 264)") 265 .isError()); 266 HandleScope scope(thread_); 267 Object result(&scope, mainModuleAt(runtime_, "result")); 268 EXPECT_PYLIST_EQ(result, {1, 2}); 269} 270 271TEST_F(CallTest, CallBoundMethodMixed) { 272 ASSERT_FALSE(runFromCStr(runtime_, R"( 273class R: 274 def m(self, a, b=2): 275 return [a, b] 276r = R() 277result = r.m(9) 278)") 279 .isError()); 280 HandleScope scope(thread_); 281 Object result(&scope, mainModuleAt(runtime_, "result")); 282 EXPECT_PYLIST_EQ(result, {9, 2}); 283} 284 285TEST_F(CallTest, SingleKW) { 286 ASSERT_FALSE(runFromCStr(runtime_, R"( 287def foo(bar): 288 return bar 289result = foo(bar=2) 290)") 291 .isError()); 292 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 2)); 293} 294 295TEST_F(CallTest, MixedKW) { 296 ASSERT_FALSE(runFromCStr(runtime_, R"( 297def foo(a, b, c): 298 return [a, b, c] 299result = foo(1, b = 2, c = 3) 300)") 301 .isError()); 302 HandleScope scope(thread_); 303 Object result(&scope, mainModuleAt(runtime_, "result")); 304 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 305} 306 307TEST_F(CallTest, FullKW) { 308 ASSERT_FALSE(runFromCStr(runtime_, R"( 309def foo(a, b, c): 310 return [a, b, c] 311result = foo(a = 1, b = 2, c = 3) 312)") 313 .isError()); 314 HandleScope scope(thread_); 315 Object result(&scope, mainModuleAt(runtime_, "result")); 316 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 317} 318 319TEST_F(CallTest, KWOutOfOrder1) { 320 ASSERT_FALSE(runFromCStr(runtime_, R"( 321def foo(a, b, c): 322 return [a, b, c] 323result = foo(c = 3, a = 1, b = 2) 324)") 325 .isError()); 326 HandleScope scope(thread_); 327 Object result(&scope, mainModuleAt(runtime_, "result")); 328 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 329} 330 331TEST_F(CallTest, KWOutOfOrder2) { 332 ASSERT_FALSE(runFromCStr(runtime_, R"( 333def foo(a, b, c): 334 return [a, b, c] 335result = foo(1, c = 3, b = 2) 336)") 337 .isError()); 338 HandleScope scope(thread_); 339 Object result(&scope, mainModuleAt(runtime_, "result")); 340 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 341} 342 343TEST_F(CallTest, KeywordOnly1) { 344 ASSERT_FALSE(runFromCStr(runtime_, R"( 345def foo(a,b, *, c): 346 return [a,b,c] 347result = foo(1, 2, c = 3) 348)") 349 .isError()); 350 HandleScope scope(thread_); 351 Object result(&scope, mainModuleAt(runtime_, "result")); 352 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 353} 354 355TEST_F(CallTest, KeywordOnly2) { 356 ASSERT_FALSE(runFromCStr(runtime_, R"( 357def foo(a,b, *, c): 358 return [a,b,c] 359result = foo(1, b = 2, c = 3) 360)") 361 .isError()); 362 HandleScope scope(thread_); 363 Object result(&scope, mainModuleAt(runtime_, "result")); 364 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 365} 366 367TEST_F(CallTest, KeyWordDefaults) { 368 ASSERT_FALSE(runFromCStr(runtime_, R"( 369def foo(a, b = 22, c = 33): 370 return [a,b,c] 371result = foo(11, c = 3) 372)") 373 .isError()); 374 HandleScope scope(thread_); 375 Object result(&scope, mainModuleAt(runtime_, "result")); 376 EXPECT_PYLIST_EQ(result, {11, 22, 3}); 377} 378 379TEST_F(CallTest, VarArgsWithExcess) { 380 ASSERT_FALSE(runFromCStr(runtime_, R"( 381def foo(a, b, *c): 382 return [a,b,c] 383result = foo(1,2,3,4,5,6) 384)") 385 .isError()); 386 HandleScope scope(thread_); 387 List result(&scope, mainModuleAt(runtime_, "result")); 388 EXPECT_TRUE(isIntEqualsWord(result.at(0), 1)); 389 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2)); 390 Tuple tuple(&scope, result.at(2)); 391 ASSERT_EQ(tuple.length(), 4); 392 EXPECT_TRUE(isIntEqualsWord(tuple.at(0), 3)); 393 EXPECT_TRUE(isIntEqualsWord(tuple.at(1), 4)); 394 EXPECT_TRUE(isIntEqualsWord(tuple.at(2), 5)); 395 EXPECT_TRUE(isIntEqualsWord(tuple.at(3), 6)); 396} 397 398TEST_F(CallTest, VarArgsEmpty) { 399 ASSERT_FALSE(runFromCStr(runtime_, R"( 400def foo(a, b, *c): 401 return [a,b,c] 402result = foo(1,2) 403)") 404 .isError()); 405 HandleScope scope(thread_); 406 List result(&scope, mainModuleAt(runtime_, "result")); 407 EXPECT_TRUE(isIntEqualsWord(result.at(0), 1)); 408 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2)); 409 Tuple tuple(&scope, result.at(2)); 410 EXPECT_EQ(tuple.length(), 0); 411} 412 413TEST_F(CallTest, CallWithKeywordsCalleeWithVarkeyword) { 414 ASSERT_FALSE(runFromCStr(runtime_, R"( 415def foo(a,b,c,**d): 416 return [a,b,c,d] 417result = foo(1,2,c=3,g=4,h=5,j="bar") 418)") 419 .isError()); 420 HandleScope scope(thread_); 421 List result(&scope, testing::mainModuleAt(runtime_, "result")); 422 EXPECT_TRUE(isIntEqualsWord(result.at(0), 1)); 423 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2)); 424 EXPECT_TRUE(isIntEqualsWord(result.at(2), 3)); 425 426 Dict dict(&scope, result.at(3)); 427 Str name_g(&scope, runtime_->newStrFromCStr("g")); 428 EXPECT_TRUE(isIntEqualsWord(dictAtByStr(thread_, dict, name_g), 4)); 429 Str name_h(&scope, runtime_->newStrFromCStr("h")); 430 EXPECT_TRUE(isIntEqualsWord(dictAtByStr(thread_, dict, name_h), 5)); 431 Str name_j(&scope, runtime_->newStrFromCStr("j")); 432 EXPECT_TRUE(isStrEqualsCStr(dictAtByStr(thread_, dict, name_j), "bar")); 433} 434 435TEST_F(CallTest, CallWithNoArgsCalleeDefaultArgsVarargsVarkeyargs) { 436 ASSERT_FALSE(runFromCStr(runtime_, R"( 437def bar(a=1, b=2, *c, **d): 438 return [a,b,c,d] 439result = bar() 440)") 441 .isError()); 442 HandleScope scope(thread_); 443 List result(&scope, testing::mainModuleAt(runtime_, "result")); 444 EXPECT_TRUE(isIntEqualsWord(result.at(0), 1)); 445 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2)); 446 Tuple tuple(&scope, result.at(2)); 447 EXPECT_EQ(tuple.length(), 0); 448 Dict dict(&scope, result.at(3)); 449 EXPECT_EQ(dict.numItems(), 0); 450} 451 452TEST_F(CallTest, CallPositionalCalleeVargsEmptyVarkeyargs) { 453 ASSERT_FALSE(runFromCStr(runtime_, R"( 454def bar(a=1, b=2, *c, **d): 455 return [a,b,c,d] 456result = bar(1,2,3,4,5,6,7) 457)") 458 .isError()); 459 HandleScope scope(thread_); 460 List result(&scope, testing::mainModuleAt(runtime_, "result")); 461 EXPECT_TRUE(isIntEqualsWord(result.at(0), 1)); 462 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2)); 463 Tuple tuple(&scope, result.at(2)); 464 ASSERT_EQ(tuple.length(), 5); 465 EXPECT_TRUE(isIntEqualsWord(tuple.at(0), 3)); 466 EXPECT_TRUE(isIntEqualsWord(tuple.at(1), 4)); 467 EXPECT_TRUE(isIntEqualsWord(tuple.at(2), 5)); 468 EXPECT_TRUE(isIntEqualsWord(tuple.at(3), 6)); 469 EXPECT_TRUE(isIntEqualsWord(tuple.at(4), 7)); 470 Dict dict(&scope, result.at(3)); 471 EXPECT_EQ(dict.numItems(), 0); 472} 473 474TEST_F(CallTest, CallWithKeywordsCalleeEmptyVarargsFullVarkeyargs) { 475 ASSERT_FALSE(runFromCStr(runtime_, R"( 476def bar(a=1, b=2, *c, **d): 477 return [a,b,c,d] 478result = bar(a1=11, a2=12, a3=13) 479)") 480 .isError()); 481 HandleScope scope(thread_); 482 List result(&scope, testing::mainModuleAt(runtime_, "result")); 483 EXPECT_TRUE(isIntEqualsWord(result.at(0), 1)); 484 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2)); 485 486 Object tuple_obj(&scope, result.at(2)); 487 ASSERT_TRUE(tuple_obj.isTuple()); 488 Tuple tuple(&scope, *tuple_obj); 489 EXPECT_EQ(tuple.length(), 0); 490 491 Dict dict(&scope, result.at(3)); 492 Str name0(&scope, runtime_->newStrFromCStr("a3")); 493 EXPECT_TRUE(isIntEqualsWord(dictAtByStr(thread_, dict, name0), 13)); 494 Str name1(&scope, runtime_->newStrFromCStr("a1")); 495 EXPECT_TRUE(isIntEqualsWord(dictAtByStr(thread_, dict, name1), 11)); 496 Str name2(&scope, runtime_->newStrFromCStr("a2")); 497 EXPECT_TRUE(isIntEqualsWord(dictAtByStr(thread_, dict, name2), 12)); 498} 499 500TEST_F(CallTest, CallWithKeywordsCalleeFullVarargsFullVarkeyargs) { 501 ASSERT_FALSE(runFromCStr(runtime_, R"( 502def bar(a=1, b=2, *c, **d): 503 return [a,b,c,d] 504result = bar(1,2,3,4,5,6,7,a9=9) 505)") 506 .isError()); 507 HandleScope scope(thread_); 508 List result(&scope, testing::mainModuleAt(runtime_, "result")); 509 EXPECT_TRUE(isIntEqualsWord(result.at(0), 1)); 510 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2)); 511 512 Tuple tuple(&scope, result.at(2)); 513 EXPECT_TRUE(isIntEqualsWord(tuple.at(0), 3)); 514 EXPECT_TRUE(isIntEqualsWord(tuple.at(1), 4)); 515 EXPECT_TRUE(isIntEqualsWord(tuple.at(2), 5)); 516 EXPECT_TRUE(isIntEqualsWord(tuple.at(3), 6)); 517 EXPECT_TRUE(isIntEqualsWord(tuple.at(4), 7)); 518 519 Dict dict(&scope, result.at(3)); 520 Str name_g(&scope, runtime_->newStrFromCStr("a9")); 521 EXPECT_TRUE(isIntEqualsWord(dictAtByStr(thread_, dict, name_g), 9)); 522} 523 524TEST_F(CallTest, CallWithOutOfOrderKeywords) { 525 ASSERT_FALSE(runFromCStr(runtime_, R"( 526def foobar(a,b,*,c): 527 return [a,b,c] 528result = foobar(c=3,a=1,b=2) 529)") 530 .isError()); 531 HandleScope scope(thread_); 532 Object result(&scope, mainModuleAt(runtime_, "result")); 533 EXPECT_PYLIST_EQ(result, {1, 2, 3}); 534} 535 536TEST_F(CallTest, CallWithKeywordsCalleeVarargsKeywordOnly) { 537 ASSERT_FALSE(runFromCStr(runtime_, R"( 538def foobar1(a,b,*c,d): 539 return [a,b,c,d] 540result = foobar1(1,2,3,4,5,d=9) 541)") 542 .isError()); 543 HandleScope scope(thread_); 544 List result(&scope, mainModuleAt(runtime_, "result")); 545 EXPECT_TRUE(isIntEqualsWord(result.at(0), 1)); 546 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2)); 547 Tuple tuple(&scope, result.at(2)); 548 ASSERT_EQ(tuple.length(), 3); 549 EXPECT_TRUE(isIntEqualsWord(tuple.at(0), 3)); 550 EXPECT_TRUE(isIntEqualsWord(tuple.at(1), 4)); 551 EXPECT_TRUE(isIntEqualsWord(tuple.at(2), 5)); 552 EXPECT_TRUE(isIntEqualsWord(result.at(3), 9)); 553} 554 555TEST_F(CallTest, CallWithKeywordsCalleeVarargsVarkeyargsKeywordOnly) { 556 ASSERT_FALSE(runFromCStr(runtime_, R"( 557def foobar2(a,b,*c, e, **d): 558 return [a,b,c,d,e] 559result = foobar2(1,e=9,b=2,f1="a",f11=12) 560)") 561 .isError()); 562 HandleScope scope(thread_); 563 List result(&scope, mainModuleAt(runtime_, "result")); 564 EXPECT_TRUE(isIntEqualsWord(result.at(0), 1)); 565 EXPECT_TRUE(isIntEqualsWord(result.at(1), 2)); 566 Tuple tuple(&scope, result.at(2)); 567 ASSERT_EQ(tuple.length(), 0); 568 Dict dict(&scope, result.at(3)); 569 Str f1(&scope, runtime_->newStrFromCStr("f1")); 570 EXPECT_TRUE(isStrEqualsCStr(dictAtByStr(thread_, dict, f1), "a")); 571 Str f11(&scope, runtime_->newStrFromCStr("f11")); 572 EXPECT_TRUE(isIntEqualsWord(dictAtByStr(thread_, dict, f11), 12)); 573 EXPECT_TRUE(isIntEqualsWord(result.at(4), 9)); 574} 575 576TEST_F(CallTest, CallEx) { 577 ASSERT_FALSE(runFromCStr(runtime_, R"( 578def foo(a,b,c,d): 579 return [a,b,c,d] 580a = (1,2,3,4) 581result = foo(*a) 582)") 583 .isError()); 584 HandleScope scope(thread_); 585 Object result(&scope, mainModuleAt(runtime_, "result")); 586 EXPECT_PYLIST_EQ(result, {1, 2, 3, 4}); 587} 588 589TEST_F(CallTest, CallExBuildTupleUnpackWithCall) { 590 ASSERT_FALSE(runFromCStr(runtime_, R"( 591def foo(a,b,c,d): 592 return [a,b,c,d] 593a = (3,4) 594result = foo(1,2,*a) 595)") 596 .isError()); 597 HandleScope scope(thread_); 598 Object result(&scope, mainModuleAt(runtime_, "result")); 599 EXPECT_PYLIST_EQ(result, {1, 2, 3, 4}); 600} 601 602TEST_F(CallTest, CallExKw) { 603 ASSERT_FALSE(runFromCStr(runtime_, R"( 604def foo(a,b,c,d): 605 return [a,b,c,d] 606a = {'d': 4, 'b': 2, 'a': 1, 'c': 3} 607result = foo(**a) 608)") 609 .isError()); 610 HandleScope scope(thread_); 611 Object result(&scope, mainModuleAt(runtime_, "result")); 612 EXPECT_PYLIST_EQ(result, {1, 2, 3, 4}); 613} 614 615TEST_F(CallTest, KeywordOnly) { 616 const char* src = R"( 617def foo(a,b, *, c): 618 print(a,b,c) 619foo(1, 2, 3); 620)"; 621 EXPECT_TRUE(raised(runFromCStr(runtime_, src), LayoutId::kTypeError)); 622} 623 624TEST_F(CallTest, MissingKeyword) { 625 const char* src = R"( 626def foo(a,b, *, c): 627 print(a,b,c) 628foo(1, 2); 629)"; 630 EXPECT_TRUE(raised(runFromCStr(runtime_, src), LayoutId::kTypeError)); 631} 632 633TEST_F(CallTest, ArgNameMismatch) { 634 const char* src = R"( 635def foo(a,b, *, c): 636 print(a,b,c) 637foo(1, d = 2, c = 3); 638)"; 639 EXPECT_TRUE(raised(runFromCStr(runtime_, src), LayoutId::kTypeError)); 640} 641 642TEST_F(CallTest, TooManyKWArgs) { 643 const char* src = R"( 644def foo(a,b, *, c): 645 print(a,b,c) 646foo(1, 2, 4, c = 3); 647)"; 648 EXPECT_TRUE(raised(runFromCStr(runtime_, src), LayoutId::kTypeError)); 649} 650 651TEST_F(CallTest, TooManyArgs) { 652 const char* src = R"( 653def foo(a,b, c): 654 print(a,b,c) 655foo(1, 2, 3, 4); 656)"; 657 EXPECT_TRUE(raised(runFromCStr(runtime_, src), LayoutId::kTypeError)); 658} 659 660TEST_F(CallTest, TooFewArgs) { 661 const char* src = R"( 662def foo(a,b, c): 663 print(a,b,c) 664foo(3, 4); 665)"; 666 EXPECT_TRUE(raised(runFromCStr(runtime_, src), LayoutId::kTypeError)); 667} 668 669static ALIGN_16 RawObject builtinReturnSecondArg(Thread*, Arguments args) { 670 return args.get(1); 671} 672 673static void createAndPatchBuiltinReturnSecondArg(Runtime* runtime) { 674 // Ensure we have a __main__ module. 675 ASSERT_FALSE(runFromCStr(runtime, "").isError()); 676 // def dummy(first, second): 677 const char* parameter_names[] = {"first", "second"}; 678 addBuiltin("dummy", builtinReturnSecondArg, parameter_names, 0); 679} 680 681TEST_F(TrampolinesTest, BuiltinTrampolineKwPassesKwargs) { 682 HandleScope scope(thread_); 683 createAndPatchBuiltinReturnSecondArg(runtime_); 684 ASSERT_FALSE(runFromCStr(runtime_, "result = dummy(second=12345, first=None)") 685 .isError()); 686 Object result(&scope, mainModuleAt(runtime_, "result")); 687 EXPECT_TRUE(isIntEqualsWord(*result, 12345)); 688} 689 690TEST_F(TrampolinesTest, BuiltinTrampolineKwWithInvalidArgRaisesTypeError) { 691 createAndPatchBuiltinReturnSecondArg(runtime_); 692 EXPECT_TRUE(raisedWithStr( 693 runFromCStr(runtime_, "dummy(third=3, first=1)"), LayoutId::kTypeError, 694 "dummy() got an unexpected keyword argument 'third'")); 695} 696 697TEST_F(TrampolinesTest, InterpreterClosureUsesArgOverCellValue) { 698 HandleScope scope(thread_); 699 700 // Create code object 701 word nlocals = 1; 702 Object bar(&scope, Runtime::internStrFromCStr(thread_, "bar")); 703 Tuple varnames(&scope, runtime_->newTupleWithN(nlocals, &bar)); 704 Tuple cellvars(&scope, runtime_->newTupleWith1(bar)); 705 const byte bytecode[] = {LOAD_CLOSURE, 0, LOAD_DEREF, 0, RETURN_VALUE, 0}; 706 Bytes bc(&scope, runtime_->newBytesWithAll(bytecode)); 707 Tuple empty_tuple(&scope, runtime_->emptyTuple()); 708 Object empty_str(&scope, Str::empty()); 709 Object empty_bytes(&scope, Bytes::empty()); 710 word flags = Code::Flags::kOptimized | Code::Flags::kNewlocals; 711 Code code(&scope, 712 runtime_->newCode(/*argcount=*/1, /*posonlyargcount=*/0, 713 /*kwonlyargcount=*/0, nlocals, /*stacksize=*/0, 714 flags, /*code=*/bc, /*consts=*/empty_tuple, 715 /*names=*/empty_tuple, varnames, 716 /*freevars=*/empty_tuple, cellvars, 717 /*filename=*/empty_str, /*name=*/empty_str, 718 /*firstlineno=*/0, /*lnotab=*/empty_bytes)); 719 ASSERT_TRUE(!code.cell2arg().isNoneType()); 720 721 Object qualname(&scope, runtime_->newStrFromCStr("foo")); 722 Module module(&scope, findMainModule(runtime_)); 723 Function foo(&scope, 724 runtime_->newFunctionWithCode(thread_, qualname, code, module)); 725 Object obj(&scope, runtime_->newInt(99)); 726 Tuple closure_tuple(&scope, runtime_->newTupleWith1(obj)); 727 foo.setClosure(*closure_tuple); 728 729 Object argument(&scope, runtime_->newInt(3)); 730 EXPECT_TRUE(isIntEqualsWord(Interpreter::call1(thread_, foo, argument), 3)); 731} 732 733TEST_F(TrampolinesTest, InterpreterClosureUsesCellValue) { 734 HandleScope scope(thread_); 735 ASSERT_FALSE(runFromCStr(runtime_, R"( 736def foo(arg): 737 def bar(): 738 return arg * 3 739 arg = 5 740 return bar() 741 742result = foo(-2) 743)") 744 .isError()); 745 Function foo(&scope, mainModuleAt(runtime_, "foo")); 746 ASSERT_EQ(foo.entry(), &interpreterTrampoline); 747 // Ensure that cellvar was populated. 748 Code code(&scope, foo.code()); 749 ASSERT_TRUE(!code.cell2arg().isNoneType()); 750 Tuple cellvars(&scope, code.cellvars()); 751 ASSERT_EQ(cellvars.length(), 1); 752 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 15)); 753} 754 755static RawObject makeFunctionWithPosOnlyArg(Thread* thread) { 756 // Create: 757 // def foo(a, /, b): 758 // return (a, b) 759 HandleScope scope(thread); 760 Runtime* runtime = thread->runtime(); 761 Object name(&scope, Runtime::internStrFromCStr(thread, "foo")); 762 const byte bytecode[] = {LOAD_FAST, 0, LOAD_FAST, 1, 763 BUILD_TUPLE, 2, RETURN_VALUE, 0}; 764 Object a(&scope, Runtime::internStrFromCStr(thread, "a")); 765 Object b(&scope, Runtime::internStrFromCStr(thread, "b")); 766 Tuple varnames(&scope, runtime->newTupleWith2(a, b)); 767 Bytes bc(&scope, runtime->newBytesWithAll(bytecode)); 768 Object empty_tuple(&scope, runtime->emptyTuple()); 769 Object empty_str(&scope, Str::empty()); 770 Object empty_bytes(&scope, Bytes::empty()); 771 Code code(&scope, 772 runtime->newCode(/*argcount=*/2, /*posonlyargcount=*/1, 773 /*kwonlyargcount=*/0, /*nlocals=*/2, 774 /*stacksize=*/2, 775 Code::Flags::kNewlocals | Code::Flags::kOptimized, 776 bc, /*consts=*/empty_tuple, 777 /*names=*/empty_tuple, varnames, 778 /*freevars=*/empty_tuple, 779 /*cellvars=*/empty_tuple, 780 /*filename=*/empty_str, name, 781 /*firstlineno=*/0, /*lnotab=*/empty_bytes)); 782 Module module(&scope, findMainModule(runtime)); 783 return runtime->newFunctionWithCode(thread, name, code, module); 784} 785 786TEST_F(TrampolinesTest, KeywordCallRejectsPositionalOnlyArgumentNames) { 787 HandleScope scope(thread_); 788 Function function(&scope, makeFunctionWithPosOnlyArg(thread_)); 789 790 // `foo(a=2, b=4)` 791 thread_->stackPush(*function); 792 thread_->stackPush(runtime_->newInt(2)); 793 thread_->stackPush(runtime_->newInt(4)); 794 Object a(&scope, Runtime::internStrFromCStr(thread_, "a")); 795 Object b(&scope, Runtime::internStrFromCStr(thread_, "b")); 796 thread_->stackPush(runtime_->newTupleWith2(a, b)); 797 Object result_obj(&scope, Interpreter::callKw(thread_, 2)); 798 EXPECT_TRUE(raisedWithStr( 799 *result_obj, LayoutId::kTypeError, 800 "keyword argument specified for positional-only argument 'a'")); 801} 802 803TEST_F(TrampolinesTest, KeywordCallAcceptsNonPositionalOnlyArgumentNames) { 804 HandleScope scope(thread_); 805 Function function(&scope, makeFunctionWithPosOnlyArg(thread_)); 806 807 // `foo(2, b=9)` 808 thread_->stackPush(*function); 809 thread_->stackPush(runtime_->newInt(2)); 810 thread_->stackPush(runtime_->newInt(9)); 811 Object b(&scope, Runtime::internStrFromCStr(thread_, "b")); 812 thread_->stackPush(runtime_->newTupleWith1(b)); 813 Object result_obj(&scope, Interpreter::callKw(thread_, 2)); 814 ASSERT_TRUE(result_obj.isTuple()); 815 Tuple result(&scope, *result_obj); 816 ASSERT_EQ(result.length(), 2); 817 EXPECT_TRUE(isIntEqualsWord(result.at(0), 2)); 818 EXPECT_TRUE(isIntEqualsWord(result.at(1), 9)); 819} 820 821TEST_F(TrampolinesTest, KeywordCallWithPositionalOnlyArgumentsAndVarKeyArgs) { 822 HandleScope scope(thread_); 823 824 // Create: 825 // def foo(a, b=7, /, c=10, **kwargs): 826 // return (a, b, c, kwargs) 827 Object name(&scope, Runtime::internStrFromCStr(thread_, "foo")); 828 const byte bytecode[] = {LOAD_FAST, 0, LOAD_FAST, 1, LOAD_FAST, 2, 829 LOAD_FAST, 3, BUILD_TUPLE, 4, RETURN_VALUE, 0}; 830 Object a(&scope, Runtime::internStrFromCStr(thread_, "a")); 831 Object b(&scope, Runtime::internStrFromCStr(thread_, "b")); 832 Object c(&scope, Runtime::internStrFromCStr(thread_, "c")); 833 Object kwargs(&scope, Runtime::internStrFromCStr(thread_, "kwargs")); 834 Tuple varnames(&scope, runtime_->newTupleWith4(a, b, c, kwargs)); 835 Bytes bc(&scope, runtime_->newBytesWithAll(bytecode)); 836 Object empty_tuple(&scope, runtime_->emptyTuple()); 837 Object empty_str(&scope, Str::empty()); 838 Object empty_bytes(&scope, Bytes::empty()); 839 Code code(&scope, runtime_->newCode( 840 /*argcount=*/3, /*posonlyargcount=*/2, 841 /*kwonlyargcount=*/0, /*nlocals=*/4, 842 /*stacksize=*/4, 843 Code::Flags::kNewlocals | Code::Flags::kOptimized | 844 Code::Flags::kVarkeyargs, 845 bc, 846 /*consts=*/empty_tuple, 847 /*names=*/empty_tuple, varnames, 848 /*freevars=*/empty_tuple, 849 /*cellvars=*/empty_tuple, 850 /*filename=*/empty_str, name, 851 /*firstlineno=*/0, /*lnotab=*/empty_bytes)); 852 Module module(&scope, findMainModule(runtime_)); 853 Function foo(&scope, 854 runtime_->newFunctionWithCode(thread_, name, code, module)); 855 Object seven(&scope, runtime_->newInt(7)); 856 Object ten(&scope, runtime_->newInt(10)); 857 foo.setDefaults(runtime_->newTupleWith2(seven, ten)); 858 // Call foo(1, c=13, b=5). 859 thread_->stackPush(*foo); 860 thread_->stackPush(runtime_->newInt(1)); 861 thread_->stackPush(runtime_->newInt(13)); 862 thread_->stackPush(runtime_->newInt(5)); 863 thread_->stackPush(runtime_->newTupleWith2(c, b)); 864 Object result_obj(&scope, Interpreter::callKw(thread_, 3)); 865 866 // Expect a `(1, 7, 13, {'b': 5})` result. 867 ASSERT_TRUE(result_obj.isTuple()); 868 Tuple result(&scope, *result_obj); 869 ASSERT_EQ(result.length(), 4); 870 EXPECT_TRUE(isIntEqualsWord(result.at(0), 1)); 871 EXPECT_TRUE(isIntEqualsWord(result.at(1), 7)); 872 EXPECT_TRUE(isIntEqualsWord(result.at(2), 13)); 873 ASSERT_TRUE(result.at(3).isDict()); 874 Dict result_dict(&scope, result.at(3)); 875 EXPECT_EQ(result_dict.numItems(), 1); 876 Object b_name(&scope, Runtime::internStrFromCStr(thread_, "b")); 877 EXPECT_TRUE(isIntEqualsWord(dictAtByStr(thread_, result_dict, b_name), 5)); 878} 879 880TEST_F(TrampolinesTest, ExplodeCallWithBadKeywordFails) { 881 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 882def take_kwargs(a): pass 883 884kwargs = {12: 34} 885take_kwargs(**kwargs) 886)"), 887 LayoutId::kTypeError, "keywords must be strings")); 888} 889 890TEST_F(TrampolinesTest, ExplodeCallWithZeroKeywords) { 891 ASSERT_FALSE(runFromCStr(runtime_, R"( 892def foo(a=10): return a 893result = foo(**{}) 894)") 895 .isError()); 896 HandleScope scope(thread_); 897 Object result(&scope, mainModuleAt(runtime_, "result")); 898 EXPECT_EQ(result, SmallInt::fromWord(10)); 899} 900 901static ALIGN_16 RawObject numArgs(Thread* thread, Arguments) { 902 return SmallInt::fromWord(thread->currentFrame()->function().totalArgs()); 903} 904 905static void createAndPatchBuiltinNumArgs(Runtime* runtime) { 906 // Ensure we have a __main__ module. 907 ASSERT_FALSE(runFromCStr(runtime, "").isError()); 908 // def dummy(first, second): 909 const char* parameter_names[] = {"first", "second"}; 910 addBuiltin("dummy", numArgs, parameter_names, 0); 911} 912 913TEST_F(TrampolinesTest, BuiltinTrampolineExReceivesExArgs) { 914 createAndPatchBuiltinNumArgs(runtime_); 915 HandleScope scope(thread_); 916 ASSERT_FALSE(runFromCStr(runtime_, "result = dummy(*(1,2))").isError()); 917 Object result(&scope, mainModuleAt(runtime_, "result")); 918 EXPECT_TRUE(isIntEqualsWord(*result, 2)); 919} 920 921TEST_F(TrampolinesTest, BuiltinTrampolineExReceivesMixOfPositionalAndExArgs1) { 922 createAndPatchBuiltinNumArgs(runtime_); 923 HandleScope scope(thread_); 924 ASSERT_FALSE(runFromCStr(runtime_, "result = dummy(1, *(2,))").isError()); 925 Object result(&scope, mainModuleAt(runtime_, "result")); 926 EXPECT_TRUE(isIntEqualsWord(*result, 2)); 927} 928 929static void createAndPatchBuiltinNumArgsVariadic(Runtime* runtime) { 930 // Ensure we have a __main__ module. 931 ASSERT_FALSE(runFromCStr(runtime, "").isError()); 932 // def dummy(*args): 933 const char* parameter_names[] = {"args"}; 934 addBuiltin("dummy", numArgs, parameter_names, Code::Flags::kVarargs); 935} 936 937TEST_F(TrampolinesTest, 938 BuiltinTrampolineExReceivesOnePositionalArgAndTwoVariableArgs) { 939 createAndPatchBuiltinNumArgsVariadic(runtime_); 940 HandleScope scope(thread_); 941 ASSERT_FALSE(runFromCStr(runtime_, "result = dummy(1, *(2, 3))").isError()); 942 Object result(&scope, mainModuleAt(runtime_, "result")); 943 EXPECT_TRUE(isIntEqualsWord(*result, 1)); 944} 945 946static void createAndPatchBuiltinNumArgsArgsKwargs(Runtime* runtime) { 947 // Ensure we have a __main__ module. 948 ASSERT_FALSE(runFromCStr(runtime, "").isError()); 949 // def dummy(*args, **kwargs): 950 const char* parameter_names[] = {"args", "kwargs"}; 951 addBuiltin("dummy", numArgs, parameter_names, 952 Code::Flags::kVarargs | Code::Flags::kVarkeyargs); 953} 954 955TEST_F(TrampolinesTest, 956 BuiltinTrampolineExReceivesTwoPositionalOneVariableAndTwoKwArgs) { 957 createAndPatchBuiltinNumArgsArgsKwargs(runtime_); 958 HandleScope scope(thread_); 959 ASSERT_FALSE( 960 runFromCStr(runtime_, 961 "result = dummy(1, 2, *(3,), **{'foo': 1, 'bar': 2})") 962 .isError()); 963 Object result(&scope, mainModuleAt(runtime_, "result")); 964 EXPECT_TRUE(isIntEqualsWord(*result, 2)); 965} 966 967TEST_F(TrampolinesTest, BuiltinTrampolineExReceivesVarArgs) { 968 createAndPatchBuiltinNumArgs(runtime_); 969 HandleScope scope(thread_); 970 ASSERT_FALSE( 971 runFromCStr(runtime_, "result = dummy(*(1,), second=5)").isError()); 972 Object result(&scope, mainModuleAt(runtime_, "result")); 973 EXPECT_TRUE(isIntEqualsWord(*result, 2)); 974} 975 976TEST_F(TrampolinesTest, BuiltinTrampolineExWithTooFewArgsRaisesTypeError) { 977 createAndPatchBuiltinNumArgs(runtime_); 978 EXPECT_TRUE( 979 raisedWithStr(runFromCStr(runtime_, "dummy(*(1,))"), LayoutId::kTypeError, 980 "'dummy' takes min 2 positional arguments but 1 given")); 981} 982 983TEST_F(TrampolinesTest, BuiltinTrampolineExWithTooManyArgsRaisesTypeError) { 984 createAndPatchBuiltinNumArgs(runtime_); 985 EXPECT_TRUE(raisedWithStr( 986 runFromCStr(runtime_, "dummy(*(1,2,3,4,5))"), LayoutId::kTypeError, 987 "'dummy' takes max 2 positional arguments but 5 given")); 988} 989 990TEST_F(TrampolinesTest, CallFunctionExWithNamedArgAndExplodeKwargs) { 991 ASSERT_FALSE(runFromCStr(runtime_, R"( 992def f(description, conflict_handler): 993 return [description, conflict_handler] 994 995result = f(description="foo", **{"conflict_handler": "conflict_handler value"}) 996)") 997 .isError()); 998 HandleScope scope(thread_); 999 Object result(&scope, mainModuleAt(runtime_, "result")); 1000 EXPECT_PYLIST_EQ(result, {"foo", "conflict_handler value"}); 1001} 1002 1003TEST_F(TrampolinesTest, CallFunctionExWithExplodeKwargsStrSubclassAlwaysEq) { 1004 ASSERT_FALSE(runFromCStr(runtime_, R"( 1005class C(str): 1006 def __eq__(self, other): 1007 return True 1008 __hash__ = str.__hash__ 1009 1010def f(param): 1011 return param 1012 1013actual = C("foo") 1014result = f(**{actual: 5}) 1015)") 1016 .isError()); 1017 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 5)); 1018} 1019 1020TEST_F(TrampolinesTest, 1021 CallFunctionExWithExplodeKwargsStrSubclassReturnNonBool) { 1022 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1023class D: 1024 def __bool__(self): 1025 raise UserWarning('foo') 1026 1027class C(str): 1028 def __eq__(self, other): 1029 return D() 1030 __hash__ = str.__hash__ 1031 1032def f(param): 1033 return param 1034 1035actual = C("foo") 1036result = f(**{actual: 5}) 1037)"), 1038 LayoutId::kUserWarning, "foo")); 1039} 1040 1041TEST_F(TrampolinesTest, 1042 CallFunctionExWithExplodeKwargsStrSubclassRaiseException) { 1043 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1044class C(str): 1045 def __eq__(self, other): 1046 raise UserWarning('foo') 1047 __hash__ = str.__hash__ 1048 1049def f(param): 1050 return param 1051 1052actual = C("foo") 1053result = f(**{actual: 5}) 1054)"), 1055 LayoutId::kUserWarning, "foo")); 1056} 1057 1058TEST_F(TrampolinesTest, CallFunctionExWithExplodeKwargsStrSubclassNotEq) { 1059 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1060class C(str): 1061 __hash__ = str.__hash__ 1062 1063def f(param): 1064 return param 1065 1066actual = C("foo") 1067result = f(**{actual: 5}) 1068)"), 1069 LayoutId::kTypeError, 1070 "f() got an unexpected keyword argument 'foo'")); 1071} 1072 1073TEST_F(TrampolinesTest, CallFunctionExWithExplodeKwargsStrSubclassNeverEq) { 1074 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1075class C(str): 1076 def __eq__(self, other): 1077 return False 1078 __hash__ = str.__hash__ 1079 1080def f(param): 1081 return param 1082 1083actual = C("param") 1084result = f(**{actual: 5}) 1085)"), 1086 LayoutId::kTypeError, 1087 "f() got an unexpected keyword argument 'param'")); 1088} 1089 1090TEST_F(TrampolinesTest, CallFunctionWithParameterInVarnames) { 1091 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"( 1092def add_argument(*args, **kwargs): 1093 action = action_class(**kwargs) 1094 1095def init(): 1096 add_argument(action='help') 1097 1098init() 1099)"), 1100 LayoutId::kNameError, 1101 "name 'action_class' is not defined")); 1102} 1103 1104TEST_F(TrampolinesTest, CallFunctionWithParameterInVarargname) { 1105 ASSERT_FALSE(runFromCStr(runtime_, R"( 1106def test(*args, **kwargs): 1107 return kwargs['args'] 1108 1109result = test(args=5) 1110)") 1111 .isError()); 1112 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 5)); 1113} 1114 1115TEST_F(TrampolinesTest, CallFunctionWithPositionalArgAndParameterInVarargname) { 1116 ASSERT_FALSE(runFromCStr(runtime_, R"( 1117def test(pos, *args, **kwargs): 1118 return kwargs['args'] 1119 1120result = test(1, args=5) 1121)") 1122 .isError()); 1123 EXPECT_TRUE(isIntEqualsWord(mainModuleAt(runtime_, "result"), 5)); 1124} 1125 1126} // namespace testing 1127} // namespace py