this repo has no description
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com)
2#include <cmath>
3
4#include "gtest/gtest.h"
5
6#include "attributedict.h"
7#include "builtins-module.h"
8#include "builtins.h"
9#include "bytearray-builtins.h"
10#include "dict-builtins.h"
11#include "int-builtins.h"
12#include "memoryview-builtins.h"
13#include "module-builtins.h"
14#include "runtime.h"
15#include "test-utils.h"
16#include "trampolines.h"
17#include "type-builtins.h"
18
19namespace py {
20namespace testing {
21
22using UnderBuiltinsModuleTest = RuntimeFixture;
23using UnderBuiltinsModuleDeathTest = RuntimeFixture;
24
25TEST_F(UnderBuiltinsModuleTest, UnderAnysetCheckWithNonSetReturnsFalse) {
26 HandleScope scope(thread_);
27 Object obj(&scope, newTupleWithNone(1));
28 Object result(&scope, runBuiltin(FUNC(_builtins, _anyset_check), obj));
29 EXPECT_EQ(result, Bool::falseObj());
30}
31
32TEST_F(UnderBuiltinsModuleTest, UnderAnysetCheckWithSetReturnsTrue) {
33 HandleScope scope(thread_);
34 Object obj(&scope, runtime_->newSet());
35 Object result(&scope, runBuiltin(FUNC(_builtins, _anyset_check), obj));
36 EXPECT_EQ(result, Bool::trueObj());
37}
38
39TEST_F(UnderBuiltinsModuleTest, UnderAnysetCheckWithSetSubclassReturnsTrue) {
40 ASSERT_FALSE(runFromCStr(runtime_, R"(
41class C(set):
42 pass
43obj = C()
44)")
45 .isError());
46 HandleScope scope(thread_);
47 Object obj(&scope, mainModuleAt(runtime_, "obj"));
48 Object result(&scope, runBuiltin(FUNC(_builtins, _anyset_check), obj));
49 EXPECT_EQ(result, Bool::trueObj());
50}
51
52TEST_F(UnderBuiltinsModuleTest, UnderAnysetCheckWithFrozenSetReturnsTrue) {
53 HandleScope scope(thread_);
54 Object obj(&scope, runtime_->newFrozenSet());
55 Object result(&scope, runBuiltin(FUNC(_builtins, _anyset_check), obj));
56 EXPECT_EQ(result, Bool::trueObj());
57}
58
59TEST_F(UnderBuiltinsModuleTest,
60 UnderAnysetCheckWithFrozenSetSubclassReturnsTrue) {
61 ASSERT_FALSE(runFromCStr(runtime_, R"(
62class C(frozenset):
63 pass
64obj = C()
65)")
66 .isError());
67 HandleScope scope(thread_);
68 Object obj(&scope, mainModuleAt(runtime_, "obj"));
69 Object result(&scope, runBuiltin(FUNC(_builtins, _anyset_check), obj));
70 EXPECT_EQ(result, Bool::trueObj());
71}
72
73TEST_F(UnderBuiltinsModuleTest, UnderBytearrayClearSetsLengthToZero) {
74 HandleScope scope(thread_);
75 Bytearray array(&scope, runtime_->newBytearray());
76 const byte byte_array[] = {'1', '2', '3'};
77 runtime_->bytearrayExtend(thread_, array, byte_array);
78 ASSERT_EQ(array.numItems(), 3);
79 ASSERT_FALSE(runBuiltin(FUNC(_builtins, _bytearray_clear), array).isError());
80 EXPECT_EQ(array.numItems(), 0);
81}
82
83TEST_F(UnderBuiltinsModuleTest,
84 UnderBytearrayContainsWithEmptyBytearrayReturnsFalse) {
85 HandleScope scope(thread_);
86 Bytearray array(&scope, runtime_->newBytearray());
87 ASSERT_EQ(array.numItems(), 0);
88 Object key(&scope, SmallInt::fromWord('a'));
89 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytearray_contains), array, key),
90 Bool::falseObj());
91}
92
93TEST_F(UnderBuiltinsModuleTest,
94 UnderBytearrayContainsWithIntBiggerThanCharRaisesValueError) {
95 HandleScope scope(thread_);
96 Bytearray array(&scope, runtime_->newBytearray());
97 const byte byte_array[] = {'1', '2', '3'};
98 runtime_->bytearrayExtend(thread_, array, byte_array);
99 ASSERT_EQ(array.numItems(), 3);
100 Object key(&scope, SmallInt::fromWord(256));
101 EXPECT_TRUE(raisedWithStr(
102 runBuiltin(FUNC(_builtins, _bytearray_contains), array, key),
103 LayoutId::kValueError, "byte must be in range(0, 256)"));
104}
105
106TEST_F(UnderBuiltinsModuleTest,
107 UnderBytearrayContainsWithByteInBytearrayReturnsTrue) {
108 HandleScope scope(thread_);
109 Bytearray array(&scope, runtime_->newBytearray());
110 const byte byte_array[] = {'1', '2', '3'};
111 runtime_->bytearrayExtend(thread_, array, byte_array);
112 ASSERT_EQ(array.numItems(), 3);
113 Object key(&scope, SmallInt::fromWord('2'));
114 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytearray_contains), array, key),
115 Bool::trueObj());
116}
117
118TEST_F(UnderBuiltinsModuleTest,
119 UnderBytearrayContainsWithByteNotInBytearrayReturnsFalse) {
120 HandleScope scope(thread_);
121 Bytearray array(&scope, runtime_->newBytearray());
122 const byte byte_array[] = {'1', '2', '3'};
123 runtime_->bytearrayExtend(thread_, array, byte_array);
124 ASSERT_EQ(array.numItems(), 3);
125 Object key(&scope, SmallInt::fromWord('x'));
126 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytearray_contains), array, key),
127 Bool::falseObj());
128}
129
130TEST_F(UnderBuiltinsModuleTest,
131 UnderBytearrayContainsByteslikeWithBytearrayInBytearrayReturnsTrue) {
132 HandleScope scope(thread_);
133 Bytearray array(&scope, newBytearrayFromCStr(thread_, "1234"));
134 ASSERT_EQ(array.numItems(), 4);
135
136 Bytearray array_search(&scope, newBytearrayFromCStr(thread_, "23"));
137 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytearray_contains_byteslike), array,
138 array_search),
139 Bool::trueObj());
140}
141
142TEST_F(UnderBuiltinsModuleTest,
143 UnderBytearrayContainsByteslikeWithBytesInBytearrayReturnsTrue) {
144 HandleScope scope(thread_);
145 Bytearray array(&scope, newBytearrayFromCStr(thread_, "1234"));
146 ASSERT_EQ(array.numItems(), 4);
147
148 Bytes bytes_search(&scope, newBytesFromCStr(thread_, "23"));
149 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytearray_contains_byteslike), array,
150 bytes_search),
151 Bool::trueObj());
152}
153
154TEST_F(UnderBuiltinsModuleTest,
155 UnderBytearrayContainsByteslikeWithMemeoryViewInBytearrayReturnsTrue) {
156 HandleScope scope(thread_);
157 Bytearray array(&scope, newBytearrayFromCStr(thread_, "1234"));
158 ASSERT_EQ(array.numItems(), 4);
159
160 const byte view_src[] = {'2', '3'};
161 MemoryView view_search(&scope,
162 newMemoryView(view_src, "b", ReadOnly::ReadWrite));
163 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytearray_contains_byteslike), array,
164 view_search),
165 Bool::trueObj());
166}
167
168TEST_F(UnderBuiltinsModuleTest,
169 UnderBytearrayContainsByteslikeWithBytearrayNotInBytearrayReturnsFalse) {
170 HandleScope scope(thread_);
171 Bytearray array(&scope, newBytearrayFromCStr(thread_, "1234"));
172 ASSERT_EQ(array.numItems(), 4);
173
174 Bytearray array_search(&scope, newBytearrayFromCStr(thread_, "24"));
175 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytearray_contains_byteslike), array,
176 array_search),
177 Bool::falseObj());
178}
179
180TEST_F(UnderBuiltinsModuleTest,
181 UnderBytearrayContainsByteslikeWithBytesNotInBytearrayReturnsFalse) {
182 HandleScope scope(thread_);
183 Bytearray array(&scope, newBytearrayFromCStr(thread_, "1234"));
184 ASSERT_EQ(array.numItems(), 4);
185
186 Bytes bytes_search(&scope, newBytesFromCStr(thread_, "24"));
187 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytearray_contains_byteslike), array,
188 bytes_search),
189 Bool::falseObj());
190}
191
192TEST_F(
193 UnderBuiltinsModuleTest,
194 UnderBytearrayContainsByteslikeWithMemoryviewNotInBytearrayReturnsFalse) {
195 HandleScope scope(thread_);
196 Bytearray array(&scope, newBytearrayFromCStr(thread_, "1234"));
197 ASSERT_EQ(array.numItems(), 4);
198
199 const byte view_src[] = {'2', '4'};
200 MemoryView view_search(&scope,
201 newMemoryView(view_src, "b", ReadOnly::ReadWrite));
202 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytearray_contains_byteslike), array,
203 view_search),
204 Bool::falseObj());
205}
206
207TEST_F(UnderBuiltinsModuleTest, UnderBytearrayDelitemDeletesItemAtIndex) {
208 HandleScope scope(thread_);
209 Bytearray self(&scope, runtime_->newBytearray());
210 bytearrayAdd(thread_, runtime_, self, 'a');
211 bytearrayAdd(thread_, runtime_, self, 'b');
212 bytearrayAdd(thread_, runtime_, self, 'c');
213 bytearrayAdd(thread_, runtime_, self, 'd');
214 bytearrayAdd(thread_, runtime_, self, 'e');
215 Int idx(&scope, SmallInt::fromWord(2));
216 EXPECT_TRUE(
217 runBuiltin(FUNC(_builtins, _bytearray_delitem), self, idx).isNoneType());
218 EXPECT_TRUE(isBytearrayEqualsCStr(self, "abde"));
219}
220
221TEST_F(UnderBuiltinsModuleTest,
222 UnderBytearrayDelsliceWithStepEqualsOneAndNoGrowthDeletesSlice) {
223 HandleScope scope(thread_);
224 Bytearray self(&scope, runtime_->newBytearray());
225 bytearrayAdd(thread_, runtime_, self, 'a');
226 bytearrayAdd(thread_, runtime_, self, 'b');
227 bytearrayAdd(thread_, runtime_, self, 'c');
228 bytearrayAdd(thread_, runtime_, self, 'd');
229 bytearrayAdd(thread_, runtime_, self, 'e');
230 Int start(&scope, SmallInt::fromWord(0));
231 Int stop(&scope, SmallInt::fromWord(3));
232 Int step(&scope, SmallInt::fromWord(1));
233 EXPECT_TRUE(
234 runBuiltin(FUNC(_builtins, _bytearray_delslice), self, start, stop, step)
235 .isNoneType());
236 EXPECT_TRUE(isBytearrayEqualsCStr(self, "de"));
237}
238
239TEST_F(UnderBuiltinsModuleTest,
240 UnderBytearrayDelsliceWithStepEqualsTwoAndNoGrowthDeletesSlice) {
241 HandleScope scope(thread_);
242 Bytearray self(&scope, runtime_->newBytearray());
243 bytearrayAdd(thread_, runtime_, self, 'a');
244 bytearrayAdd(thread_, runtime_, self, 'b');
245 bytearrayAdd(thread_, runtime_, self, 'c');
246 bytearrayAdd(thread_, runtime_, self, 'd');
247 bytearrayAdd(thread_, runtime_, self, 'e');
248 Int start(&scope, SmallInt::fromWord(0));
249 Int stop(&scope, SmallInt::fromWord(3));
250 Int step(&scope, SmallInt::fromWord(2));
251 EXPECT_TRUE(
252 runBuiltin(FUNC(_builtins, _bytearray_delslice), self, start, stop, step)
253 .isNoneType());
254 EXPECT_TRUE(isBytearrayEqualsCStr(self, "bde"));
255}
256
257TEST_F(UnderBuiltinsModuleTest,
258 UnderBytearrayJoinWithEmptyIterableReturnsEmptyBytearray) {
259 HandleScope scope(thread_);
260 Bytearray self(&scope, runtime_->newBytearray());
261 bytearrayAdd(thread_, runtime_, self, 'a');
262 Object iter(&scope, runtime_->emptyTuple());
263 Object result(&scope,
264 runBuiltin(FUNC(_builtins, _bytearray_join), self, iter));
265 EXPECT_TRUE(isBytearrayEqualsCStr(result, ""));
266}
267
268TEST_F(UnderBuiltinsModuleTest,
269 UnderBytearrayJoinWithEmptySeparatorReturnsBytearray) {
270 HandleScope scope(thread_);
271 Bytearray self(&scope, runtime_->newBytearray());
272 Object obj1(&scope, runtime_->newBytes(1, 'A'));
273 Object obj2(&scope, runtime_->newBytes(2, 'B'));
274 Object obj3(&scope, runtime_->newBytes(1, 'A'));
275 Tuple iter(&scope, runtime_->newTupleWith3(obj1, obj2, obj3));
276 Object result(&scope,
277 runBuiltin(FUNC(_builtins, _bytearray_join), self, iter));
278 EXPECT_TRUE(isBytearrayEqualsCStr(result, "ABBA"));
279}
280
281TEST_F(UnderBuiltinsModuleTest,
282 UnderBytearrayJoinWithNonEmptyReturnsBytearray) {
283 HandleScope scope(thread_);
284 Bytearray self(&scope, runtime_->newBytearray());
285 bytearrayAdd(thread_, runtime_, self, ' ');
286 List iter(&scope, runtime_->newList());
287 Bytes value(&scope, runtime_->newBytes(1, '*'));
288 runtime_->listAdd(thread_, iter, value);
289 runtime_->listAdd(thread_, iter, value);
290 runtime_->listAdd(thread_, iter, value);
291 Object result(&scope,
292 runBuiltin(FUNC(_builtins, _bytearray_join), self, iter));
293 EXPECT_TRUE(isBytearrayEqualsCStr(result, "* * *"));
294}
295
296TEST_F(UnderBuiltinsModuleTest,
297 UnderBytearraySetitemWithLargeIntRaisesIndexError) {
298 HandleScope scope(thread_);
299 Bytearray self(&scope, runtime_->newBytearray());
300 Int key(&scope, runtime_->newInt(SmallInt::kMaxValue + 1));
301 Int value(&scope, SmallInt::fromWord(0));
302 EXPECT_TRUE(raisedWithStr(
303 runBuiltin(FUNC(_builtins, _bytearray_setitem), self, key, value),
304 LayoutId::kIndexError, "cannot fit 'int' into an index-sized integer"));
305}
306
307TEST_F(UnderBuiltinsModuleTest,
308 UnderBytearraySetitemWithKeyLargerThanMaxIndexRaisesIndexError) {
309 HandleScope scope(thread_);
310 Bytearray self(&scope, runtime_->newBytearray());
311 bytearrayAdd(thread_, runtime_, self, ' ');
312 Int key(&scope, runtime_->newInt(self.numItems()));
313 Int value(&scope, SmallInt::fromWord(0));
314 EXPECT_TRUE(raisedWithStr(
315 runBuiltin(FUNC(_builtins, _bytearray_setitem), self, key, value),
316 LayoutId::kIndexError, "index out of range"));
317}
318
319TEST_F(UnderBuiltinsModuleTest,
320 UnderBytearraySetitemWithNegativeValueRaisesValueError) {
321 HandleScope scope(thread_);
322 Bytearray self(&scope, runtime_->newBytearray());
323 bytearrayAdd(thread_, runtime_, self, ' ');
324 Int key(&scope, runtime_->newInt(0));
325 Int value(&scope, SmallInt::fromWord(-1));
326 EXPECT_TRUE(raisedWithStr(
327 runBuiltin(FUNC(_builtins, _bytearray_setitem), self, key, value),
328 LayoutId::kValueError, "byte must be in range(0, 256)"));
329}
330
331TEST_F(
332 UnderBuiltinsModuleTest,
333 UnderBytearraySetitemWithKeySmallerThanNegativeLengthValueRaisesValueError) {
334 HandleScope scope(thread_);
335 Bytearray self(&scope, runtime_->newBytearray());
336 bytearrayAdd(thread_, runtime_, self, ' ');
337 Int key(&scope, runtime_->newInt(-self.numItems() - 1));
338 Int value(&scope, SmallInt::fromWord(0));
339 EXPECT_TRUE(raisedWithStr(
340 runBuiltin(FUNC(_builtins, _bytearray_setitem), self, key, value),
341 LayoutId::kIndexError, "index out of range"));
342}
343
344TEST_F(UnderBuiltinsModuleTest,
345 UnderBytearraySetitemWithValueGreaterThanKMaxByteRaisesValueError) {
346 HandleScope scope(thread_);
347 Bytearray self(&scope, runtime_->newBytearray());
348 bytearrayAdd(thread_, runtime_, self, ' ');
349 Int key(&scope, runtime_->newInt(0));
350 Int value(&scope, SmallInt::fromWord(kMaxByte + 1));
351 EXPECT_TRUE(raisedWithStr(
352 runBuiltin(FUNC(_builtins, _bytearray_setitem), self, key, value),
353 LayoutId::kValueError, "byte must be in range(0, 256)"));
354}
355
356TEST_F(UnderBuiltinsModuleTest,
357 UnderBytearraySetitemWithNegativeKeyIndexesBackwards) {
358 HandleScope scope(thread_);
359 Bytearray self(&scope, runtime_->newBytearray());
360 bytearrayAdd(thread_, runtime_, self, 'a');
361 bytearrayAdd(thread_, runtime_, self, 'b');
362 bytearrayAdd(thread_, runtime_, self, 'c');
363 Int key(&scope, SmallInt::fromWord(-1));
364 Int value(&scope, SmallInt::fromWord(1));
365 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _bytearray_setitem), self, key, value)
366 .isNoneType());
367 EXPECT_TRUE(isBytearrayEqualsCStr(self, "ab\001"));
368}
369
370TEST_F(UnderBuiltinsModuleTest,
371 UnderBytearraySetitemWithNegativeKeySetsItemAtIndex) {
372 HandleScope scope(thread_);
373 Bytearray self(&scope, runtime_->newBytearray());
374 bytearrayAdd(thread_, runtime_, self, 'a');
375 bytearrayAdd(thread_, runtime_, self, 'b');
376 bytearrayAdd(thread_, runtime_, self, 'c');
377 Int key(&scope, SmallInt::fromWord(1));
378 Int value(&scope, SmallInt::fromWord(1));
379 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _bytearray_setitem), self, key, value)
380 .isNoneType());
381 EXPECT_TRUE(isBytearrayEqualsCStr(self, "a\001c"));
382}
383
384TEST_F(UnderBuiltinsModuleTest,
385 UnderBytearraySetsliceWithStepEqualsOneAndNoGrowthSetsSlice) {
386 HandleScope scope(thread_);
387 Bytearray self(&scope, runtime_->newBytearray());
388 bytearrayAdd(thread_, runtime_, self, 'a');
389 bytearrayAdd(thread_, runtime_, self, 'b');
390 bytearrayAdd(thread_, runtime_, self, 'c');
391 bytearrayAdd(thread_, runtime_, self, 'd');
392 bytearrayAdd(thread_, runtime_, self, 'e');
393 Int start(&scope, SmallInt::fromWord(0));
394 Int stop(&scope, SmallInt::fromWord(3));
395 Int step(&scope, SmallInt::fromWord(1));
396 Bytearray value(&scope, runtime_->newBytearray());
397 bytearrayAdd(thread_, runtime_, value, 'A');
398 bytearrayAdd(thread_, runtime_, value, 'B');
399 bytearrayAdd(thread_, runtime_, value, 'C');
400 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _bytearray_setslice), self, start,
401 stop, step, value)
402 .isNoneType());
403 EXPECT_TRUE(isBytearrayEqualsCStr(self, "ABCde"));
404}
405
406TEST_F(UnderBuiltinsModuleTest,
407 UnderBytearraySetsliceWithStepEqualsTwoAndNoGrowthSetsSlice) {
408 HandleScope scope(thread_);
409 Bytearray self(&scope, runtime_->newBytearray());
410 bytearrayAdd(thread_, runtime_, self, 'a');
411 bytearrayAdd(thread_, runtime_, self, 'b');
412 bytearrayAdd(thread_, runtime_, self, 'c');
413 bytearrayAdd(thread_, runtime_, self, 'd');
414 bytearrayAdd(thread_, runtime_, self, 'e');
415 Int start(&scope, SmallInt::fromWord(0));
416 Int stop(&scope, SmallInt::fromWord(3));
417 Int step(&scope, SmallInt::fromWord(2));
418 Bytearray value(&scope, runtime_->newBytearray());
419 bytearrayAdd(thread_, runtime_, value, 'A');
420 bytearrayAdd(thread_, runtime_, value, 'B');
421 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _bytearray_setslice), self, start,
422 stop, step, value)
423 .isNoneType());
424 EXPECT_TRUE(isBytearrayEqualsCStr(self, "AbBde"));
425}
426
427TEST_F(
428 UnderBuiltinsModuleTest,
429 UnderBytearraySetsliceWithStepEqualsOneAndSelfAsSourceSetsSliceAndGrows) {
430 HandleScope scope(thread_);
431 Bytearray self(&scope, runtime_->newBytearray());
432 bytearrayAdd(thread_, runtime_, self, 'a');
433 bytearrayAdd(thread_, runtime_, self, 'b');
434 bytearrayAdd(thread_, runtime_, self, 'c');
435 bytearrayAdd(thread_, runtime_, self, 'd');
436 bytearrayAdd(thread_, runtime_, self, 'e');
437 Int start(&scope, SmallInt::fromWord(0));
438 Int stop(&scope, SmallInt::fromWord(4));
439 Int step(&scope, SmallInt::fromWord(1));
440 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _bytearray_setslice), self, start,
441 stop, step, self)
442 .isNoneType());
443 EXPECT_TRUE(isBytearrayEqualsCStr(self, "abcdee"));
444}
445
446TEST_F(
447 UnderBuiltinsModuleTest,
448 UnderBytearraySetsliceWithStepEqualsOneAndSelfAsSourceStartsAtOneSetsSliceAndGrowsLHS) {
449 HandleScope scope(thread_);
450 Bytearray self(&scope, runtime_->newBytearray());
451 bytearrayAdd(thread_, runtime_, self, 'a');
452 bytearrayAdd(thread_, runtime_, self, 'b');
453 bytearrayAdd(thread_, runtime_, self, 'c');
454 bytearrayAdd(thread_, runtime_, self, 'd');
455 bytearrayAdd(thread_, runtime_, self, 'e');
456 Int start(&scope, SmallInt::fromWord(1));
457 Int stop(&scope, SmallInt::fromWord(4));
458 Int step(&scope, SmallInt::fromWord(1));
459 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _bytearray_setslice), self, start,
460 stop, step, self)
461 .isNoneType());
462 EXPECT_TRUE(isBytearrayEqualsCStr(self, "aabcdee"));
463}
464
465TEST_F(
466 UnderBuiltinsModuleTest,
467 UnderBytearraySetsliceWithStepEqualsOneAndBytesAsSourceSetsSliceAndGrowsLHS) {
468 HandleScope scope(thread_);
469 Bytearray self(&scope, runtime_->newBytearray());
470 bytearrayAdd(thread_, runtime_, self, 'a');
471 bytearrayAdd(thread_, runtime_, self, 'b');
472 bytearrayAdd(thread_, runtime_, self, 'c');
473 bytearrayAdd(thread_, runtime_, self, 'd');
474 bytearrayAdd(thread_, runtime_, self, 'e');
475 Int start(&scope, SmallInt::fromWord(1));
476 Int stop(&scope, SmallInt::fromWord(4));
477 Int step(&scope, SmallInt::fromWord(1));
478
479 byte src[] = {'o', 'o', 'o', 'o'};
480 Bytes value(&scope, runtime_->newBytesWithAll(src));
481
482 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _bytearray_setslice), self, start,
483 stop, step, value)
484 .isNoneType());
485 EXPECT_TRUE(isBytearrayEqualsCStr(self, "aooooe"));
486}
487
488TEST_F(
489 UnderBuiltinsModuleTest,
490 UnderBytearraySetsliceWithStepEqualsOneAndMemoryViewOfBytesAsSourceSetsSliceAndGrowsLHS) {
491 HandleScope scope(thread_);
492 Bytearray self(&scope, runtime_->newBytearray());
493 bytearrayAdd(thread_, runtime_, self, 'a');
494 bytearrayAdd(thread_, runtime_, self, 'b');
495 bytearrayAdd(thread_, runtime_, self, 'c');
496 bytearrayAdd(thread_, runtime_, self, 'd');
497 bytearrayAdd(thread_, runtime_, self, 'e');
498 Int start(&scope, SmallInt::fromWord(1));
499 Int stop(&scope, SmallInt::fromWord(4));
500 Int step(&scope, SmallInt::fromWord(1));
501
502 const byte src[] = {'o', 'o', 'o', 'o'};
503 MemoryView value(&scope, newMemoryView(src, "b", ReadOnly::ReadWrite));
504
505 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _bytearray_setslice), self, start,
506 stop, step, value)
507 .isNoneType());
508 EXPECT_TRUE(isBytearrayEqualsCStr(self, "aooooe"));
509}
510
511TEST_F(
512 UnderBuiltinsModuleTest,
513 UnderBytearraySetsliceWithStepEqualsOneAndMemoryViewOfPointerAsSourceSetsSliceAndGrowsLHS) {
514 HandleScope scope(thread_);
515 Bytearray self(&scope, runtime_->newBytearray());
516 bytearrayAdd(thread_, runtime_, self, 'a');
517 bytearrayAdd(thread_, runtime_, self, 'b');
518 bytearrayAdd(thread_, runtime_, self, 'c');
519 bytearrayAdd(thread_, runtime_, self, 'd');
520 bytearrayAdd(thread_, runtime_, self, 'e');
521 Int start(&scope, SmallInt::fromWord(1));
522 Int stop(&scope, SmallInt::fromWord(4));
523 Int step(&scope, SmallInt::fromWord(1));
524
525 const word length = 4;
526 byte memory[] = {'o', 'o', 'o', 'o'};
527 Object none(&scope, NoneType::object());
528 MemoryView value(
529 &scope, runtime_->newMemoryViewFromCPtr(thread_, none, memory, length,
530 ReadOnly::ReadWrite));
531
532 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _bytearray_setslice), self, start,
533 stop, step, value)
534 .isNoneType());
535 EXPECT_TRUE(isBytearrayEqualsCStr(self, "aooooe"));
536}
537
538TEST_F(
539 UnderBuiltinsModuleTest,
540 UnderBytearraySetsliceWithStepEqualsOneAndArrayAsSourceSetsSliceAndGrowsLHS) {
541 HandleScope scope(thread_);
542 Bytearray self(&scope, runtime_->newBytearray());
543 bytearrayAdd(thread_, runtime_, self, 'a');
544 bytearrayAdd(thread_, runtime_, self, 'b');
545 bytearrayAdd(thread_, runtime_, self, 'c');
546 bytearrayAdd(thread_, runtime_, self, 'd');
547 bytearrayAdd(thread_, runtime_, self, 'e');
548 Int start(&scope, SmallInt::fromWord(1));
549 Int stop(&scope, SmallInt::fromWord(5));
550 Int step(&scope, SmallInt::fromWord(1));
551
552 ASSERT_FALSE(runFromCStr(runtime_, R"(
553import array
554arr = array.array('b', [1, 2, 3, 4, 5])
555)")
556 .isError());
557 Object value(&scope, mainModuleAt(runtime_, "arr"));
558 ASSERT_TRUE(value.isArray());
559
560 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _bytearray_setslice), self, start,
561 stop, step, value)
562 .isNoneType());
563 EXPECT_TRUE(isBytearrayEqualsCStr(self, "a\x01\x02\x03\x04\x05"));
564}
565
566TEST_F(UnderBuiltinsModuleTest,
567 UnderBytesContainsWithIntBiggerThanCharRaisesValueError) {
568 HandleScope scope(thread_);
569 const byte contents[] = {'1', '2', '3'};
570 Bytes bytes(&scope, runtime_->newBytesWithAll(contents));
571 ASSERT_EQ(bytes.length(), 3);
572 Object key(&scope, SmallInt::fromWord(256));
573 EXPECT_TRUE(
574 raisedWithStr(runBuiltin(FUNC(_builtins, _bytes_contains), bytes, key),
575 LayoutId::kValueError, "byte must be in range(0, 256)"));
576}
577
578TEST_F(UnderBuiltinsModuleTest, UnderBytesContainsWithByteInBytesReturnsTrue) {
579 HandleScope scope(thread_);
580 const byte contents[] = {'1', '2', '3'};
581 Bytes bytes(&scope, runtime_->newBytesWithAll(contents));
582 ASSERT_EQ(bytes.length(), 3);
583 Object key(&scope, SmallInt::fromWord('2'));
584 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytes_contains), bytes, key),
585 Bool::trueObj());
586}
587
588TEST_F(UnderBuiltinsModuleTest,
589 UnderBytesContainsWithByteNotInBytesReturnsFalse) {
590 HandleScope scope(thread_);
591 const byte contents[] = {'1', '2', '3'};
592 Bytes bytes(&scope, runtime_->newBytesWithAll(contents));
593 ASSERT_EQ(bytes.length(), 3);
594 Object key(&scope, SmallInt::fromWord('x'));
595 EXPECT_EQ(runBuiltin(FUNC(_builtins, _bytes_contains), bytes, key),
596 Bool::falseObj());
597}
598
599TEST_F(UnderBuiltinsModuleTest,
600 UnderBytesJoinWithEmptyIterableReturnsEmptyBytearray) {
601 Thread* thread = Thread::current();
602 HandleScope scope(thread);
603 Bytes self(&scope, runtime_->newBytes(3, 'a'));
604 Object iter(&scope, runtime_->emptyTuple());
605 Object result(&scope, runBuiltin(FUNC(_builtins, _bytes_join), self, iter));
606 EXPECT_TRUE(isBytesEqualsCStr(result, ""));
607}
608
609TEST_F(UnderBuiltinsModuleTest, UnderBytesJoinWithEmptySeparatorReturnsBytes) {
610 Thread* thread = Thread::current();
611 HandleScope scope(thread);
612 Bytes self(&scope, Bytes::empty());
613 Object obj1(&scope, runtime_->newBytes(1, 'A'));
614 Object obj2(&scope, runtime_->newBytes(2, 'B'));
615 Object obj3(&scope, runtime_->newBytes(1, 'A'));
616 Tuple iter(&scope, runtime_->newTupleWith3(obj1, obj2, obj3));
617 Object result(&scope, runBuiltin(FUNC(_builtins, _bytes_join), self, iter));
618 EXPECT_TRUE(isBytesEqualsCStr(result, "ABBA"));
619}
620
621TEST_F(UnderBuiltinsModuleTest, UnderBytesJoinWithNonEmptyListReturnsBytes) {
622 Thread* thread = Thread::current();
623 HandleScope scope(thread);
624 Bytes self(&scope, runtime_->newBytes(1, ' '));
625 List iter(&scope, runtime_->newList());
626 Bytes value(&scope, runtime_->newBytes(1, '*'));
627 runtime_->listAdd(thread, iter, value);
628 runtime_->listAdd(thread, iter, value);
629 runtime_->listAdd(thread, iter, value);
630 Object result(&scope, runBuiltin(FUNC(_builtins, _bytes_join), self, iter));
631 EXPECT_TRUE(isBytesEqualsCStr(result, "* * *"));
632}
633
634TEST_F(UnderBuiltinsModuleTest, UnderBytesJoinWithBytesSubclassesReturnsBytes) {
635 ASSERT_FALSE(runFromCStr(runtime_, R"(
636class Foo(bytes):
637 def join(self, iterable):
638 # this should not be called - expect bytes.join() instead
639 return 0
640sep = Foo(b"-")
641ac = Foo(b"AC")
642dc = Foo(b"DC")
643)")
644 .isError());
645 HandleScope scope(thread_);
646 Object self(&scope, mainModuleAt(runtime_, "sep"));
647 Object obj1(&scope, mainModuleAt(runtime_, "ac"));
648 Object obj2(&scope, mainModuleAt(runtime_, "dc"));
649 Tuple iter(&scope, runtime_->newTupleWith2(obj1, obj2));
650 Object result(&scope, runBuiltin(FUNC(_builtins, _bytes_join), self, iter));
651 EXPECT_TRUE(isBytesEqualsCStr(result, "AC-DC"));
652}
653
654TEST_F(UnderBuiltinsModuleTest, UnderBytesJoinWithMemoryViewReturnsBytes) {
655 Thread* thread = Thread::current();
656 HandleScope scope(thread);
657 Bytes self(&scope, runtime_->newBytes(1, ' '));
658 Bytes src1(&scope, newBytesFromCStr(thread_, "hello"));
659 MemoryView obj1(&scope,
660 runtime_->newMemoryView(thread_, src1, src1, src1.length(),
661 ReadOnly::ReadOnly));
662 Bytes src2(&scope, newBytesFromCStr(thread_, "world"));
663 MemoryView obj2(&scope,
664 runtime_->newMemoryView(thread_, src2, src2, src2.length(),
665 ReadOnly::ReadOnly));
666 Tuple iter(&scope, runtime_->newTupleWith2(obj1, obj2));
667 Object result(&scope, runBuiltin(FUNC(_builtins, _bytes_join), self, iter));
668 EXPECT_TRUE(isBytesEqualsCStr(result, "hello world"));
669}
670
671TEST_F(UnderBuiltinsModuleTest, UnderCallerLocalsDoesNotReturnInternalObjects) {
672 ASSERT_FALSE(runFromCStr(runtime_, R"(
673def bar():
674 a = 23
675 b = 13
676 l = locals()
677 c = 0
678 d = 0
679 e = 0
680 f = 0
681 g = 0
682 return l
683)")
684 .isError());
685 // Push arbitrary values to the stack
686 Thread* thread = Thread::current();
687 for (int a = 0; a < 20; a++) {
688 for (int i = 0; i < 5; i++) {
689 thread->stackPush(Unbound::object());
690 }
691 thread->stackPush(Error::notFound());
692 thread->stackPush(runtime_->newMutableBytesUninitialized(1));
693 thread->stackPush(runtime_->newMutableTuple(1));
694 thread->stackPush(NoneType::object());
695 }
696 // Reset the stack pointer
697 thread->stackDrop(9 * 20);
698
699 /*
700 * When locals is called in bar we expect the stack to look like below
701 Function bar
702 --- Locals ----
703 int 23 -> assigned to a
704 int 13 -> assigned to b
705 _Unbound -> assigned to l
706 _Unbound -> assigned to c
707 Error::notFound -> assigned to d
708 _mutablebytes -> assigned to e
709 _mutable_tuple -> assigned to f
710 NoneType::object -> assigned to g
711 */
712
713 HandleScope scope(thread);
714 Object bar_object(&scope, mainModuleAt(runtime_, "bar"));
715 EXPECT_TRUE(bar_object.isFunction());
716 Function bar(&scope, *bar_object);
717 Tuple args(&scope, runtime_->emptyTuple());
718 Object result(&scope, callFunction(bar, args));
719 EXPECT_TRUE(result.isDict());
720 Dict locals(&scope, *result);
721
722 Str a(&scope, runtime_->newStrFromCStr("a"));
723 Object a_val(&scope, dictAtByStr(thread_, locals, a));
724 EXPECT_TRUE(isIntEqualsWord(*a_val, 23));
725
726 Str b(&scope, runtime_->newStrFromCStr("b"));
727 Object b_val(&scope, dictAtByStr(thread_, locals, b));
728 EXPECT_TRUE(isIntEqualsWord(*b_val, 13));
729
730 Str c(&scope, runtime_->newStrFromCStr("c"));
731 Object c_val(&scope, dictAtByStr(thread_, locals, c));
732 EXPECT_TRUE(c_val.isErrorNotFound());
733
734 Str d(&scope, runtime_->newStrFromCStr("d"));
735 Object d_val(&scope, dictAtByStr(thread_, locals, d));
736 EXPECT_TRUE(d_val.isErrorNotFound());
737
738 Str e(&scope, runtime_->newStrFromCStr("e"));
739 Object e_val(&scope, dictAtByStr(thread_, locals, e));
740 EXPECT_TRUE(e_val.isErrorNotFound());
741
742 Str f(&scope, runtime_->newStrFromCStr("f"));
743 Object f_val(&scope, dictAtByStr(thread_, locals, f));
744 EXPECT_TRUE(f_val.isErrorNotFound());
745
746 Str g(&scope, runtime_->newStrFromCStr("g"));
747 Object g_val(&scope, dictAtByStr(thread_, locals, g));
748 // TODO(T89882231) Expect g_val to be ErrorNotFound
749 EXPECT_TRUE(g_val.isNoneType());
750}
751
752TEST_F(UnderBuiltinsModuleTest, UnderCodeSetFilenameSetsFilename) {
753 HandleScope scope(thread_);
754 Code code(&scope, newCodeWithBytes(View<byte>(nullptr, 0)));
755 Str filename(&scope, runtime_->newStrFromCStr("foobar"));
756 ASSERT_NE(code.filename(), filename);
757 ASSERT_FALSE(runBuiltin(FUNC(_builtins, _code_set_filename), code, filename)
758 .isError());
759 EXPECT_EQ(code.filename(), filename);
760}
761
762TEST_F(UnderBuiltinsModuleTest,
763 UnderDictGetWithNotEnoughArgumentsRaisesTypeError) {
764 EXPECT_TRUE(raisedWithStr(
765 runFromCStr(runtime_, "_dict_get()"), LayoutId::kTypeError,
766 "'_dict_get' takes min 2 positional arguments but 0 given"));
767}
768
769TEST_F(UnderBuiltinsModuleTest,
770 UnderDictGetWithTooManyArgumentsRaisesTypeError) {
771 EXPECT_TRUE(raisedWithStr(
772 runFromCStr(runtime_, "_dict_get({}, 123, 456, 789)"),
773 LayoutId::kTypeError,
774 "'_dict_get' takes max 3 positional arguments but 4 given"));
775}
776
777TEST_F(UnderBuiltinsModuleTest, UnderDictGetWithUnhashableTypeRaisesTypeError) {
778 HandleScope scope(thread_);
779 ASSERT_FALSE(runFromCStr(runtime_, R"(
780class Foo:
781 __hash__ = 2
782key = Foo()
783)")
784 .isError());
785 Dict dict(&scope, runtime_->newDict());
786 Object key(&scope, mainModuleAt(runtime_, "key"));
787 Object default_obj(&scope, NoneType::object());
788 ASSERT_TRUE(
789 raised(runBuiltin(FUNC(_builtins, _dict_get), dict, key, default_obj),
790 LayoutId::kTypeError));
791}
792
793TEST_F(UnderBuiltinsModuleTest,
794 UnderDictGetWithIntSubclassHashReturnsDefaultValue) {
795 HandleScope scope(thread_);
796 ASSERT_FALSE(runFromCStr(runtime_, R"(
797class N(int):
798 pass
799class Foo:
800 def __hash__(self):
801 return N(12)
802key = Foo()
803)")
804 .isError());
805 Dict dict(&scope, runtime_->newDict());
806 Object key(&scope, mainModuleAt(runtime_, "key"));
807 Object default_obj(&scope, runtime_->newInt(5));
808 EXPECT_EQ(runBuiltin(FUNC(_builtins, _dict_get), dict, key, default_obj),
809 default_obj);
810}
811
812TEST_F(UnderBuiltinsModuleTest, UnderDictGetReturnsDefaultValue) {
813 ASSERT_FALSE(
814 runFromCStr(runtime_, "res = _dict_get({}, 123, 456)").isError());
815 EXPECT_EQ(mainModuleAt(runtime_, "res"), RawSmallInt::fromWord(456));
816}
817
818TEST_F(UnderBuiltinsModuleTest, UnderDictGetReturnsNone) {
819 ASSERT_FALSE(runFromCStr(runtime_, "result = _dict_get({}, 123)").isError());
820 EXPECT_TRUE(mainModuleAt(runtime_, "result").isNoneType());
821}
822
823TEST_F(UnderBuiltinsModuleTest, UnderDictGetReturnsValue) {
824 HandleScope scope(thread_);
825 Dict dict(&scope, runtime_->newDict());
826 Object key(&scope, runtime_->newInt(123));
827 word hash = intHash(*key);
828 Object value(&scope, runtime_->newInt(456));
829 ASSERT_TRUE(dictAtPut(thread_, dict, key, hash, value).isNoneType());
830 Object dflt(&scope, runtime_->newInt(789));
831 Object result(&scope,
832 runBuiltin(FUNC(_builtins, _dict_get), dict, key, dflt));
833 EXPECT_TRUE(isIntEqualsWord(*result, 456));
834}
835
836TEST_F(UnderBuiltinsModuleTest, UnderDictGetWithNonDictRaisesTypeError) {
837 HandleScope scope(thread_);
838 Object foo(&scope, runtime_->newInt(123));
839 Object bar(&scope, runtime_->newInt(456));
840 Object baz(&scope, runtime_->newInt(789));
841 EXPECT_TRUE(raised(runBuiltin(FUNC(_builtins, _dict_get), foo, bar, baz),
842 LayoutId::kTypeError));
843}
844
845TEST_F(UnderBuiltinsModuleTest,
846 UnderDictSetitemWithKeyHashReturningNonIntRaisesTypeError) {
847 EXPECT_TRUE(raisedWithStr(runFromCStr(runtime_, R"(
848class E:
849 def __hash__(self): return "non int"
850
851d = {}
852_dict_setitem(d, E(), 4)
853)"),
854 LayoutId::kTypeError,
855 "__hash__ method should return an integer"));
856}
857
858TEST_F(UnderBuiltinsModuleTest, UnderDictSetitemWithExistingKey) {
859 HandleScope scope(thread_);
860 Dict dict(&scope, runtime_->newDictWithSize(1));
861 Str key(&scope, runtime_->newStrFromCStr("foo"));
862 Object val(&scope, runtime_->newInt(0));
863 Object val2(&scope, runtime_->newInt(1));
864 dictAtPutByStr(thread_, dict, key, val);
865
866 Object result(&scope,
867 runBuiltin(FUNC(_builtins, _dict_setitem), dict, key, val2));
868 ASSERT_TRUE(result.isNoneType());
869 ASSERT_EQ(dict.numItems(), 1);
870 ASSERT_EQ(dictAtByStr(thread_, dict, key), *val2);
871}
872
873TEST_F(UnderBuiltinsModuleTest, UnderDictSetitemWithNonExistentKey) {
874 HandleScope scope(thread_);
875 Dict dict(&scope, runtime_->newDictWithSize(1));
876 ASSERT_EQ(dict.numItems(), 0);
877 Str key(&scope, runtime_->newStrFromCStr("foo"));
878 Object val(&scope, runtime_->newInt(0));
879 Object result(&scope,
880 runBuiltin(FUNC(_builtins, _dict_setitem), dict, key, val));
881 ASSERT_TRUE(result.isNoneType());
882 ASSERT_EQ(dict.numItems(), 1);
883 ASSERT_EQ(dictAtByStr(thread_, dict, key), *val);
884}
885
886TEST_F(UnderBuiltinsModuleTest, UnderDictSetitemWithDictSubclassSetsItem) {
887 HandleScope scope(thread_);
888 ASSERT_FALSE(runFromCStr(runtime_, R"(
889class foo(dict):
890 pass
891d = foo()
892)")
893 .isError());
894 Dict dict(&scope, mainModuleAt(runtime_, "d"));
895 Str key(&scope, runtime_->newStrFromCStr("a"));
896 Str value(&scope, runtime_->newStrFromCStr("b"));
897 Object result1(&scope,
898 runBuiltin(FUNC(_builtins, _dict_setitem), dict, key, value));
899 EXPECT_TRUE(result1.isNoneType());
900 Object result2(&scope, dictAtByStr(thread_, dict, key));
901 ASSERT_TRUE(result2.isStr());
902 EXPECT_EQ(Str::cast(*result2), *value);
903}
904
905TEST_F(UnderBuiltinsModuleTest, UnderDivmodReturnsQuotientAndDividend) {
906 HandleScope scope(thread_);
907 Int number(&scope, SmallInt::fromWord(1234));
908 Int divisor(&scope, SmallInt::fromWord(-5));
909 Object tuple_obj(&scope,
910 runBuiltin(FUNC(_builtins, _divmod), number, divisor));
911 ASSERT_TRUE(tuple_obj.isTuple());
912 Tuple tuple(&scope, *tuple_obj);
913 ASSERT_EQ(tuple.length(), 2);
914 EXPECT_TRUE(isIntEqualsWord(tuple.at(0), -247));
915 EXPECT_TRUE(isIntEqualsWord(tuple.at(1), -1));
916}
917
918TEST_F(UnderBuiltinsModuleTest, UnderFloatDivmodReturnsQuotientAndRemainder) {
919 HandleScope scope(thread_);
920 Float number(&scope, runtime_->newFloat(3.25));
921 Float divisor(&scope, runtime_->newFloat(1.0));
922 Tuple result(&scope,
923 runBuiltin(FUNC(_builtins, _float_divmod), number, divisor));
924 ASSERT_EQ(result.length(), 2);
925 Float quotient(&scope, result.at(0));
926 Float remainder(&scope, result.at(1));
927 EXPECT_EQ(quotient.value(), 3.0);
928 EXPECT_EQ(remainder.value(), 0.25);
929}
930
931TEST_F(UnderBuiltinsModuleTest,
932 UnderFloatDivmodWithZeroDivisorRaisesZeroDivisionError) {
933 HandleScope scope(thread_);
934 Float number(&scope, runtime_->newFloat(3.25));
935 Float divisor(&scope, runtime_->newFloat(0.0));
936 EXPECT_TRUE(
937 raisedWithStr(runBuiltin(FUNC(_builtins, _float_divmod), number, divisor),
938 LayoutId::kZeroDivisionError, "float divmod()"));
939}
940
941TEST_F(UnderBuiltinsModuleTest, UnderFloatDivmodWithNanReturnsNan) {
942 HandleScope scope(thread_);
943 Float number(&scope, runtime_->newFloat(3.25));
944 double nan = std::numeric_limits<double>::quiet_NaN();
945 ASSERT_TRUE(std::isnan(nan));
946 Float divisor(&scope, runtime_->newFloat(nan));
947 Tuple result(&scope,
948 runBuiltin(FUNC(_builtins, _float_divmod), number, divisor));
949 ASSERT_EQ(result.length(), 2);
950 Float quotient(&scope, result.at(0));
951 Float remainder(&scope, result.at(1));
952 EXPECT_TRUE(std::isnan(quotient.value()));
953 EXPECT_TRUE(std::isnan(remainder.value()));
954}
955
956TEST_F(UnderBuiltinsModuleTest, UnderObjectDunderClassSetterWithTypeSelf) {
957 ASSERT_FALSE(runFromCStr(runtime_, R"(
958class M(type):
959 pass
960class C(metaclass=M):
961 pass
962)")
963 .isError());
964 HandleScope scope(thread_);
965 Type c(&scope, mainModuleAt(runtime_, "C"));
966 Layout previous_layout(&scope, c.instanceLayout());
967 EXPECT_EQ(previous_layout.id(), c.instanceLayoutId());
968 ASSERT_FALSE(runFromCStr(runtime_, R"(
969C.__class__ = type
970C_instance = C()
971)")
972 .isError());
973 EXPECT_NE(c.instanceLayout(), previous_layout);
974 EXPECT_NE(c.instanceLayoutId(), previous_layout.id());
975 EXPECT_EQ(Layout::cast(c.instanceLayout()).id(), c.instanceLayoutId());
976
977 EXPECT_EQ(runtime_->typeOf(*c), runtime_->typeAt(LayoutId::kType));
978 Object c_inst(&scope, mainModuleAt(runtime_, "C_instance"));
979 EXPECT_EQ(runtime_->typeOf(*c_inst), c);
980}
981
982// TODO(T64924852): Once module.__setattr__ is fixed, write death test for
983// setting __class__ of module.
984
985TEST_F(UnderBuiltinsModuleTest,
986 UnderObjectKeysWithUnassignedNumInObjectAttributes) {
987 HandleScope scope(thread_);
988 ASSERT_FALSE(runFromCStr(runtime_, R"(
989class C:
990 def __init__(self, p):
991 if p:
992 self.a = 42
993i = C(False)
994)")
995 .isError());
996 Object i(&scope, mainModuleAt(runtime_, "i"));
997 Object result(&scope, runBuiltin(FUNC(_builtins, _object_keys), i));
998 ASSERT_TRUE(result.isList());
999 EXPECT_EQ(List::cast(*result).numItems(), 0);
1000}
1001
1002TEST_F(UnderBuiltinsModuleTest,
1003 UnderObjectKeysWithEmptyDictOverflowReturnsKeys) {
1004 HandleScope scope(thread_);
1005 ASSERT_FALSE(runFromCStr(runtime_, R"(
1006class C:
1007 pass
1008instance = C()
1009instance.__dict__ = {}
1010)")
1011 .isError());
1012 Object instance(&scope, mainModuleAt(runtime_, "instance"));
1013 Layout layout(&scope, runtime_->layoutOf(*instance));
1014 ASSERT_TRUE(layout.hasDictOverflow());
1015 Object result(&scope, runBuiltin(FUNC(_builtins, _object_keys), instance));
1016 ASSERT_TRUE(result.isList());
1017 EXPECT_PYLIST_EQ(result, {});
1018}
1019
1020TEST_F(UnderBuiltinsModuleTest,
1021 UnderObjectKeysWithNonEmptyDictOverflowReturnsKeys) {
1022 HandleScope scope(thread_);
1023 ASSERT_FALSE(runFromCStr(runtime_, R"(
1024class C:
1025 pass
1026instance = C()
1027instance.__dict__ = {"hello": "world", "foo": "bar"}
1028)")
1029 .isError());
1030 Object instance(&scope, mainModuleAt(runtime_, "instance"));
1031 Layout layout(&scope, runtime_->layoutOf(*instance));
1032 ASSERT_TRUE(layout.hasDictOverflow());
1033 Object result(&scope, runBuiltin(FUNC(_builtins, _object_keys), instance));
1034 ASSERT_TRUE(result.isList());
1035 EXPECT_PYLIST_EQ(result, {"hello", "foo"});
1036}
1037
1038TEST_F(UnderBuiltinsModuleTest,
1039 UnderObjectKeysWithInObjectAndDictOverflowReturnsKeys) {
1040 HandleScope scope(thread_);
1041 ASSERT_FALSE(runFromCStr(runtime_, R"(
1042def instance():
1043 pass
1044instance.hello = "world"
1045instance.foo = "bar"
1046)")
1047 .isError());
1048 Object instance(&scope, mainModuleAt(runtime_, "instance"));
1049 Layout layout(&scope, runtime_->layoutOf(*instance));
1050 Tuple in_object(&scope, layout.inObjectAttributes());
1051 ASSERT_GT(in_object.length(), 0);
1052 ASSERT_TRUE(layout.hasDictOverflow());
1053 Object result_obj(&scope,
1054 runBuiltin(FUNC(_builtins, _object_keys), instance));
1055 ASSERT_TRUE(result_obj.isList());
1056 List result(&scope, *result_obj);
1057 EXPECT_GT(result.numItems(), 2);
1058 Str hello(&scope, runtime_->newStrFromCStr("hello"));
1059 Str foo(&scope, runtime_->newStrFromCStr("foo"));
1060 EXPECT_TRUE(listContains(result, hello));
1061 EXPECT_TRUE(listContains(result, foo));
1062}
1063
1064TEST_F(UnderBuiltinsModuleTest,
1065 UnderObjectKeysWithHiddenAttributesDoesNotReturnKey) {
1066 HandleScope scope(thread_);
1067 LayoutId layout_id = LayoutId::kUserWarning;
1068 Object previous_layout(&scope, runtime_->layoutAt(layout_id));
1069 BuiltinAttribute attrs[] = {
1070 {ID(__globals__), 0, AttributeFlags::kHidden},
1071 };
1072 Type type(&scope, addBuiltinType(thread_, ID(UserWarning), layout_id,
1073 LayoutId::kObject, attrs,
1074 /*size=*/kPointerSize,
1075 /*basetype=*/true));
1076 Layout layout(&scope, type.instanceLayout());
1077 runtime_->layoutAtPut(layout_id, *layout);
1078 Instance instance(&scope, runtime_->newInstance(layout));
1079 Object result_obj(&scope,
1080 runBuiltin(FUNC(_builtins, _object_keys), instance));
1081 ASSERT_TRUE(result_obj.isList());
1082 List result(&scope, *result_obj);
1083 Str dunder_globals(&scope, runtime_->newStrFromCStr("__globals__"));
1084 EXPECT_FALSE(listContains(result, dunder_globals));
1085 EXPECT_EQ(instance.layoutId(), layout.id());
1086 runtime_->layoutAtPut(layout_id, *previous_layout);
1087}
1088
1089TEST_F(UnderBuiltinsModuleTest,
1090 UnderInstanceDunderDictSetterCoalescesAffectedLayoutsIntoSingleOne) {
1091 HandleScope scope(thread_);
1092 ASSERT_FALSE(runFromCStr(runtime_, R"(
1093class C: pass
1094
1095c0 = C()
1096c0.foo = 4
1097
1098c1 = C()
1099c1.bar = 5
1100
1101c0.__dict__ = {"a": 4}
1102c1.__dict__ = {"b": 4}
1103)")
1104 .isError());
1105 Object c0(&scope, mainModuleAt(runtime_, "c0"));
1106 Object c1(&scope, mainModuleAt(runtime_, "c1"));
1107 EXPECT_EQ(c0.layoutId(), c1.layoutId());
1108}
1109
1110TEST_F(UnderBuiltinsModuleTest, UnderInstanceOverflowDictAllocatesDictionary) {
1111 HandleScope scope(thread_);
1112 ASSERT_FALSE(runFromCStr(runtime_, R"(
1113def instance():
1114 pass
1115)")
1116 .isError());
1117 Object instance_obj(&scope, mainModuleAt(runtime_, "instance"));
1118 ASSERT_TRUE(instance_obj.isHeapObject());
1119 Instance instance(&scope, *instance_obj);
1120 Layout layout(&scope, runtime_->layoutOf(*instance));
1121 ASSERT_TRUE(layout.hasDictOverflow());
1122 word offset = layout.dictOverflowOffset();
1123 ASSERT_TRUE(instance.instanceVariableAt(offset).isNoneType());
1124
1125 Object result0(
1126 &scope, runBuiltin(FUNC(_builtins, _instance_overflow_dict), instance));
1127 ASSERT_EQ(instance.layoutId(), layout.id());
1128 Object overflow_dict(&scope, instance.instanceVariableAt(offset));
1129 EXPECT_TRUE(result0.isDict());
1130 EXPECT_EQ(result0, overflow_dict);
1131
1132 Object result1(
1133 &scope, runBuiltin(FUNC(_builtins, _instance_overflow_dict), instance));
1134 EXPECT_EQ(result0, result1);
1135}
1136
1137TEST_F(UnderBuiltinsModuleTest,
1138 UnderIntFromBytesWithLittleEndianReturnsSmallInt) {
1139 HandleScope scope(thread_);
1140
1141 Type int_type(&scope, runtime_->typeAt(LayoutId::kInt));
1142 const byte bytes_array[] = {0xca, 0xfe};
1143 Bytes bytes(&scope, runtime_->newBytesWithAll(bytes_array));
1144 Bool byteorder_big(&scope, Bool::falseObj());
1145 Bool signed_arg(&scope, Bool::falseObj());
1146 Object result(&scope, runBuiltin(FUNC(_builtins, _int_from_bytes), int_type,
1147 bytes, byteorder_big, signed_arg));
1148 EXPECT_TRUE(isIntEqualsWord(*result, 0xfeca));
1149}
1150
1151TEST_F(UnderBuiltinsModuleTest,
1152 UnderIntFromBytesWithLittleEndianReturnsLargeInt) {
1153 HandleScope scope(thread_);
1154
1155 Type int_type(&scope, runtime_->typeAt(LayoutId::kInt));
1156 const byte bytes_array[] = {0xca, 0xfe, 0xba, 0xbe, 0x01, 0x23,
1157 0x45, 0x67, 0x89, 0xab, 0xcd};
1158 Bytes bytes(&scope, runtime_->newBytesWithAll(bytes_array));
1159 Bool byteorder_big(&scope, Bool::falseObj());
1160 Bool signed_arg(&scope, Bool::falseObj());
1161 Int result(&scope, runBuiltin(FUNC(_builtins, _int_from_bytes), int_type,
1162 bytes, byteorder_big, signed_arg));
1163 ASSERT_EQ(result.numDigits(), 2);
1164 EXPECT_EQ(result.digitAt(0), 0x67452301bebafecaU);
1165 EXPECT_EQ(result.digitAt(1), 0xcdab89U);
1166}
1167
1168TEST_F(UnderBuiltinsModuleTest, UnderIntFromBytesWithBigEndianReturnsSmallInt) {
1169 HandleScope scope(thread_);
1170
1171 Type int_type(&scope, runtime_->typeAt(LayoutId::kInt));
1172 const byte bytes_array[] = {0xca, 0xfe};
1173 Bytes bytes(&scope, runtime_->newBytesWithAll(bytes_array));
1174 Bool byteorder_big(&scope, Bool::trueObj());
1175 Bool signed_arg(&scope, Bool::falseObj());
1176 Object result(&scope, runBuiltin(FUNC(_builtins, _int_from_bytes), int_type,
1177 bytes, byteorder_big, signed_arg));
1178 EXPECT_TRUE(isIntEqualsWord(*result, 0xcafe));
1179}
1180
1181TEST_F(UnderBuiltinsModuleTest, UnderIntFromBytesWithBigEndianReturnsLargeInt) {
1182 HandleScope scope(thread_);
1183
1184 Type int_type(&scope, runtime_->typeAt(LayoutId::kInt));
1185 const byte bytes_array[] = {0xca, 0xfe, 0xba, 0xbe, 0x01, 0x23,
1186 0x45, 0x67, 0x89, 0xab, 0xcd};
1187 Bytes bytes(&scope, runtime_->newBytesWithAll(bytes_array));
1188 Bool byteorder_big(&scope, Bool::trueObj());
1189 Bool signed_arg(&scope, Bool::falseObj());
1190 Int result(&scope, runBuiltin(FUNC(_builtins, _int_from_bytes), int_type,
1191 bytes, byteorder_big, signed_arg));
1192 ASSERT_EQ(result.numDigits(), 2);
1193 EXPECT_EQ(result.digitAt(0), 0xbe0123456789abcdU);
1194 EXPECT_EQ(result.digitAt(1), 0xcafebaU);
1195}
1196
1197TEST_F(UnderBuiltinsModuleTest, UnderIntFromBytesWithEmptyBytes) {
1198 HandleScope scope(thread_);
1199
1200 Type int_type(&scope, runtime_->typeAt(LayoutId::kInt));
1201 Bytes bytes(&scope, runtime_->newBytesWithAll(View<byte>(nullptr, 0)));
1202 Bool bo_big_false(&scope, Bool::falseObj());
1203 Bool signed_arg(&scope, Bool::falseObj());
1204 Object result_little(
1205 &scope, runBuiltin(FUNC(_builtins, _int_from_bytes), int_type, bytes,
1206 bo_big_false, signed_arg));
1207 EXPECT_TRUE(isIntEqualsWord(*result_little, 0));
1208
1209 Bool bo_big_true(&scope, Bool::trueObj());
1210 Object result_big(
1211 &scope, runBuiltin(FUNC(_builtins, _int_from_bytes), int_type, bytes,
1212 bo_big_true, signed_arg));
1213 EXPECT_TRUE(isIntEqualsWord(*result_big, 0));
1214}
1215
1216TEST_F(UnderBuiltinsModuleTest,
1217 UnderIntFromBytesWithNumberWithDigitHighBitSet) {
1218 HandleScope scope(thread_);
1219
1220 // Test special case where a positive number having a high bit set at the end
1221 // of a "digit" needs an extra digit in the LargeInt representation.
1222 Type int_type(&scope, runtime_->typeAt(LayoutId::kInt));
1223 Bytes bytes(&scope, runtime_->newBytes(kWordSize, 0xff));
1224 Bool byteorder_big(&scope, Bool::falseObj());
1225 Bool signed_arg(&scope, Bool::falseObj());
1226 Int result(&scope, runBuiltin(FUNC(_builtins, _int_from_bytes), int_type,
1227 bytes, byteorder_big, signed_arg));
1228 const uword expected_digits[] = {kMaxUword, 0};
1229 EXPECT_TRUE(isIntEqualsDigits(*result, expected_digits));
1230}
1231
1232TEST_F(UnderBuiltinsModuleTest,
1233 UnderIntFromBytesWithNegativeNumberReturnsSmallInt) {
1234 HandleScope scope(thread_);
1235
1236 Type int_type(&scope, runtime_->typeAt(LayoutId::kInt));
1237 const byte bytes_array[] = {0xff};
1238 Bytes bytes(&scope, runtime_->newBytesWithAll(bytes_array));
1239 Bool byteorder_big(&scope, Bool::falseObj());
1240 Bool signed_arg(&scope, Bool::trueObj());
1241 Object result(&scope, runBuiltin(FUNC(_builtins, _int_from_bytes), int_type,
1242 bytes, byteorder_big, signed_arg));
1243 EXPECT_TRUE(isIntEqualsWord(*result, -1));
1244}
1245
1246TEST_F(UnderBuiltinsModuleTest,
1247 UnderIntFromBytesWithNegativeNumberReturnsLargeInt) {
1248 HandleScope scope(thread_);
1249
1250 Type int_type(&scope, runtime_->typeAt(LayoutId::kInt));
1251 const byte bytes_array[] = {0xca, 0xfe, 0xba, 0xbe, 0x01, 0x23,
1252 0x45, 0x67, 0x89, 0xab, 0xcd};
1253 Bytes bytes(&scope, runtime_->newBytesWithAll(bytes_array));
1254 Bool byteorder_big(&scope, Bool::trueObj());
1255 Bool signed_arg(&scope, Bool::trueObj());
1256 Object result(&scope, runBuiltin(FUNC(_builtins, _int_from_bytes), int_type,
1257 bytes, byteorder_big, signed_arg));
1258 const uword expected_digits[] = {0xbe0123456789abcd, 0xffffffffffcafeba};
1259 EXPECT_TRUE(isIntEqualsDigits(*result, expected_digits));
1260}
1261
1262TEST_F(UnderBuiltinsModuleTest,
1263 UnderIntNewFromByteslikeWithZeroBaseReturnsCodeLiteral) {
1264 HandleScope scope(thread_);
1265 const byte view[] = {'0', 'x', 'b', 'a', '5', 'e'};
1266 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1267 Bytearray array(&scope, runtime_->newBytearray());
1268 runtime_->bytearrayExtend(thread_, array, view);
1269 Int base(&scope, SmallInt::fromWord(0));
1270 Object result(&scope, runBuiltin(FUNC(_builtins, _int_new_from_byteslike),
1271 type, array, base));
1272 EXPECT_TRUE(isIntEqualsWord(*result, 0xba5e));
1273}
1274
1275TEST_F(UnderBuiltinsModuleTest,
1276 UnderIntNewFromByteslikeWithInvalidByteInBytearrayRaisesValueError) {
1277 HandleScope scope(thread_);
1278 const byte view[] = {'$'};
1279 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1280 Bytearray array(&scope, runtime_->newBytearray());
1281 runtime_->bytearrayExtend(thread_, array, view);
1282 Int base(&scope, SmallInt::fromWord(36));
1283 EXPECT_TRUE(raisedWithStr(
1284 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, array, base),
1285 LayoutId::kValueError, "invalid literal for int() with base 36: b'$'"));
1286}
1287
1288TEST_F(UnderBuiltinsModuleTest,
1289 UnderIntNewFromByteslikeWithInvalidLiteraRaisesValueError) {
1290 HandleScope scope(thread_);
1291 const byte view[] = {'a'};
1292 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1293 Bytearray array(&scope, runtime_->newBytearray());
1294 runtime_->bytearrayExtend(thread_, array, view);
1295 Int base(&scope, SmallInt::fromWord(10));
1296 EXPECT_TRUE(raisedWithStr(
1297 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, array, base),
1298 LayoutId::kValueError, "invalid literal for int() with base 10: b'a'"));
1299}
1300
1301TEST_F(UnderBuiltinsModuleTest,
1302 UnderIntNewFromByteslikeWithInvalidByteRaisesValueError) {
1303 HandleScope scope(thread_);
1304 const byte view[] = {'$'};
1305 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1306 Bytes bytes(&scope, runtime_->newBytesWithAll(view));
1307 Int base(&scope, SmallInt::fromWord(36));
1308 EXPECT_TRUE(raisedWithStr(
1309 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1310 LayoutId::kValueError, "invalid literal for int() with base 36: b'$'"));
1311}
1312
1313TEST_F(UnderBuiltinsModuleTest,
1314 UnderIntNewFromByteslikeWithInvalidLiteralRaisesValueError) {
1315 HandleScope scope(thread_);
1316 const byte view[] = {'8', '6'};
1317 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1318 Bytes bytes(&scope, runtime_->newBytesWithAll(view));
1319 Int base(&scope, SmallInt::fromWord(7));
1320 EXPECT_TRUE(raisedWithStr(
1321 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1322 LayoutId::kValueError, "invalid literal for int() with base 7: b'86'"));
1323}
1324
1325TEST_F(UnderBuiltinsModuleTest,
1326 UnderIntNewFromByteslikeWithBytesSubclassReturnsSmallInt) {
1327 HandleScope scope(thread_);
1328 ASSERT_FALSE(runFromCStr(runtime_, R"(
1329class Foo(bytes): pass
1330foo = Foo(b"42")
1331)")
1332 .isError());
1333 Object type(&scope, runtime_->typeAt(LayoutId::kInt));
1334 Object bytes(&scope, mainModuleAt(runtime_, "foo"));
1335 Object base(&scope, SmallInt::fromWord(21));
1336 EXPECT_EQ(
1337 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1338 SmallInt::fromWord(86));
1339}
1340
1341TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromByteslikeWithZero) {
1342 HandleScope scope(thread_);
1343 const byte src[] = {'0'};
1344 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1345 Bytes bytes(&scope, runtime_->newBytesWithAll(src));
1346 Int base(&scope, SmallInt::fromWord(10));
1347 Object result(&scope, runBuiltin(FUNC(_builtins, _int_new_from_byteslike),
1348 type, bytes, base));
1349 EXPECT_TRUE(isIntEqualsWord(*result, 0));
1350}
1351
1352TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromByteslikeWithLargeInt) {
1353 HandleScope scope(thread_);
1354 const byte src[] = "1844674407370955161500";
1355 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1356 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1357 Int base(&scope, SmallInt::fromWord(10));
1358 Object result(&scope, runBuiltin(FUNC(_builtins, _int_new_from_byteslike),
1359 type, bytes, base));
1360 ASSERT_FALSE(result.isError());
1361 EXPECT_TRUE(result.isInt());
1362 const uword digits[] = {0xffffffffffffff9c, 0x63};
1363 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
1364}
1365
1366TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromByteslikeWithLargeInt2) {
1367 HandleScope scope(thread_);
1368 const byte src[] = "46116860184273879030";
1369 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1370 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1371 Int base(&scope, SmallInt::fromWord(10));
1372 Object result(&scope, runBuiltin(FUNC(_builtins, _int_new_from_byteslike),
1373 type, bytes, base));
1374 ASSERT_FALSE(result.isError());
1375 EXPECT_TRUE(result.isInt());
1376 const uword digits[] = {0x7ffffffffffffff6, 0x2};
1377 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
1378}
1379
1380TEST_F(UnderBuiltinsModuleTest,
1381 UnderIntNewFromByteslikeWithLargeIntWithInvalidDigitRaisesValueError) {
1382 HandleScope scope(thread_);
1383 const byte src[] = "461168601$84273879030";
1384 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1385 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1386 Int base(&scope, SmallInt::fromWord(10));
1387 EXPECT_TRUE(raisedWithStr(
1388 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1389 LayoutId::kValueError,
1390 "invalid literal for int() with base 10: b'461168601$84273879030'"));
1391}
1392
1393TEST_F(UnderBuiltinsModuleTest,
1394 UnderIntNewFromByteslikeWithLeadingPlusReturnsInt) {
1395 HandleScope scope(thread_);
1396 const byte src[] = "+46116860184273879030";
1397 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1398 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1399 Int base(&scope, SmallInt::fromWord(10));
1400 Int result(&scope, runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type,
1401 bytes, base));
1402 ASSERT_FALSE(result.isError());
1403 EXPECT_TRUE(result.isInt());
1404 const uword digits[] = {0x7ffffffffffffff6, 0x2};
1405 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
1406}
1407
1408TEST_F(UnderBuiltinsModuleTest,
1409 UnderIntNewFromByteslikeWithDoubleLeadingPlusRaisesValueError) {
1410 HandleScope scope(thread_);
1411 const byte src[] = "++1";
1412 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1413 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1414 Int base(&scope, SmallInt::fromWord(10));
1415 EXPECT_TRUE(raisedWithStr(
1416 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1417 LayoutId::kValueError, "invalid literal for int() with base 10: b'++1'"));
1418}
1419
1420TEST_F(UnderBuiltinsModuleTest,
1421 UnderIntNewFromByteslikeWithLeadingNegAndSpaceReturnsInt) {
1422 HandleScope scope(thread_);
1423 const byte src[] = " -46116860184273879030";
1424 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1425 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1426 Int base(&scope, SmallInt::fromWord(10));
1427 Int result(&scope, runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type,
1428 bytes, base));
1429 ASSERT_FALSE(result.isError());
1430 EXPECT_TRUE(result.isInt());
1431 const uword digits[] = {0x800000000000000a, 0xfffffffffffffffd};
1432 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
1433}
1434
1435TEST_F(UnderBuiltinsModuleTest,
1436 UnderIntNewFromByteslikeWithDoubleLeadingNegRaisesValueError) {
1437 HandleScope scope(thread_);
1438 const byte src[] = "--1";
1439 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1440 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1441 Int base(&scope, SmallInt::fromWord(10));
1442 EXPECT_TRUE(raisedWithStr(
1443 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1444 LayoutId::kValueError, "invalid literal for int() with base 10: b'--1'"));
1445}
1446
1447TEST_F(UnderBuiltinsModuleTest,
1448 UnderIntNewFromByteslikeWithHexPrefixAndBaseZeroReturnsInt) {
1449 HandleScope scope(thread_);
1450 const byte src[] = "0x1f";
1451 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1452 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1453 Int base(&scope, SmallInt::fromWord(0));
1454 EXPECT_EQ(
1455 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1456 SmallInt::fromWord(31));
1457}
1458
1459TEST_F(UnderBuiltinsModuleTest,
1460 UnderIntNewFromByteslikeWithHexPrefixAndBaseSixteenReturnsInt) {
1461 HandleScope scope(thread_);
1462 const byte src[] = "0x1f";
1463 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1464 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1465 Int base(&scope, SmallInt::fromWord(16));
1466 EXPECT_EQ(
1467 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1468 SmallInt::fromWord(31));
1469}
1470
1471TEST_F(UnderBuiltinsModuleTest,
1472 UnderIntNewFromByteslikeWithHexPrefixAndBaseNineRaisesValueError) {
1473 HandleScope scope(thread_);
1474 const byte src[] = "0x1f";
1475 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1476 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1477 Int base(&scope, SmallInt::fromWord(9));
1478 EXPECT_TRUE(raisedWithStr(
1479 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1480 LayoutId::kValueError, "invalid literal for int() with base 9: b'0x1f'"));
1481}
1482
1483TEST_F(UnderBuiltinsModuleTest,
1484 UnderIntNewFromByteslikeWithBaseThreeReturnsInt) {
1485 HandleScope scope(thread_);
1486 const byte src[] = "221";
1487 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1488 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1489 Int base(&scope, SmallInt::fromWord(3));
1490 EXPECT_EQ(
1491 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1492 SmallInt::fromWord(25));
1493}
1494
1495TEST_F(UnderBuiltinsModuleTest,
1496 UnderIntNewFromByteslikeWithUnderscoreReturnsInt) {
1497 HandleScope scope(thread_);
1498 const byte src[] = "1_000_000";
1499 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1500 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1501 Int base(&scope, SmallInt::fromWord(10));
1502 EXPECT_EQ(
1503 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1504 SmallInt::fromWord(1000000));
1505}
1506
1507TEST_F(UnderBuiltinsModuleTest,
1508 UnderIntNewFromByteslikeWithLeadingUnderscoreRaisesValueError) {
1509 HandleScope scope(thread_);
1510 const byte src[] = "_1";
1511 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1512 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1513 Int base(&scope, SmallInt::fromWord(0));
1514 EXPECT_TRUE(raisedWithStr(
1515 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1516 LayoutId::kValueError, "invalid literal for int() with base 0: b'_1'"));
1517}
1518
1519TEST_F(
1520 UnderBuiltinsModuleTest,
1521 UnderIntNewFromByteslikeWithLeadingUnderscoreAndPrefixAndBaseReturnsInt) {
1522 HandleScope scope(thread_);
1523 const byte src[] = "0b_1";
1524 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1525 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1526 Int base(&scope, SmallInt::fromWord(2));
1527 EXPECT_EQ(
1528 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1529 SmallInt::fromWord(1));
1530}
1531
1532TEST_F(UnderBuiltinsModuleTest,
1533 UnderIntNewFromByteslikeWithTrailingUnderscoreRaisesValueError) {
1534 HandleScope scope(thread_);
1535 const byte src[] = "1_000_";
1536 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1537 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1538 Int base(&scope, SmallInt::fromWord(0));
1539 EXPECT_TRUE(raisedWithStr(
1540 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1541 LayoutId::kValueError,
1542 "invalid literal for int() with base 0: b'1_000_'"));
1543}
1544
1545TEST_F(UnderBuiltinsModuleTest,
1546 UnderIntNewFromByteslikeWithDoubleUnderscoreRaisesValueError) {
1547 HandleScope scope(thread_);
1548 const byte src[] = "1__000";
1549 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1550 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1551 Int base(&scope, SmallInt::fromWord(0));
1552 EXPECT_TRUE(raisedWithStr(
1553 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1554 LayoutId::kValueError,
1555 "invalid literal for int() with base 0: b'1__000'"));
1556}
1557
1558TEST_F(UnderBuiltinsModuleTest,
1559 UnderIntNewFromByteslikeWithWhitespaceOnLeftReturnsInt) {
1560 HandleScope scope(thread_);
1561 const byte src[] = " \t\n\t\v-123";
1562 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1563 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1564 Int base(&scope, SmallInt::fromWord(10));
1565 EXPECT_EQ(
1566 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1567 SmallInt::fromWord(-123));
1568}
1569
1570TEST_F(UnderBuiltinsModuleTest,
1571 UnderIntNewFromByteslikeWithWhitespaceOnRightReturnsInt) {
1572 HandleScope scope(thread_);
1573 const byte src[] = "-234 \t \f \n\t";
1574 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1575 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1576 Int base(&scope, SmallInt::fromWord(10));
1577 EXPECT_EQ(
1578 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1579 SmallInt::fromWord(-234));
1580}
1581
1582TEST_F(UnderBuiltinsModuleTest,
1583 UnderIntNewFromByteslikeWithWhitespaceOnLeftAndRightReturnsInt) {
1584 HandleScope scope(thread_);
1585 const byte src[] = " \n\t\r\n +345 \t \n\t";
1586 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1587 Bytes bytes(&scope, runtime_->newBytesWithAll({src, ARRAYSIZE(src) - 1}));
1588 Int base(&scope, SmallInt::fromWord(10));
1589 EXPECT_EQ(
1590 runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type, bytes, base),
1591 SmallInt::fromWord(345));
1592}
1593
1594TEST_F(UnderBuiltinsModuleTest,
1595 UnderIntNewFromByteslikeWithMemoryviewReturnsInt) {
1596 HandleScope scope(thread_);
1597 const byte bytes[] = {'-', '1', '2'};
1598 MemoryView memoryview(&scope, newMemoryView(bytes, "b"));
1599 MemoryView memoryview_slice(
1600 &scope, memoryviewGetslice(thread_, memoryview, /*start=*/1, /*stop=*/2,
1601 /*step=*/1));
1602 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1603 Int base(&scope, SmallInt::fromWord(10));
1604 EXPECT_EQ(runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type,
1605 memoryview_slice, base),
1606 SmallInt::fromWord(1));
1607}
1608
1609TEST_F(UnderBuiltinsModuleTest,
1610 UnderIntNewFromByteslikeWithMemoryviewSliceReturnsInt) {
1611 HandleScope scope(thread_);
1612 const byte bytes[] = {'-', '1', '2'};
1613 Object memoryview(&scope, newMemoryView(bytes, "b"));
1614 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1615 Int base(&scope, SmallInt::fromWord(10));
1616 EXPECT_EQ(runBuiltin(FUNC(_builtins, _int_new_from_byteslike), type,
1617 memoryview, base),
1618 SmallInt::fromWord(-12));
1619}
1620
1621TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromIntWithBoolReturnsSmallInt) {
1622 HandleScope scope(thread_);
1623 Object type(&scope, runtime_->typeAt(LayoutId::kInt));
1624 Object fls(&scope, Bool::falseObj());
1625 Object tru(&scope, Bool::trueObj());
1626 Object false_result(
1627 &scope, runBuiltin(FUNC(_builtins, _int_new_from_int), type, fls));
1628 Object true_result(&scope,
1629 runBuiltin(FUNC(_builtins, _int_new_from_int), type, tru));
1630 EXPECT_EQ(false_result, SmallInt::fromWord(0));
1631 EXPECT_EQ(true_result, SmallInt::fromWord(1));
1632}
1633
1634TEST_F(UnderBuiltinsModuleTest,
1635 UnderIntNewFromIntWithSubClassReturnsValueOfSubClass) {
1636 ASSERT_FALSE(runFromCStr(runtime_, R"(
1637class SubInt(int):
1638 def __new__(cls, value):
1639 self = super(SubInt, cls).__new__(cls, value)
1640 self.name = "subint instance"
1641 return self
1642
1643result = SubInt(50)
1644)")
1645 .isError());
1646 HandleScope scope(thread_);
1647 Object result(&scope, mainModuleAt(runtime_, "result"));
1648 EXPECT_FALSE(result.isInt());
1649 EXPECT_TRUE(isIntEqualsWord(*result, 50));
1650}
1651
1652TEST_F(UnderBuiltinsModuleTest,
1653 UnderIntNewFromStrWithZeroBaseReturnsCodeLiteral) {
1654 HandleScope scope(thread_);
1655 const char* src = "1985";
1656 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1657 Str str(&scope, runtime_->newStrFromCStr(src));
1658 Int base(&scope, SmallInt::fromWord(0));
1659 Object result(
1660 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1661 EXPECT_TRUE(isIntEqualsWord(*result, 1985));
1662}
1663
1664TEST_F(UnderBuiltinsModuleTest,
1665 UnderIntNewFromStrWithInvalidCharRaisesValueError) {
1666 HandleScope scope(thread_);
1667 const char* src = "$";
1668 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1669 Str str(&scope, runtime_->newStrFromCStr(src));
1670 Int base(&scope, SmallInt::fromWord(36));
1671 EXPECT_TRUE(raisedWithStr(
1672 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1673 LayoutId::kValueError, "invalid literal for int() with base 36: '$'"));
1674}
1675
1676TEST_F(UnderBuiltinsModuleTest,
1677 UnderIntNewFromStrWithInvalidLiteralRaisesValueError) {
1678 HandleScope scope(thread_);
1679 const char* src = "305";
1680 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1681 Str str(&scope, runtime_->newStrFromCStr(src));
1682 Int base(&scope, SmallInt::fromWord(4));
1683 EXPECT_TRUE(raisedWithStr(
1684 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1685 LayoutId::kValueError, "invalid literal for int() with base 4: '305'"));
1686}
1687
1688TEST_F(UnderBuiltinsModuleTest,
1689 UnderIntNewFromStrWithInvalidLiteralRaisesValueErrorBaseSixteen) {
1690 HandleScope scope(thread_);
1691 const char* src = "g";
1692 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1693 Str str(&scope, runtime_->newStrFromCStr(src));
1694 Int base(&scope, SmallInt::fromWord(16));
1695 EXPECT_TRUE(raisedWithStr(
1696 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1697 LayoutId::kValueError, "invalid literal for int() with base 16: 'g'"));
1698}
1699
1700TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithLargeInt) {
1701 HandleScope scope(thread_);
1702 const char* src = "1844674407370955161500";
1703 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1704 Str str(&scope, runtime_->newStrFromCStr(src));
1705 Int base(&scope, SmallInt::fromWord(10));
1706 Object result(
1707 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1708 ASSERT_FALSE(result.isError());
1709 EXPECT_TRUE(result.isInt());
1710 const uword digits[] = {0xffffffffffffff9c, 0x63};
1711 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
1712}
1713
1714TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithLargeInt2) {
1715 HandleScope scope(thread_);
1716 const char* src = "46116860184273879030";
1717 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1718 Str str(&scope, runtime_->newStrFromCStr(src));
1719 Int base(&scope, SmallInt::fromWord(10));
1720 Object result(
1721 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1722 ASSERT_FALSE(result.isError());
1723 EXPECT_TRUE(result.isInt());
1724 const uword digits[] = {0x7ffffffffffffff6, 0x2};
1725 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
1726}
1727
1728TEST_F(UnderBuiltinsModuleTest,
1729 UnderIntNewFromStrWithLargeIntWithInvalidDigitRaisesValueError) {
1730 HandleScope scope(thread_);
1731 const char* src = "461168601$84273879030";
1732 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1733 Str str(&scope, runtime_->newStrFromCStr(src));
1734 Int base(&scope, SmallInt::fromWord(10));
1735 EXPECT_TRUE(raisedWithStr(
1736 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1737 LayoutId::kValueError,
1738 "invalid literal for int() with base 10: '461168601$84273879030'"));
1739}
1740
1741TEST_F(UnderBuiltinsModuleTest,
1742 UnderIntNewFromStrWithOnlySignRaisesValueError) {
1743 HandleScope scope(thread_);
1744 const char* src = "-";
1745 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1746 Str str(&scope, runtime_->newStrFromCStr(src));
1747 Int base(&scope, SmallInt::fromWord(0));
1748 EXPECT_TRUE(raisedWithStr(
1749 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1750 LayoutId::kValueError, "invalid literal for int() with base 10: '-'"));
1751}
1752
1753TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithLengthOneInfersBase10) {
1754 HandleScope scope(thread_);
1755 const char* src = "8";
1756 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1757 Str str(&scope, runtime_->newStrFromCStr(src));
1758 Int base(&scope, SmallInt::fromWord(0));
1759 Object result(
1760 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1761 EXPECT_TRUE(isIntEqualsWord(*result, 8));
1762}
1763
1764TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithLengthOneBase10) {
1765 HandleScope scope(thread_);
1766 const char* src = "8";
1767 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1768 Str str(&scope, runtime_->newStrFromCStr(src));
1769 Int base(&scope, SmallInt::fromWord(10));
1770 Object result(
1771 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1772 EXPECT_TRUE(isIntEqualsWord(*result, 8));
1773}
1774
1775TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithLargeIntBaseTwo) {
1776 HandleScope scope(thread_);
1777 const char* src = "100";
1778 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1779 Str str(&scope, runtime_->newStrFromCStr(src));
1780 Int base(&scope, SmallInt::fromWord(2));
1781 Object result(
1782 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1783 EXPECT_TRUE(isIntEqualsWord(*result, 4));
1784}
1785
1786TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithLargeIntInfersBaseTen) {
1787 HandleScope scope(thread_);
1788 const char* src = "100";
1789 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1790 Str str(&scope, runtime_->newStrFromCStr(src));
1791 Int base(&scope, SmallInt::fromWord(0));
1792 Object result(
1793 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1794 EXPECT_TRUE(isIntEqualsWord(*result, 100));
1795}
1796
1797TEST_F(UnderBuiltinsModuleTest,
1798 UnderIntNewFromStrWithLeadingSpacesRemovesSpaces) {
1799 HandleScope scope(thread_);
1800 const char* src = " 100";
1801 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1802 Str str(&scope, runtime_->newStrFromCStr(src));
1803 Int base(&scope, SmallInt::fromWord(0));
1804 Object result(
1805 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1806 EXPECT_TRUE(isIntEqualsWord(*result, 100));
1807}
1808
1809TEST_F(UnderBuiltinsModuleTest,
1810 UnderIntNewFromStrWithOnlySpacesRaisesValueError) {
1811 HandleScope scope(thread_);
1812 const char* src = " ";
1813 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1814 Str str(&scope, runtime_->newStrFromCStr(src));
1815 Int base(&scope, SmallInt::fromWord(0));
1816 EXPECT_TRUE(raisedWithStr(
1817 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1818 LayoutId::kValueError, "invalid literal for int() with base 10: ' '"));
1819}
1820
1821TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithPlusReturnsPositiveInt) {
1822 HandleScope scope(thread_);
1823 const char* src = "+100";
1824 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1825 Str str(&scope, runtime_->newStrFromCStr(src));
1826 Int base(&scope, SmallInt::fromWord(0));
1827 Object result(
1828 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1829 EXPECT_TRUE(isIntEqualsWord(*result, 100));
1830}
1831
1832TEST_F(UnderBuiltinsModuleTest,
1833 UnderIntNewFromStrWithTwoPlusSignsRaisesValueError) {
1834 HandleScope scope(thread_);
1835 const char* src = "++100";
1836 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1837 Str str(&scope, runtime_->newStrFromCStr(src));
1838 Int base(&scope, SmallInt::fromWord(16));
1839 EXPECT_TRUE(raisedWithStr(
1840 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1841 LayoutId::kValueError,
1842 "invalid literal for int() with base 16: '++100'"));
1843}
1844
1845TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithLargeIntBaseEight) {
1846 HandleScope scope(thread_);
1847 const char* src = "0o77712371237123712371237123777";
1848 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1849 Str str(&scope, runtime_->newStrFromCStr(src));
1850 Int base(&scope, SmallInt::fromWord(8));
1851 Object result(
1852 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1853 const uword digits[] = {0xa7ca7ca7ca7ca7ff, 0x7fca7c};
1854 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
1855}
1856
1857TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithLargeIntInfersBaseEight) {
1858 HandleScope scope(thread_);
1859 const char* src = "0o77712371237123712371237123777";
1860 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1861 Str str(&scope, runtime_->newStrFromCStr(src));
1862 Int base(&scope, SmallInt::fromWord(0));
1863 Object result(
1864 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1865 const uword digits[] = {0xa7ca7ca7ca7ca7ff, 0x7fca7c};
1866 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
1867}
1868
1869TEST_F(UnderBuiltinsModuleTest,
1870 UnderIntNewFromStrWithOnlyPrefixRaisesValueError) {
1871 HandleScope scope(thread_);
1872 const char* src = "0x";
1873 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1874 Str str(&scope, runtime_->newStrFromCStr(src));
1875 Int base(&scope, SmallInt::fromWord(16));
1876 EXPECT_TRUE(raisedWithStr(
1877 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1878 LayoutId::kValueError, "invalid literal for int() with base 16: '0x'"));
1879}
1880
1881TEST_F(UnderBuiltinsModuleTest,
1882 UnderIntNewFromStrWithMinusAndPrefixRaisesValueError) {
1883 HandleScope scope(thread_);
1884 const char* src = "-0x";
1885 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1886 Str str(&scope, runtime_->newStrFromCStr(src));
1887 Int base(&scope, SmallInt::fromWord(16));
1888 EXPECT_TRUE(raisedWithStr(
1889 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1890 LayoutId::kValueError, "invalid literal for int() with base 16: '-0x'"));
1891}
1892
1893TEST_F(UnderBuiltinsModuleTest,
1894 UnderIntNewFromStrWithPlusAndPrefixRaisesValueError) {
1895 HandleScope scope(thread_);
1896 const char* src = "+0x";
1897 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1898 Str str(&scope, runtime_->newStrFromCStr(src));
1899 Int base(&scope, SmallInt::fromWord(16));
1900 EXPECT_TRUE(raisedWithStr(
1901 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1902 LayoutId::kValueError, "invalid literal for int() with base 16: '+0x'"));
1903}
1904
1905TEST_F(UnderBuiltinsModuleTest,
1906 UnderIntNewFromStrWithJustPrefixAndUnderscoreRaisesValueError) {
1907 HandleScope scope(thread_);
1908 const char* src = "0x_";
1909 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1910 Str str(&scope, runtime_->newStrFromCStr(src));
1911 Int base(&scope, SmallInt::fromWord(16));
1912 EXPECT_TRUE(raisedWithStr(
1913 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1914 LayoutId::kValueError, "invalid literal for int() with base 16: '0x_'"));
1915}
1916
1917TEST_F(UnderBuiltinsModuleTest,
1918 UnderIntNewFromStrWithUnderscoreIgnoresUnderscore) {
1919 HandleScope scope(thread_);
1920 const char* src = "0x_deadbeef";
1921 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1922 Str str(&scope, runtime_->newStrFromCStr(src));
1923 Int base(&scope, SmallInt::fromWord(0));
1924 Object result(
1925 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1926 EXPECT_TRUE(isIntEqualsWord(*result, 0xdeadbeef));
1927}
1928
1929TEST_F(UnderBuiltinsModuleTest,
1930 UnderIntNewFromStrWithUnderscoresIgnoresUnderscoresBaseSixteen) {
1931 HandleScope scope(thread_);
1932 const char* src = "0x_d_e_a_d_b_eef";
1933 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1934 Str str(&scope, runtime_->newStrFromCStr(src));
1935 Int base(&scope, SmallInt::fromWord(0));
1936 Object result(
1937 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1938 EXPECT_TRUE(isIntEqualsWord(*result, 0xdeadbeef));
1939}
1940
1941TEST_F(UnderBuiltinsModuleTest,
1942 UnderIntNewFromStrWithUnderscoresIgnoresUnderscoresBaseTen) {
1943 HandleScope scope(thread_);
1944 const char* src = "100_000_000_000";
1945 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1946 Str str(&scope, runtime_->newStrFromCStr(src));
1947 Int base(&scope, SmallInt::fromWord(0));
1948 Object result(
1949 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
1950 EXPECT_TRUE(isIntEqualsWord(*result, 100000000000));
1951}
1952
1953TEST_F(UnderBuiltinsModuleTest,
1954 UnderIntNewFromStrWithLeadingUnderscoreBaseTenRaisesValueError) {
1955 HandleScope scope(thread_);
1956 const char* src = "_100";
1957 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1958 Str str(&scope, runtime_->newStrFromCStr(src));
1959 Int base(&scope, SmallInt::fromWord(10));
1960 EXPECT_TRUE(raisedWithStr(
1961 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1962 LayoutId::kValueError, "invalid literal for int() with base 10: '_100'"));
1963}
1964
1965TEST_F(UnderBuiltinsModuleTest,
1966 UnderIntNewFromStrWithTrailingUnderscoreBaseTenRaisesValueError) {
1967 HandleScope scope(thread_);
1968 const char* src = "100_";
1969 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1970 Str str(&scope, runtime_->newStrFromCStr(src));
1971 Int base(&scope, SmallInt::fromWord(10));
1972 EXPECT_TRUE(raisedWithStr(
1973 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1974 LayoutId::kValueError, "invalid literal for int() with base 10: '100_'"));
1975}
1976
1977TEST_F(UnderBuiltinsModuleTest,
1978 UnderIntNewFromStrWithDoubleUnderscoreBaseTenRaisesValueError) {
1979 HandleScope scope(thread_);
1980 const char* src = "1__00";
1981 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1982 Str str(&scope, runtime_->newStrFromCStr(src));
1983 Int base(&scope, SmallInt::fromWord(10));
1984 EXPECT_TRUE(raisedWithStr(
1985 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1986 LayoutId::kValueError,
1987 "invalid literal for int() with base 10: '1__00'"));
1988}
1989
1990TEST_F(UnderBuiltinsModuleTest,
1991 UnderIntNewFromStrWithLeadingUnderscoreNoPrefixRaisesValueError) {
1992 HandleScope scope(thread_);
1993 const char* src = "_abc";
1994 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
1995 Str str(&scope, runtime_->newStrFromCStr(src));
1996 Int base(&scope, SmallInt::fromWord(16));
1997 EXPECT_TRUE(raisedWithStr(
1998 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
1999 LayoutId::kValueError, "invalid literal for int() with base 16: '_abc'"));
2000}
2001
2002TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithNegativeZeroReturnsZero) {
2003 HandleScope scope(thread_);
2004 const char* src = "-0";
2005 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2006 Str str(&scope, runtime_->newStrFromCStr(src));
2007 Int base(&scope, SmallInt::fromWord(0));
2008 Object result(
2009 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
2010 EXPECT_TRUE(isIntEqualsWord(*result, 0));
2011}
2012
2013TEST_F(UnderBuiltinsModuleTest,
2014 UnderIntNewFromStrWithTwoMinusSignsRaisesValueError) {
2015 HandleScope scope(thread_);
2016 const char* src = "--100";
2017 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2018 Str str(&scope, runtime_->newStrFromCStr(src));
2019 Int base(&scope, SmallInt::fromWord(16));
2020 EXPECT_TRUE(raisedWithStr(
2021 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
2022 LayoutId::kValueError,
2023 "invalid literal for int() with base 16: '--100'"));
2024}
2025
2026TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithPositiveZeroReturnsZero) {
2027 HandleScope scope(thread_);
2028 const char* src = "+0";
2029 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2030 Str str(&scope, runtime_->newStrFromCStr(src));
2031 Int base(&scope, SmallInt::fromWord(0));
2032 Object result(
2033 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
2034 EXPECT_TRUE(isIntEqualsWord(*result, 0));
2035}
2036
2037TEST_F(UnderBuiltinsModuleTest,
2038 UnderIntNewFromStrWithEmptyStringRaisesValueError) {
2039 HandleScope scope(thread_);
2040 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2041 Str str(&scope, Str::empty());
2042 Int base(&scope, SmallInt::fromWord(0));
2043 EXPECT_TRUE(raisedWithStr(
2044 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
2045 LayoutId::kValueError, "invalid literal for int() with base 10: ''"));
2046}
2047
2048TEST_F(UnderBuiltinsModuleTest,
2049 UnderIntNewFromStrWithHexLiteralNoPrefixRaisesValueError) {
2050 HandleScope scope(thread_);
2051 const char* src = "a";
2052 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2053 Str str(&scope, runtime_->newStrFromCStr(src));
2054 Int base(&scope, SmallInt::fromWord(0));
2055 EXPECT_TRUE(raisedWithStr(
2056 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
2057 LayoutId::kValueError, "invalid literal for int() with base 10: 'a'"));
2058}
2059
2060TEST_F(UnderBuiltinsModuleTest, UnderIntNewFromStrWithLargeIntBaseSixteen) {
2061 HandleScope scope(thread_);
2062 const char* src = "0x8000000000000000";
2063 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2064 Str str(&scope, runtime_->newStrFromCStr(src));
2065 Int base(&scope, SmallInt::fromWord(16));
2066 Object result(
2067 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
2068 const uword digits[] = {0x8000000000000000, 0x0};
2069 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
2070}
2071
2072TEST_F(UnderBuiltinsModuleTest,
2073 UnderIntNewFromStrWithLargeIntInfersBaseSixteen) {
2074 HandleScope scope(thread_);
2075 const char* src = "0x8000000000000000";
2076 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2077 Str str(&scope, runtime_->newStrFromCStr(src));
2078 Int base(&scope, SmallInt::fromWord(0));
2079 Object result(
2080 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
2081 const uword digits[] = {0x8000000000000000, 0x0};
2082 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
2083}
2084
2085TEST_F(UnderBuiltinsModuleTest,
2086 UnderIntNewFromStrWithLargeIntBaseSixteenWithLetters) {
2087 HandleScope scope(thread_);
2088 const char* src = "0x80000000DEADBEEF";
2089 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2090 Str str(&scope, runtime_->newStrFromCStr(src));
2091 Int base(&scope, SmallInt::fromWord(16));
2092 Object result(
2093 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
2094 const uword digits[] = {0x80000000deadbeef, 0x0};
2095 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
2096}
2097
2098TEST_F(UnderBuiltinsModuleTest,
2099 UnderIntNewFromStrWithLargeIntInfersBaseSixteenWithLetters) {
2100 HandleScope scope(thread_);
2101 const char* src = "0x80000000DEADBEEF";
2102 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2103 Str str(&scope, runtime_->newStrFromCStr(src));
2104 Int base(&scope, SmallInt::fromWord(0));
2105 Object result(
2106 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
2107 const uword digits[] = {0x80000000deadbeef, 0x0};
2108 EXPECT_TRUE(isIntEqualsDigits(*result, digits));
2109}
2110
2111TEST_F(UnderBuiltinsModuleTest,
2112 UnderIntNewFromStrWithBinaryLiteralBaseZeroReturnsOne) {
2113 HandleScope scope(thread_);
2114 const char* src = "0b1";
2115 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2116 Str str(&scope, runtime_->newStrFromCStr(src));
2117 Int base(&scope, SmallInt::fromWord(0));
2118 Object result(
2119 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
2120 EXPECT_TRUE(isIntEqualsWord(*result, 1));
2121}
2122
2123TEST_F(UnderBuiltinsModuleTest,
2124 UnderIntNewFromStrWithBinaryLiteralBaseTwoReturnsOne) {
2125 HandleScope scope(thread_);
2126 const char* src = "0b1";
2127 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2128 Str str(&scope, runtime_->newStrFromCStr(src));
2129 Int base(&scope, SmallInt::fromWord(2));
2130 Object result(
2131 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
2132 EXPECT_TRUE(isIntEqualsWord(*result, 1));
2133}
2134
2135TEST_F(
2136 UnderBuiltinsModuleTest,
2137 UnderIntNewFromStrWithBinaryLiteralBaseSixteenReturnsOneHundredSeventySeven) {
2138 HandleScope scope(thread_);
2139 const char* src = "0b1";
2140 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2141 Str str(&scope, runtime_->newStrFromCStr(src));
2142 Int base(&scope, SmallInt::fromWord(16));
2143 Object result(
2144 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
2145 EXPECT_TRUE(isIntEqualsWord(*result, 177));
2146}
2147
2148TEST_F(UnderBuiltinsModuleTest,
2149 UnderIntNewFromStrWithBinaryLiteralBaseSixteenReturnsEleven) {
2150 HandleScope scope(thread_);
2151 const char* src = "0b";
2152 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2153 Str str(&scope, runtime_->newStrFromCStr(src));
2154 Int base(&scope, SmallInt::fromWord(16));
2155 Object result(
2156 &scope, runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base));
2157 EXPECT_TRUE(isIntEqualsWord(*result, 11));
2158}
2159
2160TEST_F(UnderBuiltinsModuleTest,
2161 UnderIntNewFromStrWithBinaryLiteralBaseEightRaisesValueError) {
2162 HandleScope scope(thread_);
2163 const char* src = "0b1";
2164 Type type(&scope, runtime_->typeAt(LayoutId::kInt));
2165 Str str(&scope, runtime_->newStrFromCStr(src));
2166 Int base(&scope, SmallInt::fromWord(8));
2167 EXPECT_TRUE(raisedWithStr(
2168 runBuiltin(FUNC(_builtins, _int_new_from_str), type, str, base),
2169 LayoutId::kValueError, "invalid literal for int() with base 8: '0b1'"));
2170}
2171
2172TEST_F(UnderBuiltinsModuleTest, UnderListAppendAppendsObject) {
2173 HandleScope scope(thread_);
2174 List list(&scope, runtime_->newList());
2175 Object value0(&scope, runtime_->newInt(42));
2176 Object value1(&scope, runtime_->newStrFromCStr("foo"));
2177 EXPECT_EQ(list.numItems(), 0);
2178 EXPECT_TRUE(
2179 runBuiltin(FUNC(_builtins, _list_append), list, value0).isNoneType());
2180 EXPECT_EQ(list.numItems(), 1);
2181 EXPECT_TRUE(
2182 runBuiltin(FUNC(_builtins, _list_append), list, value1).isNoneType());
2183 ASSERT_EQ(list.numItems(), 2);
2184 EXPECT_EQ(list.at(0), value0);
2185 EXPECT_EQ(list.at(1), value1);
2186}
2187
2188TEST_F(UnderBuiltinsModuleTest, UnderListCheckExactWithExactListReturnsTrue) {
2189 HandleScope scope(thread_);
2190 Object obj(&scope, runtime_->newList());
2191 EXPECT_EQ(runBuiltin(FUNC(_builtins, _list_check_exact), obj),
2192 Bool::trueObj());
2193}
2194
2195TEST_F(UnderBuiltinsModuleTest,
2196 UnderListCheckExactWithListSubclassReturnsFalse) {
2197 ASSERT_FALSE(runFromCStr(runtime_, R"(
2198class C(list):
2199 pass
2200obj = C()
2201)")
2202 .isError());
2203 HandleScope scope(thread_);
2204 Object obj(&scope, mainModuleAt(runtime_, "obj"));
2205 EXPECT_EQ(runBuiltin(FUNC(_builtins, _list_check_exact), obj),
2206 Bool::falseObj());
2207}
2208
2209TEST_F(UnderBuiltinsModuleTest,
2210 UnderListDelitemWithNegativeIndexRemovesRelativeToEnd) {
2211 HandleScope scope(thread_);
2212 List list(&scope, listFromRange(1, 4));
2213 Object idx(&scope, SmallInt::fromWord(-3));
2214 ASSERT_TRUE(
2215 runBuiltin(FUNC(_builtins, _list_delitem), list, idx).isNoneType());
2216 EXPECT_PYLIST_EQ(list, {2, 3});
2217}
2218
2219TEST_F(UnderBuiltinsModuleTest, UnderListDelitemWithLastIndexRemovesLastItem) {
2220 HandleScope scope(thread_);
2221 List list(&scope, listFromRange(0, 2));
2222 Object idx(&scope, SmallInt::fromWord(1));
2223 ASSERT_TRUE(
2224 runBuiltin(FUNC(_builtins, _list_delitem), list, idx).isNoneType());
2225 EXPECT_PYLIST_EQ(list, {0});
2226}
2227
2228TEST_F(UnderBuiltinsModuleTest,
2229 UnderListDelitemWithFirstIndexRemovesFirstItem) {
2230 HandleScope scope(thread_);
2231 List list(&scope, listFromRange(0, 2));
2232 Object idx(&scope, SmallInt::fromWord(0));
2233 ASSERT_TRUE(
2234 runBuiltin(FUNC(_builtins, _list_delitem), list, idx).isNoneType());
2235 EXPECT_PYLIST_EQ(list, {1});
2236}
2237
2238TEST_F(UnderBuiltinsModuleTest,
2239 UnderListDelitemWithNegativeFirstIndexRemovesFirstItem) {
2240 HandleScope scope(thread_);
2241 List list(&scope, listFromRange(0, 2));
2242 Object idx(&scope, SmallInt::fromWord(-2));
2243 ASSERT_TRUE(
2244 runBuiltin(FUNC(_builtins, _list_delitem), list, idx).isNoneType());
2245 EXPECT_PYLIST_EQ(list, {1});
2246}
2247
2248TEST_F(UnderBuiltinsModuleTest,
2249 UnderListDelitemWithNegativeLastIndexRemovesLastItem) {
2250 HandleScope scope(thread_);
2251 List list(&scope, listFromRange(0, 2));
2252 Object idx(&scope, SmallInt::fromWord(-1));
2253 ASSERT_TRUE(
2254 runBuiltin(FUNC(_builtins, _list_delitem), list, idx).isNoneType());
2255 EXPECT_PYLIST_EQ(list, {0});
2256}
2257
2258TEST_F(UnderBuiltinsModuleTest,
2259 UnderListDelitemWithNumberGreaterThanSmallIntMaxDoesNotCrash) {
2260 HandleScope scope(thread_);
2261 List list(&scope, listFromRange(0, 2));
2262 Int big(&scope, runtime_->newInt(SmallInt::kMaxValue + 100));
2263 EXPECT_TRUE(raised(runBuiltin(FUNC(_builtins, _list_delitem), list, big),
2264 LayoutId::kIndexError));
2265 EXPECT_PYLIST_EQ(list, {0, 1});
2266}
2267
2268TEST_F(UnderBuiltinsModuleTest, UnderListDelsliceRemovesItems) {
2269 HandleScope scope(thread_);
2270 List list(&scope, listFromRange(1, 4));
2271 Int start(&scope, SmallInt::fromWord(0));
2272 Int stop(&scope, SmallInt::fromWord(1));
2273 Int step(&scope, SmallInt::fromWord(1));
2274 ASSERT_TRUE(
2275 runBuiltin(FUNC(_builtins, _list_delslice), list, start, stop, step)
2276 .isNoneType());
2277 EXPECT_PYLIST_EQ(list, {2, 3});
2278}
2279
2280TEST_F(UnderBuiltinsModuleTest, UnderListDelsliceRemovesFirstItem) {
2281 HandleScope scope(thread_);
2282 List list(&scope, listFromRange(0, 2));
2283 Int start(&scope, SmallInt::fromWord(0));
2284 Int stop(&scope, SmallInt::fromWord(1));
2285 Int step(&scope, SmallInt::fromWord(1));
2286 ASSERT_TRUE(
2287 runBuiltin(FUNC(_builtins, _list_delslice), list, start, stop, step)
2288 .isNoneType());
2289 EXPECT_PYLIST_EQ(list, {1});
2290}
2291
2292TEST_F(UnderBuiltinsModuleTest, UnderListDelsliceRemovesLastItem) {
2293 HandleScope scope(thread_);
2294 List list(&scope, listFromRange(0, 2));
2295 Int start(&scope, SmallInt::fromWord(1));
2296 Int stop(&scope, SmallInt::fromWord(2));
2297 Int step(&scope, SmallInt::fromWord(1));
2298 ASSERT_TRUE(
2299 runBuiltin(FUNC(_builtins, _list_delslice), list, start, stop, step)
2300 .isNoneType());
2301 EXPECT_PYLIST_EQ(list, {0});
2302}
2303
2304TEST_F(UnderBuiltinsModuleTest,
2305 UnderListDelsliceWithStopEqualsLengthRemovesTrailingItems) {
2306 HandleScope scope(thread_);
2307 List list(&scope, listFromRange(1, 4));
2308 Int start(&scope, SmallInt::fromWord(1));
2309 Int stop(&scope, SmallInt::fromWord(3));
2310 Int step(&scope, SmallInt::fromWord(1));
2311 ASSERT_TRUE(
2312 runBuiltin(FUNC(_builtins, _list_delslice), list, start, stop, step)
2313 .isNoneType());
2314 EXPECT_PYLIST_EQ(list, {1});
2315}
2316
2317TEST_F(UnderBuiltinsModuleTest,
2318 UnderListDelsliceWithStartEqualsZeroRemovesStartingItems) {
2319 HandleScope scope(thread_);
2320 List list(&scope, listFromRange(1, 4));
2321 Int start(&scope, SmallInt::fromWord(0));
2322 Int stop(&scope, SmallInt::fromWord(1));
2323 Int step(&scope, SmallInt::fromWord(1));
2324 ASSERT_TRUE(
2325 runBuiltin(FUNC(_builtins, _list_delslice), list, start, stop, step)
2326 .isNoneType());
2327 EXPECT_PYLIST_EQ(list, {2, 3});
2328}
2329
2330TEST_F(UnderBuiltinsModuleTest,
2331 UnderListDelsliceWithStartEqualsZeroAndStopEqualsLengthRemovesAllItems) {
2332 HandleScope scope(thread_);
2333 List list(&scope, listFromRange(1, 4));
2334 Int start(&scope, SmallInt::fromWord(0));
2335 Int stop(&scope, SmallInt::fromWord(3));
2336 Int step(&scope, SmallInt::fromWord(1));
2337 ASSERT_TRUE(
2338 runBuiltin(FUNC(_builtins, _list_delslice), list, start, stop, step)
2339 .isNoneType());
2340 EXPECT_EQ(list.numItems(), 0);
2341}
2342
2343TEST_F(UnderBuiltinsModuleTest,
2344 UnderListDelsliceWithStepEqualsTwoDeletesEveryEvenItem) {
2345 HandleScope scope(thread_);
2346 List list(&scope, listFromRange(0, 5));
2347 Int start(&scope, SmallInt::fromWord(0));
2348 Int stop(&scope, SmallInt::fromWord(5));
2349 Int step(&scope, SmallInt::fromWord(2));
2350 ASSERT_TRUE(
2351 runBuiltin(FUNC(_builtins, _list_delslice), list, start, stop, step)
2352 .isNoneType());
2353 EXPECT_PYLIST_EQ(list, {1, 3});
2354}
2355
2356TEST_F(UnderBuiltinsModuleTest,
2357 UnderListDelsliceWithStepEqualsTwoDeletesEveryOddItem) {
2358 HandleScope scope(thread_);
2359 List list(&scope, listFromRange(0, 5));
2360 Int start(&scope, SmallInt::fromWord(1));
2361 Int stop(&scope, SmallInt::fromWord(5));
2362 Int step(&scope, SmallInt::fromWord(2));
2363 ASSERT_TRUE(
2364 runBuiltin(FUNC(_builtins, _list_delslice), list, start, stop, step)
2365 .isNoneType());
2366 EXPECT_PYLIST_EQ(list, {0, 2, 4});
2367}
2368
2369TEST_F(UnderBuiltinsModuleTest,
2370 UnderListDelsliceWithStepGreaterThanLengthDeletesOneItem) {
2371 HandleScope scope(thread_);
2372 List list(&scope, listFromRange(0, 5));
2373 Int start(&scope, SmallInt::fromWord(0));
2374 Int stop(&scope, SmallInt::fromWord(5));
2375 Int step(&scope, SmallInt::fromWord(1000));
2376 ASSERT_TRUE(
2377 runBuiltin(FUNC(_builtins, _list_delslice), list, start, stop, step)
2378 .isNoneType());
2379 EXPECT_PYLIST_EQ(list, {1, 2, 3, 4});
2380}
2381
2382TEST_F(UnderBuiltinsModuleTest, UnderListGetitemWithNegativeIndex) {
2383 HandleScope scope(thread_);
2384 List list(&scope, listFromRange(1, 4));
2385 Object idx(&scope, SmallInt::fromWord(-3));
2386 Object result(&scope, runBuiltin(FUNC(_builtins, _list_getitem), list, idx));
2387 EXPECT_TRUE(isIntEqualsWord(*result, 1));
2388}
2389
2390TEST_F(UnderBuiltinsModuleTest,
2391 UnderListGetitemWithInvalidNegativeIndexRaisesIndexError) {
2392 HandleScope scope(thread_);
2393 List list(&scope, listFromRange(1, 4));
2394 Object idx(&scope, SmallInt::fromWord(-4));
2395 EXPECT_TRUE(
2396 raisedWithStr(runBuiltin(FUNC(_builtins, _list_getitem), list, idx),
2397 LayoutId::kIndexError, "list index out of range"));
2398}
2399
2400TEST_F(UnderBuiltinsModuleTest,
2401 UnderListGetitemWithInvalidPositiveIndexRaisesIndexError) {
2402 HandleScope scope(thread_);
2403 List list(&scope, listFromRange(1, 4));
2404 Object idx(&scope, SmallInt::fromWord(3));
2405 EXPECT_TRUE(
2406 raisedWithStr(runBuiltin(FUNC(_builtins, _list_getitem), list, idx),
2407 LayoutId::kIndexError, "list index out of range"));
2408}
2409
2410TEST_F(UnderBuiltinsModuleTest, UnderListSwapSwapsItemsAtIndices) {
2411 HandleScope scope(thread_);
2412 List list(&scope, listFromRange(0, 4));
2413 Object i(&scope, SmallInt::fromWord(1));
2414 Object j(&scope, SmallInt::fromWord(2));
2415 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _list_swap), list, i, j).isNoneType());
2416 EXPECT_PYLIST_EQ(list, {0, 2, 1, 3});
2417}
2418
2419TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatbReturnsInt) {
2420 HandleScope scope(thread_);
2421 const byte bytes[] = {0xab, 0xc5};
2422 Object view(&scope, newMemoryView(bytes, "b"));
2423 Int index(&scope, runtime_->newInt(1));
2424 Object result(&scope,
2425 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2426 EXPECT_TRUE(isIntEqualsWord(*result, -59));
2427}
2428
2429TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatBReturnsInt) {
2430 HandleScope scope(thread_);
2431 const byte bytes[] = {0xee, 0xd8};
2432 Object view(&scope, newMemoryView(bytes, "B"));
2433 Int index(&scope, runtime_->newInt(1));
2434 Object result(&scope,
2435 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2436 EXPECT_TRUE(isIntEqualsWord(*result, 216));
2437}
2438
2439TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatcReturnsBytes) {
2440 HandleScope scope(thread_);
2441 const byte bytes[] = {0x03, 0x62};
2442 Object view(&scope, newMemoryView(bytes, "c"));
2443 Int index(&scope, runtime_->newInt(1));
2444 Object result(&scope,
2445 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2446 const byte expected_bytes[] = {0x62};
2447 EXPECT_TRUE(isBytesEqualsBytes(result, expected_bytes));
2448}
2449
2450TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormathReturnsInt) {
2451 HandleScope scope(thread_);
2452 const byte bytes[] = {0xcd, 0x2c, 0x5c, 0xfc};
2453 Object view(&scope, newMemoryView(bytes, "h"));
2454 Int index(&scope, runtime_->newInt(1));
2455 Object result(&scope,
2456 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2457 EXPECT_TRUE(isIntEqualsWord(*result, -932));
2458}
2459
2460TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatHReturnsInt) {
2461 HandleScope scope(thread_);
2462 const byte bytes[] = {0xb2, 0x11, 0x94, 0xc0};
2463 Object view(&scope, newMemoryView(bytes, "H"));
2464 Int index(&scope, runtime_->newInt(1));
2465 Object result(&scope,
2466 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2467 EXPECT_TRUE(isIntEqualsWord(*result, 49300));
2468}
2469
2470TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatiReturnsInt) {
2471 HandleScope scope(thread_);
2472 const byte bytes[] = {0x30, 0x8A, 0x43, 0xF2, 0xE1, 0xD6, 0x56, 0xE4};
2473 Object view(&scope, newMemoryView(bytes, "i"));
2474 Int index(&scope, runtime_->newInt(1));
2475 Object result(&scope,
2476 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2477 EXPECT_TRUE(isIntEqualsWord(*result, -464070943));
2478}
2479
2480TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatAtiReturnsInt) {
2481 HandleScope scope(thread_);
2482 const byte bytes[] = {0x30, 0x8A, 0x43, 0xF2, 0xE1, 0xD6, 0x56, 0xE4};
2483 Object view(&scope, newMemoryView(bytes, "@i"));
2484 Int index(&scope, runtime_->newInt(1));
2485 Object result(&scope,
2486 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2487 EXPECT_TRUE(isIntEqualsWord(*result, -464070943));
2488}
2489
2490TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatIReturnsInt) {
2491 HandleScope scope(thread_);
2492 const byte bytes[] = {0x2, 0xBE, 0xA8, 0x3D, 0x74, 0x18, 0xEB, 0x8};
2493 Object view(&scope, newMemoryView(bytes, "I"));
2494 Int index(&scope, runtime_->newInt(1));
2495 Object result(&scope,
2496 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2497 EXPECT_TRUE(isIntEqualsWord(*result, 149624948));
2498}
2499
2500TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatlReturnsInt) {
2501 HandleScope scope(thread_);
2502 const byte bytes[] = {0xD8, 0x76, 0x97, 0xD1, 0x8B, 0xA1, 0xD2, 0x62,
2503 0xD9, 0xD2, 0x50, 0x47, 0xC0, 0xA8, 0xB7, 0x81};
2504 Object view(&scope, newMemoryView(bytes, "l"));
2505 Int index(&scope, runtime_->newInt(1));
2506 Object result(&scope,
2507 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2508 EXPECT_TRUE(isIntEqualsWord(*result, -9099618978295131431));
2509}
2510
2511TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatLReturnsInt) {
2512 HandleScope scope(thread_);
2513 const byte bytes[] = {0x24, 0x37, 0x8B, 0x51, 0xCB, 0xB2, 0x16, 0xFB,
2514 0xA6, 0xA9, 0x49, 0xB3, 0x59, 0x6A, 0x48, 0x62};
2515 Object view(&scope, newMemoryView(bytes, "L"));
2516 Int index(&scope, runtime_->newInt(1));
2517 Object result(&scope,
2518 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2519 EXPECT_TRUE(isIntEqualsWord(*result, 7082027347532687782));
2520}
2521
2522TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatqReturnsInt) {
2523 HandleScope scope(thread_);
2524 const byte bytes[] = {0x7, 0xE2, 0x42, 0x9E, 0x8F, 0xBF, 0xDB, 0x1B,
2525 0x8C, 0x1C, 0x34, 0x40, 0x86, 0x41, 0x2B, 0x23};
2526 Object view(&scope, newMemoryView(bytes, "q"));
2527 Int index(&scope, runtime_->newInt(1));
2528 Object result(&scope,
2529 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2530 EXPECT_TRUE(isIntEqualsWord(*result, 2534191260184616076));
2531}
2532
2533TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatQReturnsInt) {
2534 HandleScope scope(thread_);
2535 const byte bytes[] = {0xD9, 0xC6, 0xD2, 0x40, 0xBD, 0x19, 0xA9, 0xC8,
2536 0x8A, 0x1, 0x8B, 0xAF, 0x15, 0x36, 0xC7, 0xBD};
2537 Object view(&scope, newMemoryView(bytes, "Q"));
2538 Int index(&scope, runtime_->newInt(1));
2539 Object result(&scope,
2540 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2541 const uword expected_digits[] = {0xbdc73615af8b018aul, 0};
2542 EXPECT_TRUE(isIntEqualsDigits(*result, expected_digits));
2543}
2544
2545TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatnReturnsInt) {
2546 HandleScope scope(thread_);
2547 const byte bytes[] = {0xF2, 0x6F, 0xFA, 0x8B, 0x93, 0xC0, 0xED, 0x9D,
2548 0x6D, 0x7C, 0xE3, 0xDC, 0x26, 0xEF, 0xB8, 0xEB};
2549 Object view(&scope, newMemoryView(bytes, "n"));
2550 Int index(&scope, runtime_->newInt(1));
2551 Object result(&scope,
2552 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2553 EXPECT_TRUE(isIntEqualsWord(*result, -1461155128888034195l));
2554}
2555
2556TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatNReturnsInt) {
2557 HandleScope scope(thread_);
2558 const byte bytes[] = {0x6B, 0x8F, 0x6, 0xA2, 0xE0, 0x13, 0x88, 0x47,
2559 0x7E, 0xB6, 0x40, 0x7E, 0x6B, 0x2, 0x9, 0xC0};
2560 Object view(&scope, newMemoryView(bytes, "N"));
2561 Int index(&scope, runtime_->newInt(1));
2562 Object result(&scope,
2563 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2564 const uword expected_digits[] = {0xc009026b7e40b67eul, 0};
2565 EXPECT_TRUE(isIntEqualsDigits(*result, expected_digits));
2566}
2567
2568TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatfReturnsFloat) {
2569 HandleScope scope(thread_);
2570 const byte bytes[] = {0x67, 0x32, 0x23, 0x31, 0xB9, 0x70, 0xBC, 0x83};
2571 Object view(&scope, newMemoryView(bytes, "f"));
2572 Int index(&scope, runtime_->newInt(1));
2573 Object result(&scope,
2574 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2575 EXPECT_TRUE(isFloatEqualsDouble(
2576 *result, std::strtod("-0x1.78e1720000000p-120", nullptr)));
2577}
2578
2579TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewGetitemWithFormatdReturnsFloat) {
2580 HandleScope scope(thread_);
2581 const byte bytes[] = {0xEA, 0x43, 0xAD, 0x6F, 0x9D, 0x31, 0xE, 0x96,
2582 0x28, 0x80, 0x1A, 0xD, 0x87, 0xC, 0xAC, 0x4B};
2583 Object view(&scope, newMemoryView(bytes, "d"));
2584 Int index(&scope, runtime_->newInt(1));
2585 Object result(&scope,
2586 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2587 EXPECT_TRUE(isFloatEqualsDouble(
2588 *result, std::strtod("0x1.c0c870d1a8028p+187", nullptr)));
2589}
2590
2591TEST_F(UnderBuiltinsModuleTest,
2592 UnderMemoryViewGetitemWithFormatQuestionmarkReturnsTrue) {
2593 HandleScope scope(thread_);
2594 const byte bytes[] = {0x92, 0xE1, 0x57, 0xEA, 0x81, 0xA8};
2595 Object view(&scope, newMemoryView(bytes, "?"));
2596 Int index(&scope, runtime_->newInt(3));
2597 Object result(&scope,
2598 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2599 EXPECT_EQ(result, Bool::trueObj());
2600}
2601
2602TEST_F(UnderBuiltinsModuleTest,
2603 UnderMemoryViewGetitemWithFormatQuestionmarkReturnsFalse) {
2604 HandleScope scope(thread_);
2605 const byte bytes[] = {0x92, 0xE1, 0, 0xEA, 0x81, 0xA8};
2606 Object view(&scope, newMemoryView(bytes, "?"));
2607 Int index(&scope, runtime_->newInt(2));
2608 Object result(&scope,
2609 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2610 EXPECT_EQ(result, Bool::falseObj());
2611}
2612
2613TEST_F(UnderBuiltinsModuleTest,
2614 UnderMemoryViewGetitemWithNegativeIndexReturnsInt) {
2615 HandleScope scope(thread_);
2616 const byte bytes[] = {0, 1, 2, 3, 4, 5, 6, 7};
2617 Object view(&scope, newMemoryView(bytes, "h"));
2618 Int index(&scope, runtime_->newInt(-2));
2619 Object result(&scope,
2620 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2621 EXPECT_TRUE(isIntEqualsWord(*result, 0x504));
2622}
2623
2624TEST_F(UnderBuiltinsModuleTest,
2625 UnderMemoryViewGetitemWithTooBigIndexRaisesIndexError) {
2626 HandleScope scope(thread_);
2627 const byte bytes[] = {0, 1, 2, 3, 4, 5, 6, 7};
2628 Object view(&scope, newMemoryView(bytes, "I"));
2629 Int index(&scope, runtime_->newInt(2));
2630 Object result(&scope,
2631 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2632 EXPECT_TRUE(
2633 raisedWithStr(*result, LayoutId::kIndexError, "index out of bounds"));
2634}
2635
2636TEST_F(UnderBuiltinsModuleTest,
2637 UnderMemoryViewGetitemWithOverflowingIndexRaisesIndexError) {
2638 HandleScope scope(thread_);
2639 const byte bytes[] = {0, 1, 2, 3, 4, 5, 6, 7};
2640 Object view(&scope, newMemoryView(bytes, "I"));
2641 Int index(&scope, runtime_->newInt(kMaxWord / 2));
2642 Object result(&scope,
2643 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2644 EXPECT_TRUE(
2645 raisedWithStr(*result, LayoutId::kIndexError, "index out of bounds"));
2646}
2647
2648TEST_F(UnderBuiltinsModuleTest,
2649 UnderMemoryViewGetitemWithMemoryBufferReadsMemory) {
2650 HandleScope scope(thread_);
2651 const word length = 5;
2652 byte memory[length];
2653 for (word i = 0; i < length; i++) {
2654 memory[i] = i;
2655 }
2656 Object none(&scope, NoneType::object());
2657 Object view(&scope, runtime_->newMemoryViewFromCPtr(
2658 thread_, none, memory, length, ReadOnly::ReadOnly));
2659 Int idx(&scope, SmallInt::fromWord(0));
2660 EXPECT_TRUE(isIntEqualsWord(
2661 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, idx), 0));
2662 idx = Int::cast(SmallInt::fromWord(1));
2663 EXPECT_TRUE(isIntEqualsWord(
2664 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, idx), 1));
2665 idx = Int::cast(SmallInt::fromWord(2));
2666 EXPECT_TRUE(isIntEqualsWord(
2667 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, idx), 2));
2668 idx = Int::cast(SmallInt::fromWord(3));
2669 EXPECT_TRUE(isIntEqualsWord(
2670 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, idx), 3));
2671 idx = Int::cast(SmallInt::fromWord(4));
2672 EXPECT_TRUE(isIntEqualsWord(
2673 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, idx), 4));
2674}
2675
2676TEST_F(UnderBuiltinsModuleTest,
2677 UnderMemoryViewGetitemWithBytearrayReadsFromMutableBytes) {
2678 Thread* thread = Thread::current();
2679 HandleScope scope(thread);
2680 Type type(&scope, runtime_->typeAt(LayoutId::kMemoryView));
2681 Bytearray bytearray(&scope, runtime_->newBytearray());
2682 const byte byte_array[] = {0xce};
2683 runtime_->bytearrayExtend(thread, bytearray, byte_array);
2684 Object result_obj(&scope,
2685 runBuiltin(METH(memoryview, __new__), type, bytearray));
2686 ASSERT_TRUE(result_obj.isMemoryView());
2687 Object view(&scope, *result_obj);
2688 Int index(&scope, runtime_->newInt(0));
2689 Object result(&scope,
2690 runBuiltin(FUNC(_builtins, _memoryview_getitem), view, index));
2691 EXPECT_TRUE(isIntEqualsWord(*result, 0xce));
2692}
2693
2694TEST_F(UnderBuiltinsModuleTest,
2695 UnderMemoryViewItemsizeReturnsSizeOfMemoryItems) {
2696 HandleScope scope(thread_);
2697 Bytes bytes(&scope, runtime_->newBytes(5, 'x'));
2698 MemoryView view(&scope, runtime_->newMemoryView(thread_, bytes, bytes, 5,
2699 ReadOnly::ReadOnly));
2700 Object result(&scope,
2701 runBuiltin(FUNC(_builtins, _memoryview_itemsize), view));
2702 EXPECT_TRUE(isIntEqualsWord(*result, 1));
2703}
2704
2705TEST_F(UnderBuiltinsModuleTest, UnderMemoryViewNbytesReturnsSizeOfMemoryView) {
2706 HandleScope scope(thread_);
2707 Bytes bytes(&scope, runtime_->newBytes(5, 'x'));
2708 MemoryView view(&scope, runtime_->newMemoryView(thread_, bytes, bytes, 5,
2709 ReadOnly::ReadOnly));
2710 Object result(&scope, runBuiltin(FUNC(_builtins, _memoryview_nbytes), view));
2711 EXPECT_TRUE(isIntEqualsWord(*result, 5));
2712}
2713
2714TEST_F(UnderBuiltinsModuleTest, UnderModuleDirListWithFilteredOutPlaceholders) {
2715 HandleScope scope(thread_);
2716 Str module_name(&scope, runtime_->newStrFromCStr("module"));
2717 Module module(&scope, runtime_->newModule(module_name));
2718 attributeDictInit(thread_, module);
2719
2720 Object foo(&scope, Runtime::internStrFromCStr(thread_, "foo"));
2721 Object bar(&scope, Runtime::internStrFromCStr(thread_, "bar"));
2722 Object baz(&scope, Runtime::internStrFromCStr(thread_, "baz"));
2723 Str value(&scope, runtime_->newStrFromCStr("value"));
2724
2725 moduleAtPut(thread_, module, foo, value);
2726 moduleAtPut(thread_, module, bar, value);
2727 moduleAtPut(thread_, module, baz, value);
2728
2729 ValueCell::cast(moduleValueCellAt(thread_, module, bar)).makePlaceholder();
2730
2731 List keys(&scope, runBuiltin(FUNC(_builtins, _module_dir), module));
2732 EXPECT_EQ(keys.numItems(), 2);
2733 EXPECT_EQ(keys.at(0), *foo);
2734 EXPECT_EQ(keys.at(1), *baz);
2735}
2736
2737TEST_F(UnderBuiltinsModuleTest,
2738 UnderObjectTypeHasattrWithNonexistentAttrReturnsFalse) {
2739 HandleScope scope(thread_);
2740 Object obj(&scope, SmallInt::fromWord(0));
2741 Str name(&scope, runtime_->newStrFromCStr("__foo_bar_baz__"));
2742 Object result(&scope,
2743 runBuiltin(FUNC(_builtins, _object_type_hasattr), obj, name));
2744 EXPECT_EQ(result, Bool::falseObj());
2745 EXPECT_FALSE(thread_->hasPendingException());
2746}
2747
2748TEST_F(UnderBuiltinsModuleTest,
2749 UnderObjectTypeHasattrWithInstanceAttrReturnsFalse) {
2750 HandleScope scope(thread_);
2751 ASSERT_FALSE(runFromCStr(runtime_, R"(
2752class C:
2753 def __init__(self):
2754 self.foobarbaz = 5
2755obj = C()
2756)")
2757 .isError());
2758 Object obj(&scope, mainModuleAt(runtime_, "obj"));
2759 Str name(&scope, runtime_->newStrFromCStr("foobarbaz"));
2760 Object result(&scope,
2761 runBuiltin(FUNC(_builtins, _object_type_hasattr), obj, name));
2762 EXPECT_EQ(result, Bool::falseObj());
2763 EXPECT_FALSE(thread_->hasPendingException());
2764}
2765
2766TEST_F(UnderBuiltinsModuleTest,
2767 UnderObjectTypeHasattrWithExistentAttrReturnsTrue) {
2768 HandleScope scope(thread_);
2769 ASSERT_FALSE(runFromCStr(runtime_, R"(
2770class C:
2771 foobarbaz = 5
2772obj = C()
2773)")
2774 .isError());
2775 Object obj(&scope, mainModuleAt(runtime_, "obj"));
2776 Str name(&scope, runtime_->newStrFromCStr("foobarbaz"));
2777 Object result(&scope,
2778 runBuiltin(FUNC(_builtins, _object_type_hasattr), obj, name));
2779 EXPECT_EQ(result, Bool::trueObj());
2780 EXPECT_FALSE(thread_->hasPendingException());
2781}
2782
2783TEST_F(UnderBuiltinsModuleTest,
2784 UnderObjectTypeHasattrWithRaisingDescriptorDoesNotRaise) {
2785 HandleScope scope(thread_);
2786 ASSERT_FALSE(runFromCStr(runtime_, R"(
2787class Desc:
2788 def __get__(self, obj, type):
2789 raise UserWarning("foo")
2790class C:
2791 foobarbaz = Desc()
2792obj = C()
2793)")
2794 .isError());
2795 Object obj(&scope, mainModuleAt(runtime_, "obj"));
2796 Str name(&scope, runtime_->newStrFromCStr("foobarbaz"));
2797 Object result(&scope,
2798 runBuiltin(FUNC(_builtins, _object_type_hasattr), obj, name));
2799 EXPECT_EQ(result, Bool::trueObj());
2800 EXPECT_FALSE(thread_->hasPendingException());
2801}
2802
2803TEST_F(UnderBuiltinsModuleTest, UnderOsWriteWithBadFdRaisesOSError) {
2804 HandleScope scope(thread_);
2805 Int fd(&scope, SmallInt::fromWord(-1));
2806 const byte buf[] = {0x1, 0x2};
2807 Bytes bytes_buf(&scope, runtime_->newBytesWithAll(buf));
2808 EXPECT_TRUE(raised(runBuiltin(FUNC(_builtins, _os_write), fd, bytes_buf),
2809 LayoutId::kOSError));
2810}
2811
2812TEST_F(UnderBuiltinsModuleTest,
2813 UnderOsWriteWithFdNotOpenedForWritingRaisesOSError) {
2814 HandleScope scope(thread_);
2815 int fds[2];
2816 int result = ::pipe(fds);
2817 ASSERT_EQ(result, 0);
2818 Int fd(&scope, SmallInt::fromWord(fds[0]));
2819 const byte buf[] = {0x1, 0x2};
2820 Bytes bytes_buf(&scope, runtime_->newBytesWithAll(buf));
2821 EXPECT_TRUE(raised(runBuiltin(FUNC(_builtins, _os_write), fd, bytes_buf),
2822 LayoutId::kOSError));
2823 ::close(fds[0]);
2824 ::close(fds[1]);
2825}
2826
2827TEST_F(UnderBuiltinsModuleTest, UnderOsWriteWritesSizeBytes) {
2828 HandleScope scope(thread_);
2829 int fds[2];
2830 int result = ::pipe(fds);
2831 ASSERT_EQ(result, 0);
2832 Int fd(&scope, SmallInt::fromWord(fds[1]));
2833 byte to_write[] = "hello";
2834 word count = std::strlen(reinterpret_cast<char*>(to_write));
2835 Bytes bytes_buf(&scope,
2836 runtime_->newBytesWithAll(View<byte>(to_write, count)));
2837 Object result_obj(&scope,
2838 runBuiltin(FUNC(_builtins, _os_write), fd, bytes_buf));
2839 EXPECT_TRUE(isIntEqualsWord(*result_obj, count));
2840 ::close(fds[1]); // Send EOF
2841 std::unique_ptr<char[]> buf(new char[count + 1]{0});
2842 result = ::read(fds[0], buf.get(), count);
2843 EXPECT_EQ(result, count);
2844 EXPECT_STREQ(buf.get(), reinterpret_cast<char*>(to_write));
2845 ::close(fds[0]);
2846}
2847
2848TEST_F(UnderBuiltinsModuleTest, UnderOsWriteWritesSizeMemoryView) {
2849 HandleScope scope(thread_);
2850 int fds[2];
2851 int result = ::pipe(fds);
2852 ASSERT_EQ(result, 0);
2853 Int fd(&scope, SmallInt::fromWord(fds[1]));
2854 const byte bytes[] = "hello_there";
2855 MemoryView memoryview(&scope, newMemoryView(bytes, "b"));
2856 MemoryView memoryview_slice(
2857 &scope, memoryviewGetslice(thread_, memoryview, /*start=*/0, /*stop=*/5,
2858 /*step=*/1));
2859 Object result_obj(
2860 &scope, runBuiltin(FUNC(_builtins, _os_write), fd, memoryview_slice));
2861 EXPECT_TRUE(isIntEqualsWord(*result_obj, 5));
2862 ::close(fds[1]); // Send EOF
2863 std::unique_ptr<char[]> buf(new char[6]{0});
2864 result = ::read(fds[0], buf.get(), 5);
2865 EXPECT_EQ(result, 5);
2866 EXPECT_STREQ(buf.get(), "hello");
2867 ::close(fds[0]);
2868}
2869
2870TEST_F(UnderBuiltinsModuleTest,
2871 UnderStrCompareDigestWithNonASCIIRaisesTypeError) {
2872 HandleScope scope(thread_);
2873 Str left(&scope, runtime_->newStrFromCStr("foo\u00E4"));
2874 Str right(&scope, runtime_->newStrFromCStr("foo\u00E4"));
2875 EXPECT_TRUE(raisedWithStr(
2876 runBuiltin(FUNC(_builtins, _str_compare_digest), left, right),
2877 LayoutId::kTypeError,
2878 "comparing strings with non-ASCII characters is not supported"));
2879}
2880
2881TEST_F(UnderBuiltinsModuleTest,
2882 UnderStrCountWithStartAndEndSearchesWithinBounds) {
2883 HandleScope scope(thread_);
2884 Str haystack(&scope, runtime_->newStrFromCStr("ofoodo"));
2885 Str needle(&scope, runtime_->newStrFromCStr("o"));
2886 Object start(&scope, SmallInt::fromWord(2));
2887 Object end(&scope, SmallInt::fromWord(4));
2888 EXPECT_TRUE(isIntEqualsWord(
2889 runBuiltin(FUNC(_builtins, _str_count), haystack, needle, start, end),
2890 2));
2891}
2892
2893TEST_F(UnderBuiltinsModuleTest, UnderStrCountWithNoneStartStartsFromZero) {
2894 HandleScope scope(thread_);
2895 Str haystack(&scope, runtime_->newStrFromCStr("foo"));
2896 Str needle(&scope, runtime_->newStrFromCStr("o"));
2897 Object start(&scope, NoneType::object());
2898 Object end(&scope, SmallInt::fromWord(haystack.codePointLength()));
2899 EXPECT_TRUE(isIntEqualsWord(
2900 runBuiltin(FUNC(_builtins, _str_count), haystack, needle, start, end),
2901 2));
2902}
2903
2904TEST_F(UnderBuiltinsModuleTest,
2905 UnderStrCountWithNoneEndSetsEndToHaystackLength) {
2906 HandleScope scope(thread_);
2907 Str haystack(&scope, runtime_->newStrFromCStr("foo"));
2908 Str needle(&scope, runtime_->newStrFromCStr("o"));
2909 Object start(&scope, SmallInt::fromWord(0));
2910 Object end(&scope, NoneType::object());
2911 EXPECT_TRUE(isIntEqualsWord(
2912 runBuiltin(FUNC(_builtins, _str_count), haystack, needle, start, end),
2913 2));
2914}
2915
2916TEST_F(UnderBuiltinsModuleTest,
2917 UnderStrFromStrWithStrTypeReturnsValueOfStrType) {
2918 ASSERT_FALSE(runFromCStr(runtime_, R"(
2919result = _str_from_str(str, 'value')
2920)")
2921 .isError());
2922 HandleScope scope(thread_);
2923 Object result(&scope, mainModuleAt(runtime_, "result"));
2924 ASSERT_TRUE(runtime_->isInstanceOfStr(*result));
2925 EXPECT_TRUE(result.isStr());
2926}
2927
2928TEST_F(UnderBuiltinsModuleTest,
2929 UnderStrFromStrWithSubClassTypeReturnsValueOfSubClassType) {
2930 ASSERT_FALSE(runFromCStr(runtime_, R"(
2931class Sub(str): pass
2932result = _str_from_str(Sub, 'value')
2933)")
2934 .isError());
2935 HandleScope scope(thread_);
2936 Object result(&scope, mainModuleAt(runtime_, "result"));
2937 Object sub(&scope, mainModuleAt(runtime_, "Sub"));
2938 EXPECT_EQ(runtime_->typeOf(*result), sub);
2939 EXPECT_TRUE(isStrEqualsCStr(*result, "value"));
2940}
2941
2942TEST_F(UnderBuiltinsModuleTest,
2943 UnderStrCountWithStrNeedleSubClassTypeReturnsSubstr) {
2944 ASSERT_FALSE(runFromCStr(runtime_, R"(
2945class Sub(str): pass
2946result = Sub("value u")
2947count = result.count('u')
2948)")
2949 .isError());
2950 HandleScope scope(thread_);
2951 Object count(&scope, mainModuleAt(runtime_, "count"));
2952 EXPECT_TRUE(isIntEqualsWord(*count, 2));
2953}
2954
2955TEST_F(UnderBuiltinsModuleTest,
2956 UnderStrCountWithSubNeedleSubClassTypeReturnsSubstr) {
2957 ASSERT_FALSE(runFromCStr(runtime_, R"(
2958class Sub(str): pass
2959result = Sub("value")
2960count = result.count(result)
2961)")
2962 .isError());
2963 HandleScope scope(thread_);
2964 Object count(&scope, mainModuleAt(runtime_, "count"));
2965 EXPECT_TRUE(isIntEqualsWord(*count, 1));
2966}
2967
2968TEST_F(UnderBuiltinsModuleTest, UnderStrGetitemWithSubClassTypeReturnsSubstr) {
2969 ASSERT_FALSE(runFromCStr(runtime_, R"(
2970class Sub(str): pass
2971result = Sub("value")
2972result = result[:2]
2973)")
2974 .isError());
2975 HandleScope scope(thread_);
2976 Object result(&scope, mainModuleAt(runtime_, "result"));
2977 EXPECT_TRUE(isStrEqualsCStr(*result, "va"));
2978}
2979
2980TEST_F(UnderBuiltinsModuleTest, UnderStrArrayClearSetsNumItemsToZero) {
2981 HandleScope scope(thread_);
2982 StrArray self(&scope, runtime_->newStrArray());
2983 Str other(&scope, runtime_->newStrFromCStr("hello"));
2984 runtime_->strArrayAddStr(thread_, self, other);
2985 ASSERT_EQ(self.numItems(), 5);
2986 EXPECT_TRUE(runBuiltin(FUNC(_builtins, _str_array_clear), self).isNoneType());
2987 EXPECT_EQ(self.numItems(), 0);
2988
2989 // Make sure that str does not show up again
2990 other = runtime_->newStrFromCStr("abcd");
2991 runtime_->strArrayAddStr(thread_, self, other);
2992 EXPECT_TRUE(isStrEqualsCStr(runtime_->strFromStrArray(self), "abcd"));
2993}
2994
2995TEST_F(UnderBuiltinsModuleTest, UnderStrArrayIaddWithStrReturnsStrArray) {
2996 HandleScope scope(thread_);
2997 StrArray self(&scope, runtime_->newStrArray());
2998 const char* test_str = "hello";
2999 Str other(&scope, runtime_->newStrFromCStr(test_str));
3000 StrArray result(&scope,
3001 runBuiltin(FUNC(_builtins, _str_array_iadd), self, other));
3002 EXPECT_TRUE(isStrEqualsCStr(runtime_->strFromStrArray(result), test_str));
3003 EXPECT_EQ(self, result);
3004}
3005
3006TEST_F(UnderBuiltinsModuleTest, UnderStrJoinWithNonStrRaisesTypeError) {
3007 HandleScope scope(thread_);
3008 Str sep(&scope, runtime_->newStrFromCStr(","));
3009 Object obj1(&scope, runtime_->newStrFromCStr("foo"));
3010 Object obj2(&scope, runtime_->newInt(4));
3011 Object obj3(&scope, runtime_->newStrFromCStr("bar"));
3012 Tuple elts(&scope, runtime_->newTupleWith3(obj1, obj2, obj3));
3013 EXPECT_TRUE(raisedWithStr(
3014 runBuiltin(FUNC(_builtins, _str_join), sep, elts), LayoutId::kTypeError,
3015 "sequence item 1: expected str instance, int found"));
3016}
3017
3018TEST_F(UnderBuiltinsModuleTest, PartitionOnSingleCharStr) {
3019 HandleScope scope(thread_);
3020 Str str(&scope, runtime_->newStrFromCStr("hello"));
3021 Str sep(&scope, runtime_->newStrFromCStr("l"));
3022 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_partition), str, sep));
3023 ASSERT_EQ(result.length(), 3);
3024 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "he"));
3025 EXPECT_TRUE(isStrEqualsCStr(result.at(1), "l"));
3026 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "lo"));
3027}
3028
3029TEST_F(UnderBuiltinsModuleTest, PartitionOnMultiCharStr) {
3030 HandleScope scope(thread_);
3031 Str str(&scope, runtime_->newStrFromCStr("hello"));
3032 Str sep(&scope, runtime_->newStrFromCStr("ll"));
3033 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_partition), str, sep));
3034 ASSERT_EQ(result.length(), 3);
3035 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "he"));
3036 EXPECT_TRUE(isStrEqualsCStr(result.at(1), "ll"));
3037 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "o"));
3038}
3039
3040TEST_F(UnderBuiltinsModuleTest, PartitionOnExistingSuffix) {
3041 HandleScope scope(thread_);
3042 Str str(&scope, runtime_->newStrFromCStr("hello"));
3043 Str sep(&scope, runtime_->newStrFromCStr("lo"));
3044 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_partition), str, sep));
3045 ASSERT_EQ(result.length(), 3);
3046 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hel"));
3047 EXPECT_TRUE(isStrEqualsCStr(result.at(1), "lo"));
3048 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
3049}
3050
3051TEST_F(UnderBuiltinsModuleTest, PartitionOnNonExistentSuffix) {
3052 HandleScope scope(thread_);
3053 Str str(&scope, runtime_->newStrFromCStr("hello"));
3054 Str sep(&scope, runtime_->newStrFromCStr("lop"));
3055 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_partition), str, sep));
3056 ASSERT_EQ(result.length(), 3);
3057 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hello"));
3058 EXPECT_TRUE(isStrEqualsCStr(result.at(1), ""));
3059 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
3060}
3061
3062TEST_F(UnderBuiltinsModuleTest, PartitionOnExistingPrefix) {
3063 HandleScope scope(thread_);
3064 Str str(&scope, runtime_->newStrFromCStr("hello"));
3065 Str sep(&scope, runtime_->newStrFromCStr("he"));
3066 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_partition), str, sep));
3067 ASSERT_EQ(result.length(), 3);
3068 EXPECT_TRUE(isStrEqualsCStr(result.at(0), ""));
3069 EXPECT_TRUE(isStrEqualsCStr(result.at(1), "he"));
3070 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "llo"));
3071}
3072
3073TEST_F(UnderBuiltinsModuleTest, PartitionOnNonExistentPrefix) {
3074 HandleScope scope(thread_);
3075 Str str(&scope, runtime_->newStrFromCStr("hello"));
3076 Str sep(&scope, runtime_->newStrFromCStr("hex"));
3077 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_partition), str, sep));
3078 ASSERT_EQ(result.length(), 3);
3079 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hello"));
3080 EXPECT_TRUE(isStrEqualsCStr(result.at(1), ""));
3081 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
3082}
3083
3084TEST_F(UnderBuiltinsModuleTest, PartitionLargerStr) {
3085 HandleScope scope(thread_);
3086 Str str(&scope, runtime_->newStrFromCStr("hello"));
3087 Str sep(&scope, runtime_->newStrFromCStr("abcdefghijk"));
3088 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_partition), str, sep));
3089 ASSERT_EQ(result.length(), 3);
3090 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hello"));
3091 EXPECT_TRUE(isStrEqualsCStr(result.at(1), ""));
3092 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
3093}
3094
3095TEST_F(UnderBuiltinsModuleTest, PartitionEmptyStr) {
3096 HandleScope scope(thread_);
3097 Str str(&scope, Str::empty());
3098 Str sep(&scope, runtime_->newStrFromCStr("a"));
3099 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_partition), str, sep));
3100 ASSERT_EQ(result.length(), 3);
3101 EXPECT_TRUE(isStrEqualsCStr(result.at(0), ""));
3102 EXPECT_TRUE(isStrEqualsCStr(result.at(1), ""));
3103 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
3104}
3105
3106TEST_F(UnderBuiltinsModuleTest, RpartitionOnSingleCharStrPartitionsCorrectly) {
3107 HandleScope scope(thread_);
3108 Str str(&scope, runtime_->newStrFromCStr("hello"));
3109 Str sep(&scope, runtime_->newStrFromCStr("l"));
3110 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_rpartition), str, sep));
3111 ASSERT_EQ(result.length(), 3);
3112 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hel"));
3113 EXPECT_TRUE(isStrEqualsCStr(result.at(1), "l"));
3114 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "o"));
3115}
3116
3117TEST_F(UnderBuiltinsModuleTest, RpartitionOnMultiCharStrPartitionsCorrectly) {
3118 HandleScope scope(thread_);
3119 Str str(&scope, runtime_->newStrFromCStr("hello"));
3120 Str sep(&scope, runtime_->newStrFromCStr("ll"));
3121 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_rpartition), str, sep));
3122 ASSERT_EQ(result.length(), 3);
3123 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "he"));
3124 EXPECT_TRUE(isStrEqualsCStr(result.at(1), "ll"));
3125 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "o"));
3126}
3127
3128TEST_F(UnderBuiltinsModuleTest, RpartitionOnSuffixPutsEmptyStrAtEndOfResult) {
3129 HandleScope scope(thread_);
3130 Str str(&scope, runtime_->newStrFromCStr("hello"));
3131 Str sep(&scope, runtime_->newStrFromCStr("lo"));
3132 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_rpartition), str, sep));
3133 ASSERT_EQ(result.length(), 3);
3134 EXPECT_TRUE(isStrEqualsCStr(result.at(0), "hel"));
3135 EXPECT_TRUE(isStrEqualsCStr(result.at(1), "lo"));
3136 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
3137}
3138
3139TEST_F(UnderBuiltinsModuleTest,
3140 RpartitionOnNonExistentSuffixPutsStrAtEndOfResult) {
3141 HandleScope scope(thread_);
3142 Str str(&scope, runtime_->newStrFromCStr("hello"));
3143 Str sep(&scope, runtime_->newStrFromCStr("lop"));
3144 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_rpartition), str, sep));
3145 ASSERT_EQ(result.length(), 3);
3146 EXPECT_TRUE(isStrEqualsCStr(result.at(0), ""));
3147 EXPECT_TRUE(isStrEqualsCStr(result.at(1), ""));
3148 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "hello"));
3149}
3150
3151TEST_F(UnderBuiltinsModuleTest,
3152 RpartitionOnPrefixPutsEmptyStrAtBeginningOfResult) {
3153 HandleScope scope(thread_);
3154 Str str(&scope, runtime_->newStrFromCStr("hello"));
3155 Str sep(&scope, runtime_->newStrFromCStr("he"));
3156 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_rpartition), str, sep));
3157 ASSERT_EQ(result.length(), 3);
3158 EXPECT_TRUE(isStrEqualsCStr(result.at(0), ""));
3159 EXPECT_TRUE(isStrEqualsCStr(result.at(1), "he"));
3160 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "llo"));
3161}
3162
3163TEST_F(UnderBuiltinsModuleTest,
3164 RpartitionOnNonExistentPrefixPutsStrAtEndOfResult) {
3165 HandleScope scope(thread_);
3166 Str str(&scope, runtime_->newStrFromCStr("hello"));
3167 Str sep(&scope, runtime_->newStrFromCStr("hex"));
3168 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_rpartition), str, sep));
3169 ASSERT_EQ(result.length(), 3);
3170 EXPECT_TRUE(isStrEqualsCStr(result.at(0), ""));
3171 EXPECT_TRUE(isStrEqualsCStr(result.at(1), ""));
3172 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "hello"));
3173}
3174
3175TEST_F(UnderBuiltinsModuleTest, RpartitionLargerStrPutsStrAtEndOfResult) {
3176 HandleScope scope(thread_);
3177 Str str(&scope, runtime_->newStrFromCStr("hello"));
3178 Str sep(&scope, runtime_->newStrFromCStr("foobarbaz"));
3179 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_rpartition), str, sep));
3180 ASSERT_EQ(result.length(), 3);
3181 EXPECT_TRUE(isStrEqualsCStr(result.at(0), ""));
3182 EXPECT_TRUE(isStrEqualsCStr(result.at(1), ""));
3183 EXPECT_TRUE(isStrEqualsCStr(result.at(2), "hello"));
3184}
3185
3186TEST_F(UnderBuiltinsModuleTest, RpartitionEmptyStrReturnsTupleOfEmptyStrings) {
3187 HandleScope scope(thread_);
3188 Str str(&scope, Str::empty());
3189 Str sep(&scope, runtime_->newStrFromCStr("a"));
3190 Tuple result(&scope, runBuiltin(FUNC(_builtins, _str_rpartition), str, sep));
3191 ASSERT_EQ(result.length(), 3);
3192 EXPECT_TRUE(isStrEqualsCStr(result.at(0), ""));
3193 EXPECT_TRUE(isStrEqualsCStr(result.at(1), ""));
3194 EXPECT_TRUE(isStrEqualsCStr(result.at(2), ""));
3195}
3196
3197TEST_F(UnderBuiltinsModuleTest,
3198 UnderStrSplitWithStrEqualsSepReturnsTwoEmptyStrings) {
3199 HandleScope scope(thread_);
3200 Str str(&scope, runtime_->newStrFromCStr("haystack"));
3201 Str sep(&scope, runtime_->newStrFromCStr("haystack"));
3202 Int maxsplit(&scope, SmallInt::fromWord(100));
3203 List result(&scope,
3204 runBuiltin(FUNC(_builtins, _str_split), str, sep, maxsplit));
3205 EXPECT_PYLIST_EQ(result, {"", ""});
3206}
3207
3208TEST_F(UnderBuiltinsModuleTest, UnderStrSplitWithSepNotInStrReturnsListOfStr) {
3209 HandleScope scope(thread_);
3210 Str str(&scope, runtime_->newStrFromCStr("haystack"));
3211 Str sep(&scope, runtime_->newStrFromCStr("foobar"));
3212 Int maxsplit(&scope, SmallInt::fromWord(100));
3213 List result(&scope,
3214 runBuiltin(FUNC(_builtins, _str_split), str, sep, maxsplit));
3215 ASSERT_EQ(result.numItems(), 1);
3216 EXPECT_EQ(result.at(0), *str);
3217}
3218
3219TEST_F(UnderBuiltinsModuleTest, UnderStrSplitWithSepInUnderStrSplitsOnSep) {
3220 HandleScope scope(thread_);
3221 Str str(&scope, runtime_->newStrFromCStr("hello world hello world"));
3222 Str sep(&scope, runtime_->newStrFromCStr(" w"));
3223 Int maxsplit(&scope, SmallInt::fromWord(100));
3224 List result(&scope,
3225 runBuiltin(FUNC(_builtins, _str_split), str, sep, maxsplit));
3226 EXPECT_PYLIST_EQ(result, {"hello", "orld hello", "orld"});
3227}
3228
3229TEST_F(UnderBuiltinsModuleTest,
3230 UnderStrSplitWithSepInUnderStrSplitsOnSepMaxsplit) {
3231 HandleScope scope(thread_);
3232 Str str(&scope, runtime_->newStrFromCStr("a b c d e"));
3233 Str sep(&scope, runtime_->newStrFromCStr(" "));
3234 Int maxsplit(&scope, SmallInt::fromWord(2));
3235 List result(&scope,
3236 runBuiltin(FUNC(_builtins, _str_split), str, sep, maxsplit));
3237 EXPECT_PYLIST_EQ(result, {"a", "b", "c d e"});
3238}
3239
3240TEST_F(UnderBuiltinsModuleTest,
3241 UnderStrSplitWithSepInUnderStrSplitsOnSepMaxsplitZero) {
3242 HandleScope scope(thread_);
3243 Str str(&scope, runtime_->newStrFromCStr("a b c d e"));
3244 Str sep(&scope, runtime_->newStrFromCStr(" "));
3245 Int maxsplit(&scope, SmallInt::fromWord(0));
3246 List result(&scope,
3247 runBuiltin(FUNC(_builtins, _str_split), str, sep, maxsplit));
3248 EXPECT_PYLIST_EQ(result, {"a b c d e"});
3249}
3250
3251TEST_F(UnderBuiltinsModuleTest,
3252 UnderStrSplitWhitespaceSplitsOnUnicodeWhitespace) {
3253 HandleScope scope(thread_);
3254 Str str(&scope, runtime_->newStrFromCStr(u8"a \u3000 \t b\u205fc"));
3255 Object sep(&scope, NoneType::object());
3256 Int maxsplit(&scope, SmallInt::fromWord(100));
3257 List result(&scope,
3258 runBuiltin(FUNC(_builtins, _str_split), str, sep, maxsplit));
3259 EXPECT_PYLIST_EQ(result, {"a", "b", "c"});
3260}
3261
3262TEST_F(UnderBuiltinsModuleTest,
3263 UnderStrSplitWhitespaceSplitsOnWhitespaceAtEnd) {
3264 HandleScope scope(thread_);
3265 Str str(&scope, runtime_->newStrFromCStr("a \t b c "));
3266 Object sep(&scope, NoneType::object());
3267 Int maxsplit(&scope, SmallInt::fromWord(100));
3268 List result(&scope,
3269 runBuiltin(FUNC(_builtins, _str_split), str, sep, maxsplit));
3270 EXPECT_PYLIST_EQ(result, {"a", "b", "c"});
3271}
3272
3273TEST_F(UnderBuiltinsModuleTest, UnderTupleCheckExactWithExactTupleReturnsTrue) {
3274 HandleScope scope(thread_);
3275 Object obj(&scope, runtime_->emptyTuple());
3276 EXPECT_EQ(runBuiltin(FUNC(_builtins, _tuple_check_exact), obj),
3277 Bool::trueObj());
3278}
3279
3280TEST_F(UnderBuiltinsModuleTest,
3281 UnderTupleCheckExactWithTupleSubclassReturnsFalse) {
3282 ASSERT_FALSE(runFromCStr(runtime_, R"(
3283class C(tuple):
3284 pass
3285obj = C()
3286)")
3287 .isError());
3288 HandleScope scope(thread_);
3289 Object obj(&scope, mainModuleAt(runtime_, "obj"));
3290 EXPECT_EQ(runBuiltin(FUNC(_builtins, _tuple_check_exact), obj),
3291 Bool::falseObj());
3292}
3293
3294TEST_F(UnderBuiltinsModuleDeathTest, UnderUnimplementedAbortsProgram) {
3295 ASSERT_DEATH(static_cast<void>(runFromCStr(runtime_, "_unimplemented()")),
3296 ".*'_unimplemented' called.");
3297}
3298
3299TEST_F(UnderBuiltinsModuleDeathTest, UnderUnimplementedPrintsFunctionName) {
3300 ASSERT_DEATH(static_cast<void>(runFromCStr(runtime_, R"(
3301def foobar():
3302 _unimplemented()
3303foobar()
3304)")),
3305 ".*'_unimplemented' called in function 'foobar'.");
3306}
3307
3308} // namespace testing
3309} // namespace py