this repo has no description
at trunk 4337 lines 136 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include <climits> 3#include <cstring> 4 5#include "Python.h" 6#include "gtest/gtest.h" 7 8#include "capi-fixture.h" 9#include "capi-testing.h" 10 11namespace py { 12namespace testing { 13 14using AbstractExtensionApiTest = ExtensionApi; 15 16// Buffer Protocol 17 18TEST_F(AbstractExtensionApiTest, PyBufferFillInfoSimpleFillsInfo) { 19 Py_buffer buffer; 20 char buf[13]; 21 PyObjectPtr pyobj(PyTuple_New(1)); 22 long prev_refcount = Py_REFCNT(pyobj); 23 int readonly = 1; 24 int result = PyBuffer_FillInfo(&buffer, pyobj, buf, sizeof(buf), readonly, 25 PyBUF_SIMPLE); 26 EXPECT_EQ(result, 0); 27 EXPECT_EQ(Py_REFCNT(pyobj), prev_refcount + 1); 28 EXPECT_EQ(buffer.obj, pyobj); 29 EXPECT_EQ(buffer.buf, buf); 30 EXPECT_EQ(buffer.len, (Py_ssize_t)sizeof(buf)); 31 EXPECT_EQ(buffer.readonly, 1); 32 EXPECT_EQ(buffer.itemsize, 1); 33 EXPECT_EQ(buffer.format, nullptr); 34 EXPECT_EQ(buffer.ndim, 1); 35 EXPECT_EQ(buffer.shape, nullptr); 36 EXPECT_EQ(buffer.strides, nullptr); 37 EXPECT_EQ(buffer.suboffsets, nullptr); 38 EXPECT_EQ(buffer.internal, nullptr); 39} 40 41TEST_F(AbstractExtensionApiTest, 42 PyBufferFillInfoWithWritableFormatNdStridesFillsInfo) { 43 Py_buffer buffer; 44 char buf[7]; 45 PyObjectPtr pyobj(PyTuple_New(1)); 46 long prev_refcount = Py_REFCNT(pyobj); 47 int readonly = 0; 48 int result = PyBuffer_FillInfo( 49 &buffer, pyobj, buf, sizeof(buf), readonly, 50 PyBUF_WRITABLE | PyBUF_FORMAT | PyBUF_ND | PyBUF_STRIDES); 51 EXPECT_EQ(result, 0); 52 EXPECT_EQ(Py_REFCNT(pyobj), prev_refcount + 1); 53 EXPECT_EQ(buffer.obj, pyobj); 54 EXPECT_EQ(buffer.buf, buf); 55 EXPECT_EQ(buffer.len, (Py_ssize_t)sizeof(buf)); 56 EXPECT_EQ(buffer.readonly, 0); 57 EXPECT_EQ(buffer.itemsize, 1); 58 EXPECT_EQ(strcmp(buffer.format, "B"), 0); 59 EXPECT_EQ(buffer.ndim, 1); 60 EXPECT_EQ(buffer.shape, &buffer.len); 61 EXPECT_EQ(buffer.strides, &buffer.itemsize); 62 EXPECT_EQ(buffer.suboffsets, nullptr); 63 EXPECT_EQ(buffer.internal, nullptr); 64} 65 66TEST_F(AbstractExtensionApiTest, PyBufferFillInfoWithNullptrRaisesBufferError) { 67 int result = PyBuffer_FillInfo(nullptr, Py_None, nullptr, 0, 1, PyBUF_SIMPLE); 68 EXPECT_EQ(result, -1); 69 ASSERT_NE(PyErr_Occurred(), nullptr); 70 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_BufferError)); 71} 72 73TEST_F(AbstractExtensionApiTest, 74 PyBufferFillInfoWithWritableFlagAndReadonlyRaisesBufferError) { 75 Py_buffer buffer; 76 int result = 77 PyBuffer_FillInfo(&buffer, Py_None, nullptr, 0, 1, PyBUF_WRITABLE); 78 EXPECT_EQ(result, -1); 79 ASSERT_NE(PyErr_Occurred(), nullptr); 80 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_BufferError)); 81} 82 83TEST_F(AbstractExtensionApiTest, 84 PyBufferIsContiguousWithInvalidOrderReturnsFalse) { 85 Py_buffer buffer; 86 char data[1]; 87 ASSERT_EQ(PyBuffer_FillInfo(&buffer, Py_None, data, /*len=*/1, 88 /*readonly=*/1, PyBUF_SIMPLE), 89 0); 90 EXPECT_FALSE(PyBuffer_IsContiguous(&buffer, '%')); 91} 92 93TEST_F(AbstractExtensionApiTest, 94 PyBufferIsContiguousWithSubOffsetsReturnsFalse) { 95 Py_buffer buffer; 96 char data[1]; 97 ASSERT_EQ(PyBuffer_FillInfo(&buffer, Py_None, data, /*len=*/1, 98 /*readonly=*/1, PyBUF_SIMPLE), 99 0); 100 static Py_ssize_t suboffsets[] = {13}; 101 buffer.suboffsets = suboffsets; 102 EXPECT_FALSE(PyBuffer_IsContiguous(&buffer, 'C')); 103 EXPECT_FALSE(PyBuffer_IsContiguous(&buffer, 'F')); 104 EXPECT_FALSE(PyBuffer_IsContiguous(&buffer, 'A')); 105} 106 107TEST_F(AbstractExtensionApiTest, PyBufferIsContiguousReturnsTrue) { 108 Py_buffer buffer; 109 char data[1]; 110 ASSERT_EQ(PyBuffer_FillInfo(&buffer, Py_None, data, /*len=*/1, 111 /*readonly=*/1, PyBUF_SIMPLE), 112 0); 113 EXPECT_TRUE(PyBuffer_IsContiguous(&buffer, 'C')); 114 EXPECT_TRUE(PyBuffer_IsContiguous(&buffer, 'F')); 115 EXPECT_TRUE(PyBuffer_IsContiguous(&buffer, 'A')); 116} 117 118TEST_F(AbstractExtensionApiTest, PyBufferIsContiguousWithRowMajorBuffer) { 119 Py_buffer buffer; 120 char data[300]; 121 ASSERT_EQ(PyBuffer_FillInfo(&buffer, Py_None, data, /*len=*/100, 122 /*readonly=*/1, PyBUF_STRIDES), 123 0); 124 buffer.itemsize = 2; 125 buffer.format = const_cast<char*>("h"); 126 buffer.ndim = 3; 127 Py_ssize_t shape[3] = {10, 3, 5}; 128 buffer.shape = shape; 129 Py_ssize_t strides[3] = {30, 10, 2}; 130 buffer.strides = strides; 131 EXPECT_TRUE(PyBuffer_IsContiguous(&buffer, 'C')); 132 EXPECT_FALSE(PyBuffer_IsContiguous(&buffer, 'F')); 133 EXPECT_TRUE(PyBuffer_IsContiguous(&buffer, 'A')); 134} 135 136TEST_F(AbstractExtensionApiTest, PyBufferIsContiguousWithColumnMajorBuffer) { 137 Py_buffer buffer; 138 char data[420]; 139 ASSERT_EQ(PyBuffer_FillInfo(&buffer, Py_None, data, /*len=*/100, 140 /*readonly=*/1, PyBUF_STRIDES), 141 0); 142 buffer.itemsize = 4; 143 buffer.format = const_cast<char*>("L"); 144 buffer.ndim = 3; 145 Py_ssize_t shape[3] = {7, 3, 5}; 146 buffer.shape = shape; 147 Py_ssize_t strides[3] = {4, 28, 84}; 148 buffer.strides = strides; 149 EXPECT_FALSE(PyBuffer_IsContiguous(&buffer, 'C')); 150 EXPECT_TRUE(PyBuffer_IsContiguous(&buffer, 'F')); 151 EXPECT_TRUE(PyBuffer_IsContiguous(&buffer, 'A')); 152} 153 154TEST_F(AbstractExtensionApiTest, PyEvalCallFunctionCalls) { 155 PyRun_SimpleString(R"( 156def func(*args): 157 return f"{args!r}" 158)"); 159 PyObjectPtr func(mainModuleGet("func")); 160 PyObjectPtr result(PyEval_CallFunction(func, "(iI)s#i", 3, 7, "aaaa", 3, 99)); 161 EXPECT_TRUE(isUnicodeEqualsCStr(result, "((3, 7), 'aaa', 99)")); 162} 163 164TEST_F(AbstractExtensionApiTest, PyEvalCallMethodCalls) { 165 PyRun_SimpleString(R"( 166class C: 167 x = 42 168 def func(self, *args): 169 return f"{self.x}{args!r}" 170c = C() 171)"); 172 PyObjectPtr c(mainModuleGet("c")); 173 PyObjectPtr result(PyEval_CallMethod(c, "func", "s#(i)", "ccc", 1, 7)); 174 EXPECT_TRUE(isUnicodeEqualsCStr(result, "42('c', (7,))")); 175} 176 177// PyIndex_Check 178 179TEST_F(AbstractExtensionApiTest, PyIndexCheckWithIntReturnsTrue) { 180 PyObjectPtr int_num(PyLong_FromLong(1)); 181 EXPECT_TRUE(PyIndex_Check(int_num.get())); 182 ASSERT_EQ(PyErr_Occurred(), nullptr); 183} 184 185TEST_F(AbstractExtensionApiTest, PyIndexCheckWithFloatReturnsFalse) { 186 PyObjectPtr float_num(PyFloat_FromDouble(1.1)); 187 EXPECT_FALSE(PyIndex_Check(float_num.get())); 188 ASSERT_EQ(PyErr_Occurred(), nullptr); 189} 190 191TEST_F(AbstractExtensionApiTest, 192 PyIndexCheckWithUncallableDunderIndexReturnsTrue) { 193 PyRun_SimpleString(R"( 194class C: 195 __index__ = None 196idx = C() 197 )"); 198 PyObjectPtr idx(mainModuleGet("idx")); 199 EXPECT_TRUE(PyIndex_Check(idx.get())); 200 ASSERT_EQ(PyErr_Occurred(), nullptr); 201} 202 203TEST_F(AbstractExtensionApiTest, PyIndexCheckWithDunderIndexReturnsTrue) { 204 PyRun_SimpleString(R"( 205class C: 206 def __index__(self): 207 return 1 208idx = C() 209 )"); 210 PyObjectPtr idx(mainModuleGet("idx")); 211 EXPECT_TRUE(PyIndex_Check(idx.get())); 212 ASSERT_EQ(PyErr_Occurred(), nullptr); 213} 214 215TEST_F(AbstractExtensionApiTest, 216 PyIndexCheckWithDunderIndexDescriptorThatRaisesReturnsTrue) { 217 PyRun_SimpleString(R"( 218class Desc: 219 def __get__(self, obj, type): 220 raise UserWarning("foo") 221class C: 222 __index__ = Desc() 223c = C() 224)"); 225 PyObjectPtr c(mainModuleGet("c")); 226 EXPECT_EQ(PyIndex_Check(c.get()), 1); 227 ASSERT_EQ(PyErr_Occurred(), nullptr); 228} 229 230// PyIter_Next 231 232TEST_F(AbstractExtensionApiTest, PyIterNextReturnsNext) { 233 PyObjectPtr one(PyLong_FromLong(1)); 234 PyObjectPtr two(PyLong_FromLong(2)); 235 PyObjectPtr three(PyLong_FromLong(3)); 236 PyObjectPtr tuple(PyTuple_Pack(3, one.get(), two.get(), three.get())); 237 PyObjectPtr iter(PyObject_GetIter(tuple)); 238 ASSERT_NE(iter, nullptr); 239 PyObjectPtr next(PyIter_Next(iter)); 240 ASSERT_NE(next, nullptr); 241 EXPECT_EQ(PyErr_Occurred(), nullptr); 242 EXPECT_EQ(PyLong_AsLong(next), 1); 243 next = PyIter_Next(iter); 244 ASSERT_NE(next, nullptr); 245 EXPECT_EQ(PyErr_Occurred(), nullptr); 246 EXPECT_EQ(PyLong_AsLong(next), 2); 247 next = PyIter_Next(iter); 248 ASSERT_NE(next, nullptr); 249 EXPECT_EQ(PyErr_Occurred(), nullptr); 250 EXPECT_EQ(PyLong_AsLong(next), 3); 251 next = PyIter_Next(iter); 252 ASSERT_EQ(next, nullptr); 253 EXPECT_EQ(PyErr_Occurred(), nullptr); 254} 255 256TEST_F(AbstractExtensionApiTest, PyIterNextOnNonIterRaises) { 257 ASSERT_EQ(PyObject_GetIter(Py_None), nullptr); 258 ASSERT_NE(PyErr_Occurred(), nullptr); 259 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 260} 261 262TEST_F(AbstractExtensionApiTest, PyIterNextPropagatesException) { 263 PyRun_SimpleString(R"( 264class C: 265 def __iter__(self): 266 return self 267 def __next__(self): 268 raise ValueError("hi") 269 270c = C() 271)"); 272 PyObjectPtr c(mainModuleGet("c")); 273 PyObjectPtr iter(PyObject_GetIter(c)); 274 ASSERT_NE(iter, nullptr); 275 PyObjectPtr next(PyIter_Next(iter)); 276 ASSERT_EQ(next, nullptr); 277 ASSERT_NE(PyErr_Occurred(), nullptr); 278 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 279} 280 281// Mapping Protocol 282 283TEST_F(AbstractExtensionApiTest, PyMappingCheckWithoutGetItemReturnsFalse) { 284 PyRun_SimpleString(R"( 285class ClassWithoutDunderGetItem: pass 286 287obj = ClassWithoutDunderGetItem() 288 )"); 289 290 PyObjectPtr obj(mainModuleGet("obj")); 291 EXPECT_FALSE(PyMapping_Check(obj)); 292} 293 294TEST_F(AbstractExtensionApiTest, 295 PyMappingCheckWithoutGetItemOnClassReturnsFalse) { 296 PyRun_SimpleString(R"( 297class ClassWithoutDunderGetItem: pass 298 299obj = ClassWithoutDunderGetItem() 300obj.__getitem__ = lambda self, key: 1 301 )"); 302 303 PyObjectPtr obj(mainModuleGet("obj")); 304 EXPECT_FALSE(PyMapping_Check(obj)); 305} 306 307TEST_F(AbstractExtensionApiTest, PyMappingCheckWithNumericReturnsFalse) { 308 PyObjectPtr num(PyLong_FromLong(4)); 309 EXPECT_FALSE(PyMapping_Check(num)); 310} 311 312TEST_F(AbstractExtensionApiTest, PyMappingCheckWithSetReturnsFalse) { 313 PyObjectPtr set(PySet_New(nullptr)); 314 EXPECT_FALSE(PyMapping_Check(set)); 315} 316 317TEST_F(AbstractExtensionApiTest, PyMappingCheckWithBooleanReturnsFalse) { 318 EXPECT_FALSE(PyMapping_Check(Py_False)); 319} 320 321TEST_F(AbstractExtensionApiTest, PyMappingCheckWithGetItemMethodReturnsTrue) { 322 PyRun_SimpleString(R"( 323class ClassWithDunderGetItemMethod: 324 def __getitem__(self, key): 325 return None 326 327obj = ClassWithDunderGetItemMethod() 328 )"); 329 330 PyObjectPtr obj(mainModuleGet("obj")); 331 EXPECT_TRUE(PyMapping_Check(obj)); 332} 333 334TEST_F(AbstractExtensionApiTest, PyMappingCheckWithGetItemAttrReturnsTrue) { 335 PyRun_SimpleString(R"( 336class ClassWithDunderGetItemAttr: 337 __getitem__ = 42 338 339obj = ClassWithDunderGetItemAttr() 340 )"); 341 342 PyObjectPtr obj(mainModuleGet("obj")); 343 EXPECT_TRUE(PyMapping_Check(obj)); 344} 345 346TEST_F(AbstractExtensionApiTest, PyMappingCheckWithStringReturnsTrue) { 347 PyObjectPtr str(PyUnicode_FromString("foo")); 348 EXPECT_TRUE(PyMapping_Check(str)); 349} 350 351TEST_F(AbstractExtensionApiTest, PyMappingCheckWithListReturnsTrue) { 352 PyObjectPtr list(PyList_New(3)); 353 EXPECT_TRUE(PyMapping_Check(list)); 354} 355 356TEST_F(AbstractExtensionApiTest, PyMappingCheckWithDictReturnsTrue) { 357 PyObjectPtr dict(PyDict_New()); 358 EXPECT_TRUE(PyMapping_Check(dict)); 359} 360 361TEST_F(AbstractExtensionApiTest, PyMappingLengthOnNullRaisesSystemError) { 362 EXPECT_EQ(PyMapping_Length(nullptr), -1); 363 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 364} 365 366TEST_F(AbstractExtensionApiTest, PyMappingLengthWithNonMappingReturnsLen) { 367 PyRun_SimpleString(R"( 368class Foo: 369 def __len__(self): 370 return 1 371obj = Foo() 372 )"); 373 374 PyObjectPtr obj(mainModuleGet("obj")); 375 EXPECT_EQ(PyMapping_Length(obj), 1); 376 EXPECT_EQ(PyErr_Occurred(), nullptr); 377} 378 379TEST_F(AbstractExtensionApiTest, PyMappingSizeOnNullRaisesSystemError) { 380 EXPECT_EQ(PyMapping_Size(nullptr), -1); 381 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 382} 383 384// Number Protocol 385 386TEST_F(AbstractExtensionApiTest, PyNumberAbsoluteWithNullRaisesSystemError) { 387 ASSERT_EQ(PyNumber_Absolute(nullptr), nullptr); 388 ASSERT_NE(PyErr_Occurred(), nullptr); 389 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 390} 391 392TEST_F(AbstractExtensionApiTest, 393 PyNumberAbsoluteWithNoDunderAbsRaisesTypeError) { 394 PyRun_SimpleString(R"( 395class C: 396 pass 397c = C() 398)"); 399 PyObjectPtr c(mainModuleGet("c")); 400 ASSERT_EQ(PyNumber_Absolute(c), nullptr); 401 ASSERT_NE(PyErr_Occurred(), nullptr); 402 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 403} 404 405TEST_F(AbstractExtensionApiTest, PyNumberAbsoluteCallsDunderAbs) { 406 PyObjectPtr negative(PyLong_FromLong(-10)); 407 PyObjectPtr positive(PyLong_FromLong(10)); 408 PyObjectPtr result(PyNumber_Absolute(negative)); 409 EXPECT_EQ(result, positive); 410 EXPECT_EQ(PyErr_Occurred(), nullptr); 411} 412 413TEST_F(AbstractExtensionApiTest, PyNumberAddWithNoDunderAddRaisesTypeError) { 414 PyRun_SimpleString(R"( 415class C: 416 pass 417c = C() 418)"); 419 PyObjectPtr c(mainModuleGet("c")); 420 ASSERT_EQ(PyNumber_Add(c, c), nullptr); 421 ASSERT_NE(PyErr_Occurred(), nullptr); 422 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 423} 424 425TEST_F(AbstractExtensionApiTest, PyNumberAddCallsDunderAdd) { 426 PyRun_SimpleString(R"( 427class ClassWithDunderAdd: 428 def __add__(self, other): 429 return "hello"; 430 431x = ClassWithDunderAdd() 432 )"); 433 PyObjectPtr x(mainModuleGet("x")); 434 PyObjectPtr y(PyLong_FromLong(7)); 435 PyObjectPtr result(PyNumber_Add(x, y)); 436 EXPECT_TRUE(isUnicodeEqualsCStr(result, "hello")); 437} 438 439TEST_F(AbstractExtensionApiTest, PyNumberAddWithIntsReturnsSum) { 440 PyObjectPtr x(PyLong_FromLong(7)); 441 PyObjectPtr y(PyLong_FromLong(10)); 442 PyObjectPtr result(PyNumber_Add(x, y)); 443 ASSERT_TRUE(PyLong_CheckExact(result)); 444 EXPECT_EQ(PyLong_AsLong(result), 17); 445} 446 447TEST_F(AbstractExtensionApiTest, PyNumberAddWithUnicodeReturnsConcat) { 448 PyObjectPtr x(PyUnicode_FromString("foo")); 449 PyObjectPtr y(PyUnicode_FromString("bar")); 450 PyObjectPtr result(PyNumber_Add(x, y)); 451 EXPECT_TRUE(isUnicodeEqualsCStr(result, "foobar")); 452} 453 454TEST_F(AbstractExtensionApiTest, PyNumberAndWithNonIntRaisesTypeError) { 455 PyObjectPtr x(PyUnicode_FromString("foo")); 456 PyObjectPtr y(PyLong_FromLong(2)); 457 ASSERT_EQ(PyNumber_And(x, y), nullptr); 458 ASSERT_NE(PyErr_Occurred(), nullptr); 459 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 460} 461 462TEST_F(AbstractExtensionApiTest, PyNumberAndWithIntsReturnsBitwiseAnd) { 463 PyObjectPtr x(PyLong_FromLong(5)); // 0b0101 464 PyObjectPtr y(PyLong_FromLong(3)); // 0b0011 465 PyObjectPtr result(PyNumber_And(x, y)); 466 ASSERT_TRUE(PyLong_CheckExact(result)); 467 EXPECT_EQ(PyLong_AsLong(result), 1); // 0b0001 468} 469 470TEST_F(AbstractExtensionApiTest, PyNumberAsSsizeTWithNullRaisesSystemError) { 471 ASSERT_EQ(PyNumber_AsSsize_t(nullptr, PyExc_TypeError), -1); 472 ASSERT_NE(PyErr_Occurred(), nullptr); 473 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 474} 475 476TEST_F(AbstractExtensionApiTest, PyNumberAsSsizeTWithStringRaisesTypeError) { 477 PyObjectPtr str(PyUnicode_FromString("foo")); 478 ASSERT_EQ(PyNumber_AsSsize_t(str, nullptr), -1); 479 ASSERT_NE(PyErr_Occurred(), nullptr); 480 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 481} 482 483TEST_F(AbstractExtensionApiTest, PyNumberAsSsizeTWithIntReturnsInt) { 484 PyObjectPtr num(PyLong_FromLong(10)); 485 Py_ssize_t result = PyNumber_AsSsize_t(num, nullptr); 486 ASSERT_EQ(PyErr_Occurred(), nullptr); 487 EXPECT_EQ(result, 10); 488} 489 490TEST_F(AbstractExtensionApiTest, PyNumberAsSsizeTWithIntSubclassReturnsInt) { 491 PyRun_SimpleString(R"( 492class C(int): 493 def __index__(self): return 10 494obj = C(42); 495)"); 496 PyObjectPtr obj(mainModuleGet("obj")); 497 Py_ssize_t result = PyNumber_AsSsize_t(obj, nullptr); 498 EXPECT_EQ(PyErr_Occurred(), nullptr); 499 EXPECT_EQ(result, 42); 500} 501 502TEST_F(AbstractExtensionApiTest, PyNumberAsSsizeTWithDunderIndexReturnsInt) { 503 PyRun_SimpleString(R"( 504class C: 505 def __index__(self): return 42 506obj = C(); 507)"); 508 PyObjectPtr obj(mainModuleGet("obj")); 509 Py_ssize_t result = PyNumber_AsSsize_t(obj, nullptr); 510 EXPECT_EQ(PyErr_Occurred(), nullptr); 511 EXPECT_EQ(result, 42); 512} 513 514TEST_F(AbstractExtensionApiTest, 515 PyNumberAsSsizeTWithNegativeOneReturnsNegativeOne) { 516 PyObjectPtr num(PyLong_FromLong(-1)); 517 Py_ssize_t result = PyNumber_AsSsize_t(num, nullptr); 518 ASSERT_EQ(PyErr_Occurred(), nullptr); 519 EXPECT_EQ(result, -1); 520} 521 522TEST_F(AbstractExtensionApiTest, 523 PyNumberAsSsizeTWithOverflowAndNullClearsError) { 524 const unsigned char bytes[] = {0x01, 0x00, 0x00, 0x00, 0x00, 525 0x00, 0x00, 0x00, 0x00}; 526 PyObjectPtr num(_PyLong_FromByteArray(bytes, sizeof(bytes), false, true)); 527 Py_ssize_t result = PyNumber_AsSsize_t(num, nullptr); 528 ASSERT_EQ(PyErr_Occurred(), nullptr); 529 EXPECT_EQ(result, 0x7fffffffffffffff); 530} 531 532TEST_F(AbstractExtensionApiTest, 533 PyNumberAsSsizeTWithUnderflowAndNullClearsError) { 534 const unsigned char bytes[] = {0xff, 0x00, 0x00, 0x00, 0x00, 535 0x00, 0x00, 0x00, 0x00}; 536 PyObjectPtr num(_PyLong_FromByteArray(bytes, sizeof(bytes), false, true)); 537 Py_ssize_t result = PyNumber_AsSsize_t(num, nullptr); 538 ASSERT_EQ(PyErr_Occurred(), nullptr); 539 EXPECT_EQ(result, INT64_MIN); 540} 541 542TEST_F(AbstractExtensionApiTest, PyNumberAsSsizeTWithOverflowSetsGivenError) { 543 const unsigned char bytes[] = {0x01, 0x00, 0x00, 0x00, 0x00, 544 0x00, 0x00, 0x00, 0x00}; 545 PyObjectPtr num(_PyLong_FromByteArray(bytes, sizeof(bytes), false, true)); 546 ASSERT_EQ(PyNumber_AsSsize_t(num, PyExc_ModuleNotFoundError), -1); 547 ASSERT_NE(PyErr_Occurred(), nullptr); 548 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)); 549} 550 551TEST_F(AbstractExtensionApiTest, PyNumberCheckWithFloatReturnsTrue) { 552 PyObjectPtr float_num(PyFloat_FromDouble(1.1)); 553 EXPECT_EQ(PyNumber_Check(float_num), 1); 554 ASSERT_EQ(PyErr_Occurred(), nullptr); 555} 556 557TEST_F(AbstractExtensionApiTest, PyNumberCheckWithIntReturnsTrue) { 558 PyObjectPtr int_num(PyLong_FromLong(1)); 559 EXPECT_EQ(PyNumber_Check(int_num), 1); 560 ASSERT_EQ(PyErr_Occurred(), nullptr); 561} 562 563TEST_F(AbstractExtensionApiTest, PyNumberCheckWithFloatSubclassReturnsTrue) { 564 PyRun_SimpleString(R"( 565class SubFloat(float): 566 pass 567sub = SubFloat() 568 )"); 569 PyObjectPtr sub(mainModuleGet("sub")); 570 EXPECT_EQ(PyNumber_Check(sub), 1); 571 ASSERT_EQ(PyErr_Occurred(), nullptr); 572} 573 574TEST_F(AbstractExtensionApiTest, PyNumberCheckWithDunderIntClassReturnsTrue) { 575 PyRun_SimpleString(R"( 576class DunderIntClass(): 577 def __int__(self): 578 return 5 579i = DunderIntClass() 580 )"); 581 PyObjectPtr i(mainModuleGet("i")); 582 EXPECT_EQ(PyNumber_Check(i), 1); 583 ASSERT_EQ(PyErr_Occurred(), nullptr); 584} 585 586TEST_F(AbstractExtensionApiTest, PyNumberCheckWithDunderFloatClassReturnsTrue) { 587 PyRun_SimpleString(R"( 588class DunderFloatClass(): 589 def __float__(self): 590 return 5.0 591f = DunderFloatClass() 592 )"); 593 PyObjectPtr f(mainModuleGet("f")); 594 EXPECT_EQ(PyNumber_Check(f), 1); 595 ASSERT_EQ(PyErr_Occurred(), nullptr); 596} 597 598TEST_F(AbstractExtensionApiTest, PyNumberCheckWithNonNumberReturnsFalse) { 599 PyObjectPtr str(PyUnicode_FromString("")); 600 EXPECT_EQ(PyNumber_Check(str), 0); 601 ASSERT_EQ(PyErr_Occurred(), nullptr); 602} 603 604TEST_F(AbstractExtensionApiTest, 605 PyNumberCheckWithDunderIntDescriptorThatRaisesReturnsTrue) { 606 PyRun_SimpleString(R"( 607class Desc: 608 def __get__(self, obj, type): 609 raise UserWarning("foo") 610class C: 611 __int__ = Desc() 612c = C() 613)"); 614 PyObjectPtr c(mainModuleGet("c")); 615 EXPECT_EQ(PyNumber_Check(c), 1); 616 ASSERT_EQ(PyErr_Occurred(), nullptr); 617} 618 619TEST_F(AbstractExtensionApiTest, 620 PyNumberCheckWithDunderFloatDescriptorThatRaisesReturnsTrue) { 621 PyRun_SimpleString(R"( 622class Desc: 623 def __get__(self, obj, type): 624 raise UserWarning("foo") 625class C: 626 __float__ = Desc() 627c = C() 628)"); 629 PyObjectPtr c(mainModuleGet("c")); 630 EXPECT_EQ(PyNumber_Check(c), 1); 631 ASSERT_EQ(PyErr_Occurred(), nullptr); 632} 633 634TEST_F(AbstractExtensionApiTest, PyNumberCheckWithNullReturnsFalse) { 635 EXPECT_EQ(PyNumber_Check(nullptr), 0); 636 ASSERT_EQ(PyErr_Occurred(), nullptr); 637} 638 639TEST_F(AbstractExtensionApiTest, PyNumberFloatWithNullRaisesSystemError) { 640 EXPECT_EQ(PyNumber_Float(nullptr), nullptr); 641 ASSERT_NE(PyErr_Occurred(), nullptr); 642 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 643} 644 645TEST_F(AbstractExtensionApiTest, PyNumberFloatWithStringReturnsFloat) { 646 PyObjectPtr str(PyUnicode_FromString("4.2")); 647 PyObjectPtr flt(PyNumber_Float(str)); 648 EXPECT_EQ(PyErr_Occurred(), nullptr); 649 ASSERT_TRUE(PyFloat_CheckExact(flt)); 650 EXPECT_EQ(PyFloat_AsDouble(flt), 4.2); 651} 652 653TEST_F(AbstractExtensionApiTest, PyNumberFloatWithIntReturnsFloat) { 654 PyObjectPtr num(PyLong_FromLong(42)); 655 PyObjectPtr flt(PyNumber_Float(num)); 656 EXPECT_EQ(PyErr_Occurred(), nullptr); 657 ASSERT_TRUE(PyFloat_CheckExact(flt)); 658 EXPECT_EQ(PyFloat_AsDouble(flt), 42.0); 659} 660 661TEST_F(AbstractExtensionApiTest, PyNumberFloatWithFloatReturnsSameFloat) { 662 PyObjectPtr num(PyFloat_FromDouble(4.2)); 663 Py_ssize_t refcnt = Py_REFCNT(num); 664 PyObjectPtr flt(PyNumber_Float(num)); 665 EXPECT_EQ(PyErr_Occurred(), nullptr); 666 EXPECT_EQ(num, flt); 667 EXPECT_EQ(Py_REFCNT(num), refcnt + 1); 668} 669 670TEST_F(AbstractExtensionApiTest, PyNumberFloatWithFloatSubclassReturnsFloat) { 671 PyRun_SimpleString(R"( 672class C(float): 673 pass 674x = C(4.2) 675)"); 676 PyObjectPtr x(mainModuleGet("x")); 677 PyObjectPtr flt(PyNumber_Float(x)); 678 EXPECT_EQ(PyErr_Occurred(), nullptr); 679 ASSERT_TRUE(PyFloat_CheckExact(flt)); 680 EXPECT_EQ(PyFloat_AsDouble(flt), 4.2); 681} 682 683TEST_F(AbstractExtensionApiTest, 684 PyNumberFloatWithDescriptorThatRaisesPropagatesException) { 685 PyRun_SimpleString(R"( 686class Desc: 687 def __get__(self, obj, type): 688 raise UserWarning("foo") 689class C: 690 __float__ = Desc() 691c = C() 692)"); 693 PyObjectPtr c(mainModuleGet("c")); 694 EXPECT_EQ(PyNumber_Float(c), nullptr); 695 ASSERT_NE(PyErr_Occurred(), nullptr); 696 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_UserWarning)); 697} 698 699TEST_F(AbstractExtensionApiTest, PyNumberFloorDivideWithNonIntRaisesTypeError) { 700 PyObjectPtr x(PyUnicode_FromString("foo")); 701 PyObjectPtr y(PyLong_FromLong(2)); 702 ASSERT_EQ(PyNumber_FloorDivide(x, y), nullptr); 703 ASSERT_NE(PyErr_Occurred(), nullptr); 704 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 705} 706 707TEST_F(AbstractExtensionApiTest, PyNumberFloorDivideWithIntsReturnsInt) { 708 PyObjectPtr x(PyLong_FromLong(42)); 709 PyObjectPtr y(PyLong_FromLong(5)); 710 PyObjectPtr result(PyNumber_FloorDivide(x, y)); 711 ASSERT_TRUE(PyLong_CheckExact(result)); 712 EXPECT_EQ(PyLong_AsLong(result), 8); 713} 714 715TEST_F(AbstractExtensionApiTest, PyNumberIndexOnIntReturnsSelf) { 716 PyObjectPtr pylong(PyLong_FromLong(666)); 717 PyObjectPtr index(PyNumber_Index(pylong)); 718 EXPECT_EQ(index, pylong); 719} 720 721TEST_F(AbstractExtensionApiTest, PyNumberIndexOnIntSubclassReturnsSelf) { 722 PyRun_SimpleString(R"( 723class C(int): pass 724obj = C(42); 725)"); 726 PyObjectPtr obj(mainModuleGet("obj")); 727 PyObjectPtr index(PyNumber_Index(obj)); 728 EXPECT_EQ(index, obj); 729} 730 731TEST_F(AbstractExtensionApiTest, PyNumberIndexCallsDunderIndex) { 732 PyRun_SimpleString(R"( 733class IntLikeClass: 734 def __index__(self): 735 return 42; 736 737i = IntLikeClass(); 738 )"); 739 PyObjectPtr i(mainModuleGet("i")); 740 PyObjectPtr index(PyNumber_Index(i)); 741 ASSERT_TRUE(PyLong_CheckExact(index)); 742 EXPECT_EQ(PyLong_AsLong(index), 42); 743} 744 745TEST_F(AbstractExtensionApiTest, PyNumberIndexOnNullRaisesSystemError) { 746 ASSERT_EQ(PyNumber_Index(nullptr), nullptr); 747 ASSERT_NE(PyErr_Occurred(), nullptr); 748 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 749} 750 751TEST_F(AbstractExtensionApiTest, PyNumberIndexOnNonIntRaisesTypeError) { 752 PyObjectPtr str(PyUnicode_FromString("not an int")); 753 ASSERT_EQ(PyNumber_Index(str), nullptr); 754 ASSERT_NE(PyErr_Occurred(), nullptr); 755 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 756} 757 758TEST_F(AbstractExtensionApiTest, 759 PyNumberIndexWithMistypedDunderIndexRaisesTypeError) { 760 PyRun_SimpleString(R"( 761class IntLikeClass: 762 def __index__(self): 763 return "not an int"; 764 765i = IntLikeClass(); 766 )"); 767 PyObjectPtr i(mainModuleGet("i")); 768 ASSERT_EQ(PyNumber_Index(i), nullptr); 769 ASSERT_NE(PyErr_Occurred(), nullptr); 770 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 771} 772 773TEST_F(AbstractExtensionApiTest, 774 PyNumberInPlaceAddWithNonNumberRaisesTypeError) { 775 PyObjectPtr x(PyUnicode_FromString("foo")); 776 PyObjectPtr y(PyLong_FromLong(2)); 777 ASSERT_EQ(PyNumber_InPlaceAdd(x, y), nullptr); 778 ASSERT_NE(PyErr_Occurred(), nullptr); 779 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 780} 781 782TEST_F(AbstractExtensionApiTest, PyNumberInPlaceAddWithIntsReturnsInt) { 783 PyObjectPtr x(PyLong_FromLong(4)); 784 PyObjectPtr y(PyLong_FromLong(2)); 785 PyObjectPtr result(PyNumber_InPlaceAdd(x, y)); 786 ASSERT_TRUE(PyLong_CheckExact(result)); 787 EXPECT_EQ(PyLong_AsLong(result), 6); 788 EXPECT_EQ(PyLong_AsLong(x), 4); 789} 790 791TEST_F(AbstractExtensionApiTest, 792 PyNumberInPlaceAndWithNonNumberRaisesTypeError) { 793 PyObjectPtr x(PyUnicode_FromString("foo")); 794 PyObjectPtr y(PyLong_FromLong(2)); 795 ASSERT_EQ(PyNumber_InPlaceAnd(x, y), nullptr); 796 ASSERT_NE(PyErr_Occurred(), nullptr); 797 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 798} 799 800TEST_F(AbstractExtensionApiTest, PyNumberInPlaceAndWithIntsReturnsInt) { 801 PyObjectPtr x(PyLong_FromLong(5)); // 0b0101 802 PyObjectPtr y(PyLong_FromLong(3)); // 0b0011 803 PyObjectPtr result(PyNumber_InPlaceAnd(x, y)); 804 ASSERT_TRUE(PyLong_CheckExact(result)); 805 EXPECT_EQ(PyLong_AsLong(result), 1); // 0b0001 806 EXPECT_EQ(PyLong_AsLong(x), 5); 807} 808 809TEST_F(AbstractExtensionApiTest, 810 PyNumberInPlaceFloorDivideWithNonNumberRaisesTypeError) { 811 PyObjectPtr x(PyUnicode_FromString("foo")); 812 PyObjectPtr y(PyLong_FromLong(2)); 813 ASSERT_EQ(PyNumber_InPlaceFloorDivide(x, y), nullptr); 814 ASSERT_NE(PyErr_Occurred(), nullptr); 815 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 816} 817 818TEST_F(AbstractExtensionApiTest, PyNumberInPlaceFloorDivideWithIntsReturnsInt) { 819 PyObjectPtr x(PyLong_FromLong(42)); 820 PyObjectPtr y(PyLong_FromLong(5)); 821 PyObjectPtr result(PyNumber_InPlaceFloorDivide(x, y)); 822 ASSERT_TRUE(PyLong_CheckExact(result)); 823 EXPECT_EQ(PyLong_AsLong(result), 8); 824 EXPECT_EQ(PyLong_AsLong(x), 42); 825} 826 827TEST_F(AbstractExtensionApiTest, 828 PyNumberInPlaceLshiftWithNonNumberRaisesTypeError) { 829 PyObjectPtr x(PyUnicode_FromString("foo")); 830 PyObjectPtr y(PyLong_FromLong(2)); 831 ASSERT_EQ(PyNumber_InPlaceLshift(x, y), nullptr); 832 ASSERT_NE(PyErr_Occurred(), nullptr); 833 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 834} 835 836TEST_F(AbstractExtensionApiTest, PyNumberInPlaceLshiftIntsReturnsInt) { 837 PyObjectPtr x(PyLong_FromLong(5)); 838 PyObjectPtr y(PyLong_FromLong(3)); 839 PyObjectPtr result(PyNumber_InPlaceLshift(x, y)); 840 ASSERT_TRUE(PyLong_CheckExact(result)); 841 EXPECT_EQ(PyLong_AsLong(result), 40); 842 EXPECT_EQ(PyLong_AsLong(x), 5); 843} 844 845TEST_F(AbstractExtensionApiTest, 846 PyNumberInPlaceMatrixMultiplyWithNonNumberRaisesTypeError) { 847 PyObjectPtr x(PyUnicode_FromString("foo")); 848 PyObjectPtr y(PyLong_FromLong(2)); 849 ASSERT_EQ(PyNumber_InPlaceMatrixMultiply(x, y), nullptr); 850 ASSERT_NE(PyErr_Occurred(), nullptr); 851 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 852} 853 854TEST_F(AbstractExtensionApiTest, 855 PyNumberInPlaceMatrixMultiplyCallsDunderImatmul) { 856 PyRun_SimpleString(R"( 857class C: 858 def __init__(self): 859 self.called = False 860 def __imatmul__(self, other): 861 self.called = True 862 return 1 863x = C() 864)"); 865 PyObjectPtr x(mainModuleGet("x")); 866 PyObjectPtr y(PyLong_FromLong(3)); 867 PyObjectPtr called1(PyObject_GetAttrString(x, "called")); 868 EXPECT_EQ(called1, Py_False); 869 PyObjectPtr result(PyNumber_InPlaceMatrixMultiply(x, y)); 870 ASSERT_TRUE(PyLong_CheckExact(result)); 871 EXPECT_EQ(PyLong_AsLong(result), 1); 872 PyObjectPtr called2(PyObject_GetAttrString(x, "called")); 873 EXPECT_EQ(called2, Py_True); 874} 875 876TEST_F(AbstractExtensionApiTest, 877 PyNumberInPlaceMultiplyWithNonNumberRaisesTypeError) { 878 PyObjectPtr x(PyLong_FromLong(2)); 879 ASSERT_EQ(PyNumber_InPlaceMultiply(x, Py_None), nullptr); 880 ASSERT_NE(PyErr_Occurred(), nullptr); 881 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 882} 883 884TEST_F(AbstractExtensionApiTest, PyNumberInPlaceMultiplyWithIntsReturnsInt) { 885 PyObjectPtr x(PyLong_FromLong(3)); 886 PyObjectPtr y(PyLong_FromLong(2)); 887 PyObjectPtr result(PyNumber_InPlaceMultiply(x, y)); 888 ASSERT_TRUE(PyLong_CheckExact(result)); 889 EXPECT_EQ(PyLong_AsLong(result), 6); 890} 891 892TEST_F(AbstractExtensionApiTest, 893 PyNumberInPlaceOrWithNonNumberRaisesTypeError) { 894 PyObjectPtr x(PyUnicode_FromString("foo")); 895 PyObjectPtr y(PyLong_FromLong(2)); 896 ASSERT_EQ(PyNumber_InPlaceOr(x, y), nullptr); 897 ASSERT_NE(PyErr_Occurred(), nullptr); 898 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 899} 900 901TEST_F(AbstractExtensionApiTest, PyNumberInPlaceOrWithIntsReturnsInt) { 902 PyObjectPtr x(PyLong_FromLong(5)); // 0b0101 903 PyObjectPtr y(PyLong_FromLong(3)); // 0b0011 904 PyObjectPtr result(PyNumber_InPlaceOr(x, y)); 905 ASSERT_TRUE(PyLong_CheckExact(result)); 906 EXPECT_EQ(PyLong_AsLong(result), 7); // 0b0111 907 EXPECT_EQ(PyLong_AsLong(x), 5); 908} 909 910TEST_F(AbstractExtensionApiTest, 911 PyNumberInPlacePowerWithNonNumberRaisesTypeError) { 912 PyObjectPtr x(PyUnicode_FromString("foo")); 913 PyObjectPtr y(PyLong_FromLong(2)); 914 ASSERT_EQ(PyNumber_InPlacePower(x, y, Py_None), nullptr); 915 ASSERT_NE(PyErr_Occurred(), nullptr); 916 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 917} 918 919TEST_F(AbstractExtensionApiTest, PyNumberInPlacePowerCallsDunderIpow) { 920 PyRun_SimpleString(R"( 921class C: 922 def __init__(self): 923 self.called = False 924 def __ipow__(self, other): 925 self.called = True 926 return 1 927x = C() 928)"); 929 PyObjectPtr x(mainModuleGet("x")); 930 PyObjectPtr y(PyLong_FromLong(3)); 931 PyObjectPtr called1(PyObject_GetAttrString(x, "called")); 932 EXPECT_EQ(called1, Py_False); 933 PyObjectPtr result(PyNumber_InPlacePower(x, y, Py_None)); 934 ASSERT_TRUE(PyLong_CheckExact(result)); 935 EXPECT_EQ(PyLong_AsLong(result), 1); 936 PyObjectPtr called2(PyObject_GetAttrString(x, "called")); 937 EXPECT_EQ(called2, Py_True); 938} 939 940TEST_F(AbstractExtensionApiTest, 941 PyNumberInPlaceRemainderWithNonNumberRaisesTypeError) { 942 PyObjectPtr x(PyList_New(0)); 943 PyObjectPtr y(PyLong_FromLong(2)); 944 ASSERT_EQ(PyNumber_InPlaceRemainder(x, y), nullptr); 945 ASSERT_NE(PyErr_Occurred(), nullptr); 946 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 947} 948 949TEST_F(AbstractExtensionApiTest, PyNumberInPlaceRemainderWithIntsReturnsInt) { 950 PyObjectPtr x(PyLong_FromLong(42)); 951 PyObjectPtr y(PyLong_FromLong(5)); 952 PyObjectPtr result(PyNumber_InPlaceRemainder(x, y)); 953 ASSERT_TRUE(PyLong_CheckExact(result)); 954 EXPECT_EQ(PyLong_AsLong(result), 2); 955} 956 957TEST_F(AbstractExtensionApiTest, 958 PyNumberInPlaceRshiftWithNonNumberRaisesTypeError) { 959 PyObjectPtr x(PyUnicode_FromString("foo")); 960 PyObjectPtr y(PyLong_FromLong(2)); 961 ASSERT_EQ(PyNumber_InPlaceRshift(x, y), nullptr); 962 ASSERT_NE(PyErr_Occurred(), nullptr); 963 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 964} 965 966TEST_F(AbstractExtensionApiTest, PyNumberInPlaceRshiftIntsReturnsInt) { 967 PyObjectPtr x(PyLong_FromLong(42)); 968 PyObjectPtr y(PyLong_FromLong(3)); 969 PyObjectPtr result(PyNumber_InPlaceRshift(x, y)); 970 ASSERT_TRUE(PyLong_CheckExact(result)); 971 EXPECT_EQ(PyLong_AsLong(result), 5); 972 EXPECT_EQ(PyLong_AsLong(x), 42); 973} 974 975TEST_F(AbstractExtensionApiTest, 976 PyNumberInPlaceSubtractWithNonNumberRaisesTypeError) { 977 PyObjectPtr x(PyUnicode_FromString("foo")); 978 PyObjectPtr y(PyLong_FromLong(2)); 979 ASSERT_EQ(PyNumber_InPlaceSubtract(x, y), nullptr); 980 ASSERT_NE(PyErr_Occurred(), nullptr); 981 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 982} 983 984TEST_F(AbstractExtensionApiTest, PyNumberInPlaceSubtractIntsReturnsInt) { 985 PyObjectPtr x(PyLong_FromLong(5)); 986 PyObjectPtr y(PyLong_FromLong(3)); 987 PyObjectPtr result(PyNumber_InPlaceSubtract(x, y)); 988 ASSERT_TRUE(PyLong_CheckExact(result)); 989 EXPECT_EQ(PyLong_AsLong(result), 2); 990 EXPECT_EQ(PyLong_AsLong(x), 5); 991} 992 993TEST_F(AbstractExtensionApiTest, 994 PyNumberInPlaceTrueDivideWithNonNumberRaisesTypeError) { 995 PyObjectPtr x(PyUnicode_FromString("foo")); 996 PyObjectPtr y(PyLong_FromLong(2)); 997 ASSERT_EQ(PyNumber_InPlaceTrueDivide(x, y), nullptr); 998 ASSERT_NE(PyErr_Occurred(), nullptr); 999 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1000} 1001 1002TEST_F(AbstractExtensionApiTest, 1003 PyNumberInPlaceTrueDivideWithFloatsReturnsFloat) { 1004 PyObjectPtr x(PyLong_FromLong(42.0)); 1005 PyObjectPtr y(PyLong_FromLong(5)); 1006 PyObjectPtr result(PyNumber_InPlaceTrueDivide(x, y)); 1007 ASSERT_TRUE(PyFloat_CheckExact(result)); 1008 EXPECT_EQ(PyFloat_AsDouble(result), 8.4); 1009 EXPECT_EQ(PyFloat_AsDouble(x), 42.0); 1010} 1011 1012TEST_F(AbstractExtensionApiTest, 1013 PyNumberInPlaceXorWithNonNumberRaisesTypeError) { 1014 PyObjectPtr x(PyUnicode_FromString("foo")); 1015 PyObjectPtr y(PyLong_FromLong(2)); 1016 ASSERT_EQ(PyNumber_InPlaceXor(x, y), nullptr); 1017 ASSERT_NE(PyErr_Occurred(), nullptr); 1018 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1019} 1020 1021TEST_F(AbstractExtensionApiTest, PyNumberInPlaceXorWithIntsReturnsInt) { 1022 PyObjectPtr x(PyLong_FromLong(5)); // 0b0101 1023 PyObjectPtr y(PyLong_FromLong(3)); // 0b0011 1024 PyObjectPtr result(PyNumber_InPlaceXor(x, y)); 1025 ASSERT_TRUE(PyLong_CheckExact(result)); 1026 EXPECT_EQ(PyLong_AsLong(result), 6); // 0b0110 1027 EXPECT_EQ(PyLong_AsLong(x), 5); 1028} 1029 1030TEST_F(AbstractExtensionApiTest, PyNumberInvertWithIntReturnsInt) { 1031 PyObjectPtr num(PyLong_FromLong(7)); 1032 PyObjectPtr result(PyNumber_Invert(num)); 1033 EXPECT_EQ(PyLong_AsLong(result), -8); 1034} 1035 1036TEST_F(AbstractExtensionApiTest, 1037 PyNumberInvertWithCustomClassCallsDunderInvert) { 1038 PyRun_SimpleString(R"( 1039class C: 1040 def __invert__(self): 1041 return "custom invert" 1042c = C() 1043)"); 1044 PyObjectPtr c(mainModuleGet("c")); 1045 PyObjectPtr result(PyNumber_Invert(c)); 1046 EXPECT_EQ(PyUnicode_CompareWithASCIIString(result, "custom invert"), 0); 1047} 1048 1049TEST_F(AbstractExtensionApiTest, PyNumberInvertWithNullRaisesSystemError) { 1050 ASSERT_EQ(PyNumber_Invert(nullptr), nullptr); 1051 ASSERT_NE(PyErr_Occurred(), nullptr); 1052 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 1053} 1054 1055TEST_F(AbstractExtensionApiTest, PyNumberInvertWithNonNumberRaisesTypeError) { 1056 ASSERT_EQ(PyNumber_Positive(Py_None), nullptr); 1057 ASSERT_NE(PyErr_Occurred(), nullptr); 1058 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1059} 1060 1061TEST_F(AbstractExtensionApiTest, PyNumberInvertPropagatesException) { 1062 PyRun_SimpleString(R"( 1063class C: 1064 def __invert__(self): 1065 raise UserWarning() 1066c = C() 1067)"); 1068 PyObjectPtr c(mainModuleGet("c")); 1069 PyObjectPtr result(PyNumber_Invert(c)); 1070 ASSERT_EQ(result, nullptr); 1071 ASSERT_NE(PyErr_Occurred(), nullptr); 1072 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_UserWarning)); 1073} 1074 1075TEST_F(AbstractExtensionApiTest, PyNumberLongWithNullRaisesSystemError) { 1076 EXPECT_EQ(PyNumber_Long(nullptr), nullptr); 1077 ASSERT_NE(PyErr_Occurred(), nullptr); 1078 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 1079} 1080 1081TEST_F(AbstractExtensionApiTest, PyNumberLongWithIntReturnsInt) { 1082 PyObjectPtr intobj(PyLong_FromLong(PY_SSIZE_T_MAX)); 1083 Py_ssize_t refcnt = Py_REFCNT(intobj); 1084 PyObjectPtr result(PyNumber_Long(intobj)); 1085 ASSERT_NE(result, nullptr); 1086 EXPECT_EQ(result, intobj); 1087 EXPECT_EQ(Py_REFCNT(result), refcnt + 1); 1088 EXPECT_EQ(PyErr_Occurred(), nullptr); 1089} 1090 1091TEST_F(AbstractExtensionApiTest, 1092 PyNumberLongDunderLongReturnsNonIntRaisesTypeError) { 1093 PyRun_SimpleString(R"( 1094class C: 1095 def __int__(self): 1096 return "foo" 1097c = C() 1098)"); 1099 PyObjectPtr c(mainModuleGet("c")); 1100 EXPECT_EQ(PyNumber_Long(c), nullptr); 1101 ASSERT_NE(PyErr_Occurred(), nullptr); 1102 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1103} 1104 1105TEST_F(AbstractExtensionApiTest, PyNumberLongCallsDunderTrunc) { 1106 PyRun_SimpleString(R"( 1107class C: 1108 def __trunc__(self): 1109 return 7 1110c = C() 1111)"); 1112 PyObjectPtr c(mainModuleGet("c")); 1113 PyObjectPtr result(PyNumber_Long(c)); 1114 ASSERT_NE(result, nullptr); 1115 EXPECT_EQ(PyLong_AsLong(result), 7); 1116 EXPECT_EQ(PyErr_Occurred(), nullptr); 1117} 1118 1119TEST_F(AbstractExtensionApiTest, PyNumberLongCallsDunderTruncAndDunderInt) { 1120 PyRun_SimpleString(R"( 1121class D: 1122 def __int__(self): 1123 return 8 1124 1125class C: 1126 def __trunc__(self): 1127 return D() 1128 1129c = C() 1130)"); 1131 PyObjectPtr c(mainModuleGet("c")); 1132 PyObjectPtr result(PyNumber_Long(c)); 1133 ASSERT_NE(result, nullptr); 1134 EXPECT_EQ(PyLong_AsLong(result), 8); 1135 EXPECT_EQ(PyErr_Occurred(), nullptr); 1136} 1137 1138TEST_F(AbstractExtensionApiTest, PyNumberLongWithStringReturnsInt) { 1139 PyObjectPtr str(PyUnicode_FromString("7")); 1140 PyObjectPtr result(PyNumber_Long(str)); 1141 ASSERT_NE(result, nullptr); 1142 EXPECT_EQ(PyLong_AsLong(result), 7); 1143 EXPECT_EQ(PyErr_Occurred(), nullptr); 1144} 1145 1146TEST_F(AbstractExtensionApiTest, 1147 PyNumberLongWithUnsupportedTypeRaisesTypeError) { 1148 PyRun_SimpleString(R"( 1149class C: 1150 pass 1151c = C() 1152)"); 1153 PyObjectPtr c(mainModuleGet("c")); 1154 EXPECT_EQ(PyNumber_Long(c), nullptr); 1155 ASSERT_NE(PyErr_Occurred(), nullptr); 1156 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1157} 1158 1159TEST_F(AbstractExtensionApiTest, PyNumberLshiftWithNonIntSelfRaisesTypeError) { 1160 PyObjectPtr x(PyFloat_FromDouble(5.0)); 1161 PyObjectPtr y(PyLong_FromLong(2)); 1162 ASSERT_EQ(PyNumber_Lshift(x, y), nullptr); 1163 ASSERT_NE(PyErr_Occurred(), nullptr); 1164 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1165} 1166 1167TEST_F(AbstractExtensionApiTest, PyNumberLshiftWithNonIntOtherRaisesTypeError) { 1168 PyObjectPtr x(PyLong_FromLong(5)); 1169 PyObjectPtr y(PyFloat_FromDouble(2.0)); 1170 ASSERT_EQ(PyNumber_Lshift(x, y), nullptr); 1171 ASSERT_NE(PyErr_Occurred(), nullptr); 1172 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1173} 1174 1175TEST_F(AbstractExtensionApiTest, PyNumberLshiftWithIntsShiftBitsLeft) { 1176 PyObjectPtr x(PyLong_FromLong(0x13)); 1177 PyObjectPtr y(PyLong_FromLong(2)); 1178 PyObjectPtr result(PyNumber_Lshift(x, y)); 1179 ASSERT_TRUE(PyLong_CheckExact(result)); 1180 EXPECT_EQ(PyLong_AsLong(result), 0x4C); 1181} 1182 1183TEST_F(AbstractExtensionApiTest, 1184 PyNumberMatrixMultiplyWithoutDunderMatmulRaisesTypeError) { 1185 PyObjectPtr x(PyFloat_FromDouble(5.0)); 1186 PyObjectPtr y(PyLong_FromLong(2)); 1187 ASSERT_EQ(PyNumber_MatrixMultiply(x, y), nullptr); 1188 ASSERT_NE(PyErr_Occurred(), nullptr); 1189 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1190} 1191 1192TEST_F(AbstractExtensionApiTest, PyNumberMatrixMultiplyCallsDunderMatmul) { 1193 PyRun_SimpleString(R"( 1194class C: 1195 def __matmul__(self, other): 1196 return other 1197c = C() 1198)"); 1199 PyObjectPtr c(mainModuleGet("c")); 1200 PyObjectPtr x(PyLong_FromLong(42)); 1201 PyObjectPtr result(PyNumber_MatrixMultiply(c, x)); 1202 ASSERT_TRUE(PyLong_CheckExact(result)); 1203 ASSERT_EQ(PyLong_AsLong(result), 42); 1204} 1205 1206TEST_F(AbstractExtensionApiTest, PyNumberMultiplyWithIntsReturnsInt) { 1207 PyObjectPtr x(PyLong_FromLong(5)); 1208 PyObjectPtr y(PyLong_FromLong(2)); 1209 PyObjectPtr result(PyNumber_Multiply(x, y)); 1210 ASSERT_TRUE(PyLong_CheckExact(result)); 1211 EXPECT_EQ(PyLong_AsLong(result), 10); 1212} 1213 1214TEST_F(AbstractExtensionApiTest, PyNumberMultiplyWithFloatReturnsFloat) { 1215 PyObjectPtr x(PyFloat_FromDouble(5.0)); 1216 PyObjectPtr y(PyLong_FromLong(2)); 1217 PyObjectPtr result(PyNumber_Multiply(x, y)); 1218 ASSERT_TRUE(PyFloat_CheckExact(result)); 1219 ASSERT_EQ(PyFloat_AsDouble(result), 10.0); 1220} 1221 1222TEST_F(AbstractExtensionApiTest, PyNumberMultiplyCallsDunderMul) { 1223 PyRun_SimpleString(R"( 1224class C: 1225 def __mul__(self, other): 1226 return other 1227c = C() 1228)"); 1229 PyObjectPtr c(mainModuleGet("c")); 1230 PyObjectPtr x(PyLong_FromLong(42)); 1231 PyObjectPtr result(PyNumber_Multiply(c, x)); 1232 ASSERT_TRUE(PyLong_CheckExact(result)); 1233 ASSERT_EQ(PyLong_AsLong(result), 42); 1234} 1235 1236TEST_F(AbstractExtensionApiTest, PyNumberNegativeWithIntReturnsInt) { 1237 PyObjectPtr num(PyLong_FromLong(-22)); 1238 PyObjectPtr result(PyNumber_Negative(num)); 1239 EXPECT_EQ(PyLong_AsLong(result), 22); 1240} 1241 1242TEST_F(AbstractExtensionApiTest, 1243 PyNumberNegativeWithCustomClassCallsDunderNeg) { 1244 PyRun_SimpleString(R"( 1245class C: 1246 def __neg__(self): 1247 return "custom neg" 1248c = C() 1249)"); 1250 PyObjectPtr c(mainModuleGet("c")); 1251 PyObjectPtr result(PyNumber_Negative(c)); 1252 EXPECT_EQ(PyUnicode_CompareWithASCIIString(result, "custom neg"), 0); 1253} 1254 1255TEST_F(AbstractExtensionApiTest, PyNumberNegativeWithNullRaisesSystemError) { 1256 EXPECT_EQ(PyNumber_Negative(nullptr), nullptr); 1257 ASSERT_NE(PyErr_Occurred(), nullptr); 1258 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 1259} 1260 1261TEST_F(AbstractExtensionApiTest, PyNumberNegativeWithNonNumberRaisesTypeError) { 1262 EXPECT_EQ(PyNumber_Negative(Py_None), nullptr); 1263 ASSERT_NE(PyErr_Occurred(), nullptr); 1264 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1265} 1266 1267TEST_F(AbstractExtensionApiTest, PyNumberNegativePropagatesException) { 1268 PyRun_SimpleString(R"( 1269class C: 1270 def __neg__(self): 1271 raise UserWarning() 1272c = C() 1273)"); 1274 PyObjectPtr c(mainModuleGet("c")); 1275 PyObjectPtr result(PyNumber_Negative(c)); 1276 EXPECT_EQ(result, nullptr); 1277 ASSERT_NE(PyErr_Occurred(), nullptr); 1278 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_UserWarning)); 1279} 1280 1281TEST_F(AbstractExtensionApiTest, PyNumberOrWithNonIntRaisesTypeError) { 1282 PyObjectPtr x(PyLong_FromLong(10)); 1283 PyObjectPtr y(PyFloat_FromDouble(2.0)); 1284 ASSERT_EQ(PyNumber_Or(x, y), nullptr); 1285 ASSERT_NE(PyErr_Occurred(), nullptr); 1286 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1287} 1288 1289TEST_F(AbstractExtensionApiTest, PyNumberOrWithIntsReturnsBitwiseOr) { 1290 PyObjectPtr x(PyLong_FromLong(5)); // 0b0101 1291 PyObjectPtr y(PyLong_FromLong(3)); // 0b0011 1292 PyObjectPtr result(PyNumber_Or(x, y)); 1293 ASSERT_TRUE(PyLong_CheckExact(result)); 1294 EXPECT_EQ(PyLong_AsLong(result), 7); // 0b0111 1295} 1296 1297TEST_F(AbstractExtensionApiTest, PyNumberPositiveWithIntReturnsInt) { 1298 PyObjectPtr num(PyLong_FromLong(-13)); 1299 PyObjectPtr result(PyNumber_Positive(num)); 1300 EXPECT_EQ(PyLong_AsLong(result), -13); 1301} 1302 1303TEST_F(AbstractExtensionApiTest, 1304 PyNumberPositiveWithCustomClassCallsDunderPos) { 1305 PyRun_SimpleString(R"( 1306class C: 1307 def __pos__(self): 1308 return "custom pos" 1309c = C() 1310)"); 1311 PyObjectPtr c(mainModuleGet("c")); 1312 PyObjectPtr result(PyNumber_Positive(c)); 1313 EXPECT_EQ(PyUnicode_CompareWithASCIIString(result, "custom pos"), 0); 1314} 1315 1316TEST_F(AbstractExtensionApiTest, PyNumberPositiveWithNullRaisesSystemError) { 1317 ASSERT_EQ(PyNumber_Positive(nullptr), nullptr); 1318 ASSERT_NE(PyErr_Occurred(), nullptr); 1319 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 1320} 1321 1322TEST_F(AbstractExtensionApiTest, PyNumberPositiveWithNonNumberRaisesTypeError) { 1323 ASSERT_EQ(PyNumber_Positive(Py_None), nullptr); 1324 ASSERT_NE(PyErr_Occurred(), nullptr); 1325 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1326} 1327 1328TEST_F(AbstractExtensionApiTest, PyNumberPositivePropagatesException) { 1329 PyRun_SimpleString(R"( 1330class C: 1331 def __pos__(self): 1332 raise UserWarning() 1333c = C() 1334)"); 1335 PyObjectPtr c(mainModuleGet("c")); 1336 PyObjectPtr result(PyNumber_Positive(c)); 1337 EXPECT_EQ(result, nullptr); 1338 ASSERT_NE(PyErr_Occurred(), nullptr); 1339 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_UserWarning)); 1340} 1341 1342TEST_F(AbstractExtensionApiTest, PyNumberPowerWithNonNumberRaisesTypeError) { 1343 PyObjectPtr x(PyUnicode_FromString("foo")); 1344 PyObjectPtr y(PyLong_FromLong(2)); 1345 ASSERT_EQ(PyNumber_Power(x, y, Py_None), nullptr); 1346 ASSERT_NE(PyErr_Occurred(), nullptr); 1347 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1348} 1349 1350TEST_F(AbstractExtensionApiTest, PyNumberPowerWithFloatReturnsFloat) { 1351 PyObjectPtr x(PyFloat_FromDouble(2.0)); 1352 PyObjectPtr y(PyLong_FromLong(3)); 1353 PyObjectPtr result(PyNumber_Power(x, y, Py_None)); 1354 ASSERT_TRUE(PyFloat_CheckExact(result)); 1355 EXPECT_EQ(PyFloat_AsDouble(result), 8.0); 1356} 1357 1358TEST_F(AbstractExtensionApiTest, PyNumberRemainderWithNonIntRaisesTypeError) { 1359 PyObjectPtr x(PyLong_FromLong(10)); 1360 ASSERT_EQ(PyNumber_Remainder(x, Py_None), nullptr); 1361 ASSERT_NE(PyErr_Occurred(), nullptr); 1362 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1363} 1364 1365TEST_F(AbstractExtensionApiTest, PyNumberRemainderWithIntsReturnsInt) { 1366 PyObjectPtr x(PyLong_FromLong(10)); 1367 PyObjectPtr y(PyLong_FromLong(3)); 1368 PyObjectPtr result(PyNumber_Remainder(x, y)); 1369 ASSERT_TRUE(PyLong_CheckExact(result)); 1370 EXPECT_EQ(PyLong_AsLong(result), 1); 1371} 1372 1373TEST_F(AbstractExtensionApiTest, PyNumberRshiftWithNonIntSelfRaisesTypeError) { 1374 PyObjectPtr x(PyFloat_FromDouble(5.0)); 1375 PyObjectPtr y(PyLong_FromLong(2)); 1376 ASSERT_EQ(PyNumber_Rshift(x, y), nullptr); 1377 ASSERT_NE(PyErr_Occurred(), nullptr); 1378 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1379} 1380 1381TEST_F(AbstractExtensionApiTest, PyNumberRshiftWithNonIntOtherRaisesTypeError) { 1382 PyObjectPtr x(PyLong_FromLong(5)); 1383 PyObjectPtr y(PyFloat_FromDouble(2.0)); 1384 ASSERT_EQ(PyNumber_Rshift(x, y), nullptr); 1385 ASSERT_NE(PyErr_Occurred(), nullptr); 1386 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1387} 1388 1389TEST_F(AbstractExtensionApiTest, PyNumberRshiftWithIntsShiftBitsRight) { 1390 PyObjectPtr x(PyLong_FromLong(0x4C)); 1391 PyObjectPtr y(PyLong_FromLong(2)); 1392 PyObjectPtr result(PyNumber_Rshift(x, y)); 1393 ASSERT_TRUE(PyLong_CheckExact(result)); 1394 EXPECT_EQ(PyLong_AsLong(result), 0x13); 1395} 1396 1397TEST_F(AbstractExtensionApiTest, 1398 PyNumberSubtractWithoutDunderSubtractRaisesTypeError) { 1399 PyObjectPtr x(PyUnicode_FromString("foo")); 1400 PyObjectPtr y(PyLong_FromLong(2)); 1401 ASSERT_EQ(PyNumber_Subtract(x, y), nullptr); 1402 ASSERT_NE(PyErr_Occurred(), nullptr); 1403 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1404} 1405 1406TEST_F(AbstractExtensionApiTest, PyNumberSubtractCallsDunderSub) { 1407 PyRun_SimpleString(R"( 1408class C: 1409 def __sub__(self, other): 1410 return other 1411c = C() 1412)"); 1413 PyObjectPtr c(mainModuleGet("c")); 1414 PyObjectPtr x(PyLong_FromLong(42)); 1415 PyObjectPtr result(PyNumber_Subtract(c, x)); 1416 ASSERT_TRUE(PyLong_CheckExact(result)); 1417 EXPECT_EQ(PyLong_AsLong(result), 42); 1418} 1419 1420TEST_F(AbstractExtensionApiTest, PyNumberSubtractWithFloatReturnsFloat) { 1421 PyObjectPtr x(PyLong_FromLong(10)); 1422 PyObjectPtr y(PyFloat_FromDouble(2.0)); 1423 PyObjectPtr result(PyNumber_Subtract(x, y)); 1424 ASSERT_TRUE(PyFloat_CheckExact(result)); 1425 EXPECT_EQ(PyFloat_AsDouble(result), 8.0); 1426 1427 PyObjectPtr result2(PyNumber_Subtract(y, x)); 1428 ASSERT_TRUE(PyFloat_CheckExact(result2)); 1429 EXPECT_EQ(PyFloat_AsDouble(result2), -8.0); 1430} 1431 1432TEST_F(AbstractExtensionApiTest, PyNumberSubtractWithIntsReturnsInt) { 1433 PyObjectPtr x(PyLong_FromLong(10)); 1434 PyObjectPtr y(PyLong_FromLong(2)); 1435 PyObjectPtr result(PyNumber_Subtract(x, y)); 1436 ASSERT_TRUE(PyLong_CheckExact(result)); 1437 EXPECT_EQ(PyLong_AsLong(result), 8); 1438} 1439 1440TEST_F(AbstractExtensionApiTest, PyNumberToBaseWithBinaryFormatsAsBinary) { 1441 PyObjectPtr x(PyLong_FromLong(10)); // 0b1010 1442 PyObjectPtr result(PyNumber_ToBase(x, 2)); 1443 EXPECT_EQ(PyErr_Occurred(), nullptr); 1444 EXPECT_EQ(PyUnicode_CompareWithASCIIString(result, "0b1010"), 0); 1445} 1446 1447TEST_F(AbstractExtensionApiTest, PyNumberToBaseWithOctalFormatsAsOctal) { 1448 PyObjectPtr x(PyLong_FromLong(520)); // 0o1010 1449 PyObjectPtr result(PyNumber_ToBase(x, 8)); 1450 EXPECT_EQ(PyErr_Occurred(), nullptr); 1451 EXPECT_EQ(PyUnicode_CompareWithASCIIString(result, "0o1010"), 0); 1452} 1453 1454TEST_F(AbstractExtensionApiTest, PyNumberToBaseWithDecimalFormatsAsDecimal) { 1455 PyObjectPtr x(PyLong_FromLong(12345)); 1456 PyObjectPtr result(PyNumber_ToBase(x, 10)); 1457 EXPECT_EQ(PyErr_Occurred(), nullptr); 1458 EXPECT_EQ(PyUnicode_CompareWithASCIIString(result, "12345"), 0); 1459} 1460 1461TEST_F(AbstractExtensionApiTest, PyNumberToBaseWithHexFormatsAsHex) { 1462 PyObjectPtr x(PyLong_FromLong(0xdeadbeef)); 1463 PyObjectPtr result(PyNumber_ToBase(x, 16)); 1464 EXPECT_EQ(PyErr_Occurred(), nullptr); 1465 EXPECT_EQ(PyUnicode_CompareWithASCIIString(result, "0xdeadbeef"), 0); 1466} 1467 1468TEST_F(AbstractExtensionApiTest, PyNumberToBaseSupportsIndex) { 1469 PyRun_SimpleString(R"( 1470class C: 1471 def __index__(self): 1472 return 42 1473c = C() 1474)"); 1475 PyObjectPtr c(mainModuleGet("c")); 1476 PyObjectPtr result(PyNumber_ToBase(c, 8)); 1477 EXPECT_EQ(PyErr_Occurred(), nullptr); 1478 EXPECT_EQ(PyUnicode_CompareWithASCIIString(result, "0o52"), 0); 1479} 1480 1481TEST_F(AbstractExtensionApiTest, PyNumberToBasePropagatesIndexException) { 1482 PyRun_SimpleString(R"( 1483class C: 1484 def __index__(self): 1485 raise ValueError 1486c = C() 1487)"); 1488 PyObjectPtr c(mainModuleGet("c")); 1489 PyObjectPtr result(PyNumber_ToBase(c, 8)); 1490 ASSERT_NE(PyErr_Occurred(), nullptr); 1491 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 1492 EXPECT_EQ(result, nullptr); 1493} 1494 1495TEST_F(AbstractExtensionApiTest, PyNumberToBaseSupportsIntSubclass) { 1496 PyRun_SimpleString(R"( 1497class C(int): 1498 pass 1499c = C(33) 1500)"); 1501 PyObjectPtr c(mainModuleGet("c")); 1502 PyObjectPtr result(PyNumber_ToBase(c, 16)); 1503 EXPECT_EQ(PyErr_Occurred(), nullptr); 1504 EXPECT_EQ(PyUnicode_CompareWithASCIIString(result, "0x21"), 0); 1505} 1506 1507TEST_F(AbstractExtensionApiTest, PyNumberToBaseWithInvalidBaseRaises) { 1508 PyObjectPtr x(PyLong_FromLong(0xdeadbeef)); 1509 PyObjectPtr result(PyNumber_ToBase(x, 15)); 1510 ASSERT_NE(PyErr_Occurred(), nullptr); 1511 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 1512 EXPECT_EQ(result, nullptr); 1513} 1514 1515TEST_F(AbstractExtensionApiTest, PyNumberTrueDivideWithNonIntRaisesTypeError) { 1516 PyObjectPtr x(PyUnicode_FromString("foo")); 1517 PyObjectPtr y(PyLong_FromLong(2)); 1518 ASSERT_EQ(PyNumber_TrueDivide(x, y), nullptr); 1519 ASSERT_NE(PyErr_Occurred(), nullptr); 1520 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1521} 1522 1523TEST_F(AbstractExtensionApiTest, PyNumberTrueDivideCallsDunderTruediv) { 1524 PyRun_SimpleString(R"( 1525class C: 1526 def __truediv__(self, other): 1527 return other 1528c = C() 1529)"); 1530 PyObjectPtr c(mainModuleGet("c")); 1531 PyObjectPtr x(PyLong_FromLong(42)); 1532 PyObjectPtr result(PyNumber_TrueDivide(c, x)); 1533 ASSERT_TRUE(PyLong_CheckExact(result)); 1534 EXPECT_EQ(PyLong_AsLong(result), 42); 1535} 1536 1537TEST_F(AbstractExtensionApiTest, PyNumberTrueDivideWithIntsReturnsFloat) { 1538 PyObjectPtr x(PyLong_FromLong(42)); 1539 PyObjectPtr y(PyLong_FromLong(5)); 1540 PyObjectPtr result(PyNumber_TrueDivide(x, y)); 1541 ASSERT_TRUE(PyFloat_CheckExact(result)); 1542 EXPECT_EQ(PyFloat_AsDouble(result), 8.4); 1543} 1544 1545TEST_F(AbstractExtensionApiTest, PyNumberTrueDivideWithFloatReturnsFloat) { 1546 PyObjectPtr a(PyFloat_FromDouble(42.0)); 1547 PyObjectPtr b(PyLong_FromLong(5)); 1548 PyObjectPtr result1(PyNumber_TrueDivide(a, b)); 1549 ASSERT_TRUE(PyFloat_CheckExact(result1)); 1550 EXPECT_EQ(PyFloat_AsDouble(result1), 8.4); 1551 1552 PyObjectPtr x(PyLong_FromLong(42)); 1553 PyObjectPtr y(PyFloat_FromDouble(5.0)); 1554 PyObjectPtr result2(PyNumber_TrueDivide(x, y)); 1555 ASSERT_TRUE(PyFloat_CheckExact(result2)); 1556 EXPECT_EQ(PyFloat_AsDouble(result2), 8.4); 1557} 1558 1559TEST_F(AbstractExtensionApiTest, PyNumberXorWithNonIntRaisesTypeError) { 1560 PyObjectPtr x(PyFloat_FromDouble(5.0)); 1561 PyObjectPtr y(PyLong_FromLong(3)); 1562 ASSERT_EQ(PyNumber_Xor(x, y), nullptr); 1563 ASSERT_NE(PyErr_Occurred(), nullptr); 1564 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1565} 1566 1567TEST_F(AbstractExtensionApiTest, PyNumberXorWithIntsReturnsBitwiseOr) { 1568 PyObjectPtr v(PyLong_FromLong(5)); // 0b0101 1569 PyObjectPtr w(PyLong_FromLong(3)); // 0b0011 1570 PyObjectPtr result(PyNumber_Xor(v, w)); 1571 ASSERT_TRUE(PyLong_CheckExact(result)); 1572 EXPECT_EQ(PyLong_AsLong(result), 6); // 0b0110 1573} 1574 1575// Object Protocol 1576 1577TEST_F(AbstractExtensionApiTest, PyObjectCallWithArgsCalls) { 1578 PyRun_SimpleString(R"( 1579def func(*args, **kwargs): 1580 return f"{args!r}{kwargs!r}" 1581)"); 1582 PyObjectPtr func(mainModuleGet("func")); 1583 PyObjectPtr tup0(PyUnicode_FromString("one")); 1584 PyObjectPtr tup1(PyLong_FromLong(2)); 1585 PyObjectPtr tup2(PyLong_FromLong(3)); 1586 PyObjectPtr args(PyTuple_Pack(3, tup0.get(), tup1.get(), tup2.get())); 1587 PyObjectPtr result(PyObject_Call(func, args, nullptr)); 1588 EXPECT_TRUE(isUnicodeEqualsCStr(result, "('one', 2, 3){}")); 1589} 1590 1591TEST_F(AbstractExtensionApiTest, PyObjectCallWithArgsAndKwargsCalls) { 1592 PyRun_SimpleString(R"( 1593def func(*args, **kwargs): 1594 return f"{args!r}{kwargs!r}" 1595)"); 1596 PyObjectPtr func(mainModuleGet("func")); 1597 PyObjectPtr tup0(PyLong_FromLong(1)); 1598 PyObjectPtr tup1(PyLong_FromLong(2)); 1599 PyObjectPtr tup2(PyUnicode_FromString("three")); 1600 PyObjectPtr args(PyTuple_Pack(3, tup0.get(), tup1.get(), tup2.get())); 1601 PyObjectPtr kwargs(PyDict_New()); 1602 PyObjectPtr kwarg_name(PyUnicode_FromString("kwarg")); 1603 PyObjectPtr kwarg_val(PyLong_FromLong(4)); 1604 PyDict_SetItem(kwargs, kwarg_name, kwarg_val); 1605 PyObjectPtr result(PyObject_Call(func, args, kwargs)); 1606 EXPECT_TRUE(isUnicodeEqualsCStr(result, "(1, 2, 'three'){'kwarg': 4}")); 1607} 1608 1609TEST_F(AbstractExtensionApiTest, PyObjectCallPropagatesException) { 1610 PyRun_SimpleString(R"( 1611def func(*args, **kwargs): 1612 raise UserWarning() 1613)"); 1614 PyObjectPtr func(mainModuleGet("func")); 1615 PyObjectPtr args(PyTuple_New(0)); 1616 PyObjectPtr result(PyObject_Call(func, args, nullptr)); 1617 EXPECT_EQ(result, nullptr); 1618 ASSERT_NE(PyErr_Occurred(), nullptr); 1619 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_UserWarning)); 1620} 1621 1622TEST_F(AbstractExtensionApiTest, PyObjectCallWithCallableOfNativeType) { 1623 ternaryfunc meth = [](PyObject*, PyObject*, PyObject*) { 1624 return PyUnicode_FromString("from_tp_call"); 1625 }; 1626 static const PyType_Slot slots[] = { 1627 {Py_tp_call, reinterpret_cast<void*>(meth)}, 1628 {0, nullptr}, 1629 }; 1630 static PyType_Spec spec = { 1631 "__main__.Bar", 1632 0, 1633 0, 1634 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 1635 const_cast<PyType_Slot*>(slots), 1636 }; 1637 PyObjectPtr type(PyType_FromSpec(&spec)); 1638 moduleSet("__main__", "Bar", type); 1639 1640 PyRun_SimpleString(R"( 1641b = Bar() 1642)"); 1643 1644 PyObjectPtr func(mainModuleGet("b")); 1645 PyObjectPtr args(PyTuple_New(0)); 1646 PyObjectPtr result(PyObject_Call(func, args, nullptr)); 1647 EXPECT_TRUE(isUnicodeEqualsCStr(result, "from_tp_call")); 1648} 1649 1650TEST_F(AbstractExtensionApiTest, PyObjectCallFunctionCalls) { 1651 PyRun_SimpleString(R"( 1652def func(*args): 1653 return f"{args!r}" 1654)"); 1655 PyObjectPtr func(mainModuleGet("func")); 1656 PyObjectPtr result( 1657 PyObject_CallFunction(func, "(iI)s#i", 3, 7, "aaaa", 3, 99)); 1658 EXPECT_TRUE(isUnicodeEqualsCStr(result, "((3, 7), 'aaa', 99)")); 1659} 1660 1661TEST_F(AbstractExtensionApiTest, PyObjectCallFunctionWithTypeAndTupleCalls) { 1662 PyObjectPtr result( 1663 PyObject_CallFunction(reinterpret_cast<PyObject*>(&PyList_Type), 1664 "((ss#i))", "bce", "aaaa", 3, 99)); 1665 EXPECT_TRUE(PyList_CheckExact(result)); 1666 EXPECT_EQ(PyList_Size(result), 3); 1667 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "bce")); 1668 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "aaa")); 1669 EXPECT_TRUE(isLongEqualsLong(PyList_GetItem(result, 2), 99)); 1670} 1671 1672TEST_F(AbstractExtensionApiTest, PyObjectCallFunctionWithTypeAndListCalls) { 1673 PyObjectPtr result( 1674 PyObject_CallFunction(reinterpret_cast<PyObject*>(&PyList_Type), "[ss#i]", 1675 "bce", "aaaa", 3, 99)); 1676 EXPECT_TRUE(PyList_CheckExact(result)); 1677 EXPECT_EQ(PyList_Size(result), 3); 1678 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "bce")); 1679 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "aaa")); 1680 EXPECT_TRUE(isLongEqualsLong(PyList_GetItem(result, 2), 99)); 1681} 1682 1683TEST_F(AbstractExtensionApiTest, 1684 PyObjectCallFunctionWithNonCallableRaisesTypeError) { 1685 PyObjectPtr result(PyObject_CallFunction(Py_None, nullptr)); 1686 EXPECT_EQ(result, nullptr); 1687 ASSERT_NE(PyErr_Occurred(), nullptr); 1688 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1689} 1690 1691TEST_F(AbstractExtensionApiTest, PyObjectCallFunctionPropagatesException) { 1692 PyRun_SimpleString(R"( 1693def func(): 1694 raise UserWarning() 1695)"); 1696 PyObjectPtr func(mainModuleGet("func")); 1697 PyObjectPtr result(PyObject_CallFunction(func, nullptr)); 1698 EXPECT_EQ(result, nullptr); 1699 ASSERT_NE(PyErr_Occurred(), nullptr); 1700 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_UserWarning)); 1701} 1702 1703TEST_F(AbstractExtensionApiTest, PyObjectCallFunctionSizeTCalls) { 1704 PyRun_SimpleString(R"( 1705def func(*args): 1706 return f"{args!r}" 1707)"); 1708 PyObjectPtr func(mainModuleGet("func")); 1709 PyObjectPtr result( 1710 PyObject_CallFunction(func, "is#i", 7, "bbb", Py_ssize_t{2}, 14)); 1711 EXPECT_TRUE(isUnicodeEqualsCStr(result, "(7, 'bb', 14)")); 1712} 1713 1714TEST_F(AbstractExtensionApiTest, PyObjectCallMethodWithEmptyTuplePassesNoArgs) { 1715 PyRun_SimpleString(R"( 1716class C: 1717 def func(self, *arg): 1718 return f"{self.__class__.__name__} {arg}" 1719instance = C() 1720)"); 1721 PyObjectPtr instance(mainModuleGet("instance")); 1722 PyObjectPtr result(PyObject_CallMethod(instance, "func", "()")); 1723 EXPECT_TRUE(isUnicodeEqualsCStr(result, "C ()")); 1724} 1725 1726TEST_F(AbstractExtensionApiTest, PyObjectCallMethodWithIntTuplePassesTwoInts) { 1727 PyRun_SimpleString(R"( 1728class C: 1729 def func(self, *arg): 1730 return f"{self.__class__.__name__} {arg}" 1731instance = C() 1732)"); 1733 PyObjectPtr instance(mainModuleGet("instance")); 1734 PyObjectPtr result(PyObject_CallMethod(instance, "func", "(ii)", 5, 10)); 1735 EXPECT_TRUE(isUnicodeEqualsCStr(result, "C (5, 10)")); 1736} 1737 1738TEST_F(AbstractExtensionApiTest, 1739 PyObjectCallMethodWithTupleAndIntPassesTwoArgs) { 1740 PyRun_SimpleString(R"( 1741class C: 1742 def func(self, *arg): 1743 return f"{self.__class__.__name__} {arg}" 1744instance = C() 1745)"); 1746 PyObjectPtr instance(mainModuleGet("instance")); 1747 PyObjectPtr result(PyObject_CallMethod(instance, "func", "()i", 10)); 1748 EXPECT_TRUE(isUnicodeEqualsCStr(result, "C ((), 10)")); 1749} 1750 1751TEST_F(AbstractExtensionApiTest, PyObjectCallMethodCalls) { 1752 PyRun_SimpleString(R"( 1753class C: 1754 x = 42 1755 def func(self, *args): 1756 return f"{self.x}{args!r}" 1757c = C() 1758)"); 1759 PyObjectPtr c(mainModuleGet("c")); 1760 PyObjectPtr result(PyObject_CallMethod(c, "func", "s#(i)", "ccc", 1, 7)); 1761 EXPECT_TRUE(isUnicodeEqualsCStr(result, "42('c', (7,))")); 1762} 1763 1764TEST_F(AbstractExtensionApiTest, 1765 PyObjectCallMethodWithNonExistentMemberRaisesAttributeError) { 1766 PyObjectPtr result(PyObject_CallMethod(Py_None, "foo", nullptr)); 1767 EXPECT_EQ(result, nullptr); 1768 ASSERT_NE(PyErr_Occurred(), nullptr); 1769 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_AttributeError)); 1770} 1771 1772TEST_F(AbstractExtensionApiTest, PyObjectCallMethodPropagatesException) { 1773 PyRun_SimpleString(R"( 1774class C: 1775 def func(self): 1776 raise UserWarning() 1777c = C() 1778)"); 1779 PyObjectPtr c(mainModuleGet("c")); 1780 PyObjectPtr result(PyObject_CallMethod(c, "func", nullptr)); 1781 EXPECT_EQ(result, nullptr); 1782 ASSERT_NE(PyErr_Occurred(), nullptr); 1783 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_UserWarning)); 1784} 1785 1786TEST_F(AbstractExtensionApiTest, PyObjectCallMethodObjArgsCalls) { 1787 PyRun_SimpleString(R"( 1788class C: 1789 x = 23 1790 def func(self, *args): 1791 return f"{self.x}{args!r}" 1792c = C() 1793)"); 1794 PyObjectPtr c(mainModuleGet("c")); 1795 PyObjectPtr name(PyUnicode_FromString("func")); 1796 PyObjectPtr arg0(PyLong_FromLong(-13)); 1797 PyObjectPtr arg1(PyUnicode_FromString("zzz")); 1798 PyObjectPtr result( 1799 PyObject_CallMethodObjArgs(c, name, arg0.get(), arg1.get(), nullptr)); 1800 EXPECT_TRUE(isUnicodeEqualsCStr(result, "23(-13, 'zzz')")); 1801} 1802 1803TEST_F(AbstractExtensionApiTest, 1804 PyObjectCallMethodObjArgsWithNullObjectRaisesSystemError) { 1805 PyObjectPtr name(PyUnicode_FromString("func")); 1806 PyObjectPtr result(PyObject_CallMethodObjArgs(nullptr, name)); 1807 ASSERT_EQ(result, nullptr); 1808 ASSERT_NE(PyErr_Occurred(), nullptr); 1809 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 1810} 1811 1812TEST_F(AbstractExtensionApiTest, 1813 PyObjectCallMethodObjArgsWithNullMethodNameRaisesSystemError) { 1814 PyObjectPtr result(PyObject_CallMethodObjArgs(Py_None, nullptr)); 1815 ASSERT_EQ(result, nullptr); 1816 ASSERT_NE(PyErr_Occurred(), nullptr); 1817 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 1818} 1819 1820TEST_F(AbstractExtensionApiTest, PyObjectCallMethodSizeTCalls) { 1821 PyRun_SimpleString(R"( 1822class C: 1823 x = -5 1824 def func(self, *args): 1825 return f"{self.x}{args!r}" 1826c = C() 1827)"); 1828 PyObjectPtr c(mainModuleGet("c")); 1829 PyObjectPtr result(_PyObject_CallMethod_SizeT(c, "func", "is#i", 9, "ddd", 1830 Py_ssize_t{2}, 8)); 1831 EXPECT_TRUE(isUnicodeEqualsCStr(result, "-5(9, 'dd', 8)")); 1832} 1833 1834TEST_F(AbstractExtensionApiTest, PyObjectCallObjectCalls) { 1835 PyRun_SimpleString(R"( 1836class C: 1837 x = 9 1838 def __call__(self, *args): 1839 return f"{self.x}{args!r}" 1840c = C() 1841)"); 1842 PyObjectPtr c(mainModuleGet("c")); 1843 PyObjectPtr one(PyLong_FromLong(1)); 1844 PyObjectPtr two(PyUnicode_FromString("two")); 1845 PyObjectPtr three(PyLong_FromLong(3)); 1846 PyObjectPtr args(PyTuple_Pack(3, one.get(), two.get(), three.get())); 1847 PyObjectPtr result(PyObject_CallObject(c, args)); 1848 EXPECT_TRUE(isUnicodeEqualsCStr(result, "9(1, 'two', 3)")); 1849} 1850 1851TEST_F(AbstractExtensionApiTest, PyObjectCallObjectWithArgsNullptrCalls) { 1852 PyRun_SimpleString(R"( 1853def func(*args, **kwargs): 1854 return f"{args!r}{kwargs!r}" 1855)"); 1856 PyObjectPtr func(mainModuleGet("func")); 1857 PyObjectPtr result(PyObject_CallObject(func, nullptr)); 1858 EXPECT_TRUE(isUnicodeEqualsCStr(result, "(){}")); 1859} 1860 1861TEST_F(AbstractExtensionApiTest, PyObjCallFunctionObjArgsWithNullReturnsNull) { 1862 testing::PyObjectPtr test(PyObject_CallFunctionObjArgs(nullptr, nullptr)); 1863 EXPECT_EQ(nullptr, test); 1864 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 1865} 1866 1867TEST_F(AbstractExtensionApiTest, 1868 PyObjCallFunctionObjArgsWithNonFunctionReturnsNull) { 1869 testing::PyObjectPtr non_func(PyTuple_New(0)); 1870 testing::PyObjectPtr test(PyObject_CallFunctionObjArgs(non_func, nullptr)); 1871 EXPECT_EQ(test, nullptr); 1872 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 1873} 1874 1875TEST_F(AbstractExtensionApiTest, PyObjectGetBufferWithBytesReturnsBuffer) { 1876 Py_buffer buffer; 1877 PyObjectPtr bytes(PyBytes_FromStringAndSize("hello\0world", 11)); 1878 Py_ssize_t old_refcnt = Py_REFCNT(bytes); 1879 int result = PyObject_GetBuffer(bytes, &buffer, 0); 1880 EXPECT_EQ(Py_REFCNT(bytes), old_refcnt + 1); 1881 ASSERT_EQ(buffer.len, 11); 1882 EXPECT_EQ(std::memcmp(buffer.buf, "hello\0world", 11), 0); 1883 ASSERT_EQ(result, 0); 1884 PyBuffer_Release(&buffer); 1885 EXPECT_EQ(PyErr_Occurred(), nullptr); 1886 EXPECT_EQ(buffer.obj, nullptr); 1887 EXPECT_EQ(Py_REFCNT(bytes), old_refcnt); 1888} 1889 1890TEST_F(AbstractExtensionApiTest, PyObjectGetBufferWithByteArrayReturnsBuffer) { 1891 Py_buffer buffer; 1892 PyObjectPtr bytearray(PyByteArray_FromStringAndSize("hello\0world", 11)); 1893 Py_ssize_t old_refcnt = Py_REFCNT(bytearray); 1894 int result = PyObject_GetBuffer(bytearray, &buffer, 0); 1895 EXPECT_EQ(Py_REFCNT(bytearray), old_refcnt + 1); 1896 ASSERT_EQ(buffer.len, 11); 1897 EXPECT_EQ(std::memcmp(buffer.buf, "hello\0world", 11), 0); 1898 ASSERT_EQ(result, 0); 1899 PyBuffer_Release(&buffer); 1900 EXPECT_EQ(PyErr_Occurred(), nullptr); 1901 EXPECT_EQ(buffer.obj, nullptr); 1902 EXPECT_EQ(Py_REFCNT(bytearray), old_refcnt); 1903} 1904 1905TEST_F(AbstractExtensionApiTest, 1906 PyObjectGetBufferWithBufferProtocolObjectReturnsBuffer) { 1907 static char contents[] = "hello world"; 1908 static Py_ssize_t contents_len = std::strlen(contents); 1909 getbufferproc getbuffer_func = [](PyObject* obj, Py_buffer* view, int flags) { 1910 return PyBuffer_FillInfo(view, obj, strdup(contents), contents_len, 1911 /*readonly=*/1, flags); 1912 }; 1913 releasebufferproc releasebuffer_func = [](PyObject*, Py_buffer* view) { 1914 std::free(view->buf); 1915 view->obj = nullptr; 1916 }; 1917 PyType_Slot slots[] = { 1918 {Py_bf_getbuffer, reinterpret_cast<void*>(getbuffer_func)}, 1919 {Py_bf_releasebuffer, reinterpret_cast<void*>(releasebuffer_func)}, 1920 {0, nullptr}, 1921 }; 1922 static PyType_Spec spec; 1923 spec = { 1924 "foo.Bar", 0, 0, Py_TPFLAGS_DEFAULT, slots, 1925 }; 1926 PyObjectPtr type(PyType_FromSpec(&spec)); 1927 PyObjectPtr instance(PyObject_CallFunction(type, nullptr)); 1928 1929 Py_buffer buffer; 1930 Py_ssize_t old_refcnt = Py_REFCNT(instance); 1931 int result = PyObject_GetBuffer(instance, &buffer, 0); 1932 EXPECT_EQ(Py_REFCNT(instance), old_refcnt + 1); 1933 ASSERT_EQ(buffer.len, contents_len); 1934 EXPECT_NE(buffer.buf, contents); 1935 EXPECT_EQ(std::memcmp(buffer.buf, contents, contents_len), 0); 1936 ASSERT_EQ(result, 0); 1937 PyBuffer_Release(&buffer); 1938 EXPECT_EQ(PyErr_Occurred(), nullptr); 1939 EXPECT_EQ(buffer.obj, nullptr); 1940 EXPECT_EQ(Py_REFCNT(instance), old_refcnt); 1941} 1942 1943TEST_F(AbstractExtensionApiTest, 1944 PyObjectGetBufferWithBytesMemoryViewReturnsBuffer) { 1945 Py_buffer buffer; 1946 PyObjectPtr bytes(PyBytes_FromStringAndSize("hello\0world", 11)); 1947 PyObjectPtr memoryview(PyMemoryView_FromObject(bytes)); 1948 Py_ssize_t old_memoryview_refcnt = Py_REFCNT(memoryview); 1949 Py_ssize_t old_bytes_refcnt = Py_REFCNT(bytes); 1950 1951 ASSERT_EQ(PyObject_GetBuffer(memoryview, &buffer, 0), 0); 1952 1953 // Getting the underlying buffer increments references to the underlying 1954 // buffer, not the memoryview object itself. 1955 EXPECT_EQ(Py_REFCNT(memoryview), old_memoryview_refcnt + 1); 1956 EXPECT_EQ(Py_REFCNT(bytes), old_bytes_refcnt); 1957 ASSERT_EQ(buffer.len, 11); 1958 EXPECT_EQ(std::memcmp(buffer.buf, "hello\0world", 11), 0); 1959 1960 PyBuffer_Release(&buffer); 1961 EXPECT_EQ(PyErr_Occurred(), nullptr); 1962 EXPECT_EQ(buffer.obj, nullptr); 1963 EXPECT_EQ(Py_REFCNT(memoryview), old_memoryview_refcnt); 1964 EXPECT_EQ(Py_REFCNT(bytes), old_bytes_refcnt); 1965} 1966 1967TEST_F(AbstractExtensionApiTest, 1968 PyObjectGetBufferWithBytearrayMemoryViewReturnsBuffer) { 1969 Py_buffer buffer; 1970 PyObjectPtr bytearray(PyByteArray_FromStringAndSize("hello\0world", 11)); 1971 PyObjectPtr memoryview_unsliced(PyMemoryView_FromObject(bytearray)); 1972 PyObjectPtr memoryview(PySequence_GetSlice(memoryview_unsliced, 0, 10)); 1973 Py_ssize_t old_memoryview_refcnt = Py_REFCNT(memoryview); 1974 Py_ssize_t old_bytearray_refcnt = Py_REFCNT(bytearray); 1975 1976 ASSERT_EQ(PyObject_GetBuffer(memoryview, &buffer, 0), 0); 1977 1978 EXPECT_EQ(Py_REFCNT(memoryview), old_memoryview_refcnt + 1); 1979 EXPECT_EQ(Py_REFCNT(bytearray), old_bytearray_refcnt); 1980 ASSERT_EQ(buffer.len, 10); 1981 EXPECT_EQ(std::memcmp(buffer.buf, "hello\0worl", 10), 0); 1982 1983 PyBuffer_Release(&buffer); 1984 EXPECT_EQ(PyErr_Occurred(), nullptr); 1985 EXPECT_EQ(buffer.obj, nullptr); 1986 EXPECT_EQ(Py_REFCNT(memoryview), old_memoryview_refcnt); 1987 EXPECT_EQ(Py_REFCNT(bytearray), old_bytearray_refcnt); 1988} 1989 1990TEST_F(AbstractExtensionApiTest, 1991 PyObjectGetBufferWithFromMemoryMemoryViewReturnsBuffer) { 1992 char memory[6] = "hello"; 1993 PyObjectPtr memoryview( 1994 PyMemoryView_FromMemory(reinterpret_cast<char*>(memory), 6, PyBUF_READ)); 1995 Py_ssize_t old_memoryview_refcnt = Py_REFCNT(memoryview); 1996 Py_buffer buffer; 1997 EXPECT_EQ(PyObject_GetBuffer(memoryview, &buffer, 0), 0); 1998 1999 EXPECT_EQ(Py_REFCNT(memoryview), old_memoryview_refcnt + 1); 2000 ASSERT_EQ(buffer.len, 6); 2001 EXPECT_EQ(std::memcmp(buffer.buf, "hello", 6), 0); 2002 2003 PyBuffer_Release(&buffer); 2004 EXPECT_EQ(PyErr_Occurred(), nullptr); 2005 EXPECT_EQ(buffer.obj, nullptr); 2006 EXPECT_EQ(Py_REFCNT(memoryview), old_memoryview_refcnt); 2007} 2008 2009TEST_F(AbstractExtensionApiTest, 2010 PyObjectGetBufferWithByteFormattedArrayReturnsBuffer) { 2011 PyRun_SimpleString(R"( 2012import array 2013result = array.array('b', b'hello') 2014)"); 2015 PyObjectPtr array(mainModuleGet("result")); 2016 Py_ssize_t old_array_refcnt = Py_REFCNT(array); 2017 2018 Py_buffer buffer; 2019 EXPECT_EQ(PyObject_GetBuffer(array, &buffer, 0), 0); 2020 2021 EXPECT_EQ(Py_REFCNT(array), old_array_refcnt + 1); 2022 ASSERT_EQ(buffer.len, 5); 2023 EXPECT_EQ(std::memcmp(buffer.buf, "hello", 5), 0); 2024 2025 PyBuffer_Release(&buffer); 2026 EXPECT_EQ(buffer.obj, nullptr); 2027 EXPECT_EQ(Py_REFCNT(array), old_array_refcnt); 2028} 2029 2030TEST_F(AbstractExtensionApiTest, PyObjectGetBufferWithQuadArrayReturnsBuffer) { 2031 PyRun_SimpleString(R"( 2032import array 2033result = array.array('Q') 2034result.append(0xdeadbeef12345678) 2035)"); 2036 PyObjectPtr array(mainModuleGet("result")); 2037 Py_ssize_t old_array_refcnt = Py_REFCNT(array); 2038 2039 Py_buffer buffer; 2040 EXPECT_EQ(PyObject_GetBuffer(array, &buffer, 0), 0); 2041 2042 EXPECT_EQ(Py_REFCNT(array), old_array_refcnt + 1); 2043 char* underlying_buffer = reinterpret_cast<char*>(buffer.buf); 2044 ASSERT_EQ(buffer.len, 8); 2045 EXPECT_EQ(underlying_buffer[0], '\x78'); 2046 EXPECT_EQ(underlying_buffer[1], '\x56'); 2047 EXPECT_EQ(underlying_buffer[2], '\x34'); 2048 EXPECT_EQ(underlying_buffer[3], '\x12'); 2049 EXPECT_EQ(underlying_buffer[4], '\xef'); 2050 EXPECT_EQ(underlying_buffer[5], '\xbe'); 2051 EXPECT_EQ(underlying_buffer[6], '\xad'); 2052 EXPECT_EQ(underlying_buffer[7], '\xde'); 2053 2054 PyBuffer_Release(&buffer); 2055 EXPECT_EQ(buffer.obj, nullptr); 2056 EXPECT_EQ(Py_REFCNT(array), old_array_refcnt); 2057} 2058 2059TEST_F(AbstractExtensionApiTest, 2060 PyObjectGetBufferWithNonBufferExtensionObjectRaisesTypeError) { 2061 PyType_Slot slots[] = { 2062 {0, nullptr}, 2063 }; 2064 static PyType_Spec spec; 2065 spec = { 2066 "foo.Bar", 0, 0, Py_TPFLAGS_DEFAULT, slots, 2067 }; 2068 PyObjectPtr type(PyType_FromSpec(&spec)); 2069 PyObjectPtr instance(PyObject_CallFunction(type, nullptr)); 2070 Py_buffer buffer; 2071 EXPECT_EQ(PyObject_GetBuffer(instance, &buffer, 0), -1); 2072 EXPECT_NE(PyErr_Occurred(), nullptr); 2073 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2074} 2075 2076TEST_F(AbstractExtensionApiTest, 2077 PyObjectGetBufferWithNonBufferManagedObjectRaisesTypeError) { 2078 PyRun_SimpleString(R"( 2079class C: 2080 pass 2081instance = C() 2082)"); 2083 Py_buffer buffer; 2084 PyObjectPtr instance(mainModuleGet("instance")); 2085 EXPECT_EQ(PyObject_GetBuffer(instance, &buffer, 0), -1); 2086 EXPECT_NE(PyErr_Occurred(), nullptr); 2087 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2088} 2089 2090TEST_F(AbstractExtensionApiTest, 2091 PyObjectGetBufferWithNonBufferBuiltinTypeRaisesTypeError) { 2092 Py_buffer buffer; 2093 PyObjectPtr instance(PyLong_FromLong(42)); 2094 EXPECT_EQ(PyObject_GetBuffer(instance, &buffer, 0), -1); 2095 EXPECT_NE(PyErr_Occurred(), nullptr); 2096 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2097} 2098 2099TEST_F(AbstractExtensionApiTest, CallFunctionObjArgsWithNoArgsReturnsValue) { 2100 PyRun_SimpleString(R"( 2101def func(): 2102 return 5 2103 )"); 2104 2105 testing::PyObjectPtr func(testing::mainModuleGet("func")); 2106 testing::PyObjectPtr func_result(PyObject_CallFunctionObjArgs(func, nullptr)); 2107 EXPECT_EQ(PyLong_AsLong(func_result), 5); 2108 EXPECT_EQ(PyErr_Occurred(), nullptr); 2109} 2110 2111TEST_F(AbstractExtensionApiTest, 2112 CallFunctionObjArgsWithCallableClassReturnsValue) { 2113 PyRun_SimpleString(R"( 2114class Foo(): 2115 def __call__(self): 2116 return 5 2117f = Foo() 2118 )"); 2119 2120 testing::PyObjectPtr f(testing::mainModuleGet("f")); 2121 testing::PyObjectPtr f_result(PyObject_CallFunctionObjArgs(f, nullptr)); 2122 EXPECT_EQ(PyLong_AsLong(f_result), 5); 2123 EXPECT_EQ(PyErr_Occurred(), nullptr); 2124} 2125 2126TEST_F(AbstractExtensionApiTest, 2127 CallFunctionObjArgsWithManyArgumentsReturnsValue) { 2128 PyRun_SimpleString(R"( 2129def func(a, b, c, d, e, f): 2130 return a + b + c + d + e + f 2131 )"); 2132 2133 testing::PyObjectPtr func(testing::mainModuleGet("func")); 2134 PyObject* one = PyLong_FromLong(1); 2135 PyObject* two = PyLong_FromLong(2); 2136 testing::PyObjectPtr func_result(PyObject_CallFunctionObjArgs( 2137 func, one, one, two, two, one, two, nullptr)); 2138 Py_DECREF(one); 2139 Py_DECREF(two); 2140 EXPECT_EQ(PyLong_AsLong(func_result), 9); 2141 EXPECT_EQ(PyErr_Occurred(), nullptr); 2142} 2143 2144TEST_F(AbstractExtensionApiTest, PyObjectCheckBufferWithBytesReturnsTrue) { 2145 PyObjectPtr obj(PyBytes_FromString("foo")); 2146 EXPECT_TRUE(PyObject_CheckBuffer(obj.get())); 2147} 2148 2149TEST_F(AbstractExtensionApiTest, PyObjectCheckBufferWithBytearrayReturnsTrue) { 2150 PyObjectPtr obj(PyByteArray_FromStringAndSize("foo", 3)); 2151 EXPECT_TRUE(PyObject_CheckBuffer(obj.get())); 2152} 2153 2154TEST_F(AbstractExtensionApiTest, 2155 PyObjectCheckBufferWithBufferObjectReturnsTrue) { 2156 static char contents[] = "hello world"; 2157 static Py_ssize_t contents_len = std::strlen(contents); 2158 getbufferproc getbuffer_func = [](PyObject* obj, Py_buffer* view, int flags) { 2159 return PyBuffer_FillInfo(view, obj, strdup(contents), contents_len, 2160 /*readonly=*/1, flags); 2161 }; 2162 releasebufferproc releasebuffer_func = [](PyObject*, Py_buffer* view) { 2163 std::free(view->buf); 2164 view->obj = nullptr; 2165 }; 2166 PyType_Slot slots[] = { 2167 {Py_bf_getbuffer, reinterpret_cast<void*>(getbuffer_func)}, 2168 {Py_bf_releasebuffer, reinterpret_cast<void*>(releasebuffer_func)}, 2169 {0, nullptr}, 2170 }; 2171 static PyType_Spec spec; 2172 spec = { 2173 "foo.Bar", 0, 0, Py_TPFLAGS_DEFAULT, slots, 2174 }; 2175 PyObjectPtr type(PyType_FromSpec(&spec)); 2176 PyObjectPtr obj(PyObject_CallFunction(type, nullptr)); 2177 EXPECT_TRUE(PyObject_CheckBuffer(obj.get())); 2178} 2179 2180TEST_F(AbstractExtensionApiTest, 2181 PyObjectCheckBufferWithNonByteslikeReturnsFalse) { 2182 PyObjectPtr obj(PyLong_FromLong(2)); 2183 EXPECT_FALSE(PyObject_CheckBuffer(obj.get())); 2184} 2185 2186TEST_F(AbstractExtensionApiTest, 2187 PyObjectFastCallDictWithPositionalsAndKeywordArgsCalls) { 2188 PyRun_SimpleString(R"( 2189def func(*args, **kwargs): 2190 return f"{args!r}{kwargs!r}" 2191)"); 2192 PyObjectPtr func(mainModuleGet("func")); 2193 PyObject* args[] = { 2194 PyLong_FromLong(3), 2195 PyUnicode_FromString("lll"), 2196 PyLong_FromLong(2), 2197 }; 2198 size_t n_args = Py_ARRAY_LENGTH(args); 2199 PyObjectPtr kwargs(PyDict_New()); 2200 PyObjectPtr kwarg_name(PyUnicode_FromString("kwarg")); 2201 PyObjectPtr kwarg_value(PyLong_FromLong(7)); 2202 PyDict_SetItem(kwargs, kwarg_name, kwarg_value); 2203 PyObjectPtr result(_PyObject_FastCallDict(func, args, n_args, kwargs)); 2204 EXPECT_TRUE(isUnicodeEqualsCStr(result, "(3, 'lll', 2){'kwarg': 7}")); 2205 for (size_t i = 0; i < n_args; i++) { 2206 Py_DECREF(args[i]); 2207 } 2208} 2209 2210TEST_F(AbstractExtensionApiTest, PyObjectFastCallDictWithNoArgsCalls) { 2211 PyRun_SimpleString(R"( 2212def func(*args, **kwargs): 2213 return f"{args!r}{kwargs!r}" 2214)"); 2215 PyObjectPtr func(mainModuleGet("func")); 2216 PyObjectPtr result(_PyObject_FastCallDict(func, nullptr, 0, nullptr)); 2217 EXPECT_TRUE(isUnicodeEqualsCStr(result, "(){}")); 2218} 2219 2220TEST_F(AbstractExtensionApiTest, PyObjectFastCallDictWithoutKeywordArgsCalls) { 2221 PyRun_SimpleString(R"( 2222def func(*args, **kwargs): 2223 return f"{args!r}{kwargs!r}" 2224)"); 2225 PyObjectPtr func(mainModuleGet("func")); 2226 PyObject* args[] = { 2227 PyLong_FromLong(7), 2228 PyUnicode_FromString("xxx"), 2229 PyLong_FromLong(16), 2230 }; 2231 size_t n_args = Py_ARRAY_LENGTH(args); 2232 PyObjectPtr result(_PyObject_FastCallDict(func, args, n_args, nullptr)); 2233 EXPECT_TRUE(isUnicodeEqualsCStr(result, "(7, 'xxx', 16){}")); 2234 for (size_t i = 0; i < n_args; i++) { 2235 Py_DECREF(args[i]); 2236 } 2237} 2238 2239TEST_F(AbstractExtensionApiTest, 2240 PyObjectFastCallDictWithZeroPositionalsAndKeywordArgsCalls) { 2241 PyRun_SimpleString(R"( 2242def func(*args, **kwargs): 2243 return f"{args!r}{kwargs!r}" 2244)"); 2245 PyObjectPtr func(mainModuleGet("func")); 2246 PyObjectPtr kwargs(PyDict_New()); 2247 PyObjectPtr kwarg_name(PyUnicode_FromString("kwarg")); 2248 PyObjectPtr kwarg_value(PyLong_FromLong(2)); 2249 PyDict_SetItem(kwargs, kwarg_name, kwarg_value); 2250 PyObjectPtr result(_PyObject_FastCallDict(func, nullptr, 0, kwargs)); 2251 EXPECT_TRUE(isUnicodeEqualsCStr(result, "(){'kwarg': 2}")); 2252} 2253 2254TEST_F(AbstractExtensionApiTest, 2255 PyObjectFastCallDictWithPositionalsAndKeywordArgsPropagatesException) { 2256 PyRun_SimpleString(R"( 2257def func(*args, **kwargs): 2258 raise UserWarning() 2259)"); 2260 PyObjectPtr func(mainModuleGet("func")); 2261 PyObject* args[] = { 2262 PyLong_FromLong(8), 2263 }; 2264 size_t n_args = Py_ARRAY_LENGTH(args); 2265 PyObjectPtr kwargs(PyDict_New()); 2266 PyObjectPtr kwarg_name(PyUnicode_FromString("kwarg")); 2267 PyObjectPtr kwarg_value(PyLong_FromLong(7)); 2268 PyDict_SetItem(kwargs, kwarg_name, kwarg_value); 2269 PyObjectPtr result(_PyObject_FastCallDict(func, args, n_args, kwargs)); 2270 for (size_t i = 0; i < n_args; i++) { 2271 Py_DECREF(args[i]); 2272 } 2273 ASSERT_EQ(result, nullptr); 2274 ASSERT_NE(PyErr_Occurred(), nullptr); 2275 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_UserWarning)); 2276} 2277 2278TEST_F(AbstractExtensionApiTest, 2279 PyObjectFastCallDictWithoutKeywordArgsPropagatesException) { 2280 PyRun_SimpleString(R"( 2281def func(*args, **kwargs): 2282 raise UserWarning() 2283)"); 2284 PyObjectPtr func(mainModuleGet("func")); 2285 PyObject* args[] = { 2286 PyUnicode_FromString(""), 2287 }; 2288 size_t n_args = Py_ARRAY_LENGTH(args); 2289 PyObjectPtr result(_PyObject_FastCallDict(func, args, n_args, nullptr)); 2290 for (size_t i = 0; i < n_args; i++) { 2291 Py_DECREF(args[i]); 2292 } 2293 ASSERT_EQ(result, nullptr); 2294 ASSERT_NE(PyErr_Occurred(), nullptr); 2295 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_UserWarning)); 2296} 2297 2298TEST_F(AbstractExtensionApiTest, GetIterWithNoDunderIterRaises) { 2299 PyRun_SimpleString(R"( 2300class C: 2301 pass 2302c = C() 2303)"); 2304 PyObjectPtr c(mainModuleGet("c")); 2305 ASSERT_EQ(PyObject_GetIter(c), nullptr); 2306 ASSERT_NE(PyErr_Occurred(), nullptr); 2307 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2308} 2309 2310TEST_F(AbstractExtensionApiTest, GetIterWithNonCallableDunderIterRaises) { 2311 PyRun_SimpleString(R"( 2312class C: 2313 __iter__ = 4 2314c = C() 2315)"); 2316 PyObjectPtr c(mainModuleGet("c")); 2317 ASSERT_EQ(PyObject_GetIter(c), nullptr); 2318 ASSERT_NE(PyErr_Occurred(), nullptr); 2319 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2320} 2321 2322TEST_F(AbstractExtensionApiTest, GetIterWithDunderIterReturningNonIterRaises) { 2323 PyRun_SimpleString(R"( 2324class C: 2325 def __iter__(self): 2326 return 4 2327c = C() 2328)"); 2329 PyObjectPtr c(mainModuleGet("c")); 2330 ASSERT_EQ(PyObject_GetIter(c), nullptr); 2331 ASSERT_NE(PyErr_Occurred(), nullptr); 2332 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2333} 2334 2335TEST_F(AbstractExtensionApiTest, GetIterPropagatesException) { 2336 PyRun_SimpleString(R"( 2337class C: 2338 def __iter__(self): 2339 raise ValueError("hi") 2340c = C() 2341)"); 2342 PyObjectPtr c(mainModuleGet("c")); 2343 ASSERT_EQ(PyObject_GetIter(c), nullptr); 2344 ASSERT_NE(PyErr_Occurred(), nullptr); 2345 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 2346} 2347 2348TEST_F(AbstractExtensionApiTest, PyObjectIsInstanceWithNonTypeRaisesTypeError) { 2349 PyObjectPtr obj(PyLong_FromLong(1)); 2350 PyObjectPtr cls(PyList_New(0)); 2351 EXPECT_EQ(PyObject_IsInstance(obj, cls), -1); 2352 ASSERT_NE(PyErr_Occurred(), nullptr); 2353 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2354} 2355 2356TEST_F(AbstractExtensionApiTest, PyObjectIsInstanceWithTypeReturnsTrue) { 2357 PyObjectPtr obj(PyList_New(0)); 2358 PyObjectPtr cls(PyObject_Type(obj)); 2359 EXPECT_EQ(PyObject_IsInstance(obj, cls), 1); 2360 EXPECT_EQ(PyErr_Occurred(), nullptr); 2361} 2362 2363TEST_F(AbstractExtensionApiTest, PyObjectIsInstanceWithSupertypeReturnsTrue) { 2364 PyObjectPtr obj(PyLong_FromLong(0)); 2365 PyObjectPtr cls(PyObject_Type(obj)); 2366 EXPECT_EQ(PyObject_IsInstance(Py_True, cls), 1); 2367 EXPECT_EQ(PyErr_Occurred(), nullptr); 2368} 2369 2370TEST_F(AbstractExtensionApiTest, PyObjectIsInstanceWithSubtypeReturnsFalse) { 2371 PyObjectPtr obj(PyLong_FromLong(0)); 2372 PyObjectPtr cls(PyObject_Type(Py_True)); 2373 EXPECT_EQ(PyObject_IsInstance(obj, cls), 0); 2374 EXPECT_EQ(PyErr_Occurred(), nullptr); 2375} 2376 2377TEST_F(AbstractExtensionApiTest, PyObjectIsInstanceWithTupleChecksTypes) { 2378 PyObjectPtr obj1(PyList_New(0)); 2379 PyObjectPtr obj2(PyLong_FromLong(10)); 2380 PyObjectPtr cls(PyTuple_New(3)); 2381 PyTuple_SetItem(cls, 0, PyObject_Type(obj1)); 2382 PyTuple_SetItem(cls, 1, PyObject_Type(obj2)); 2383 PyTuple_SetItem(cls, 2, PySet_New(nullptr)); 2384 EXPECT_EQ(PyObject_IsInstance(Py_True, cls), 1); 2385 EXPECT_EQ(PyErr_Occurred(), nullptr); 2386} 2387 2388TEST_F(AbstractExtensionApiTest, PyObjectIsSubclassWithNonTypeRaisesTypeError) { 2389 PyObjectPtr obj(PyLong_FromLong(2)); 2390 PyObjectPtr subclass(PyObject_Type(obj)); 2391 PyObjectPtr superclass(PyList_New(0)); 2392 EXPECT_EQ(PyObject_IsSubclass(subclass, superclass), -1); 2393 ASSERT_NE(PyErr_Occurred(), nullptr); 2394 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2395} 2396 2397TEST_F(AbstractExtensionApiTest, PyObjectIsSubclassWithSameTypesReturnsTrue) { 2398 PyObjectPtr obj1(PyLong_FromLong(2)); 2399 PyObjectPtr obj2(PyLong_FromLong(10)); 2400 PyObjectPtr subclass(PyObject_Type(obj1)); 2401 PyObjectPtr superclass(PyObject_Type(obj2)); 2402 EXPECT_EQ(PyObject_IsSubclass(subclass, superclass), 1); 2403 EXPECT_EQ(PyErr_Occurred(), nullptr); 2404} 2405 2406TEST_F(AbstractExtensionApiTest, PyObjectIsSubclassWithSubtypeReturnsTrue) { 2407 PyObjectPtr obj(PyLong_FromLong(10)); 2408 PyObjectPtr subclass(PyObject_Type(Py_True)); 2409 PyObjectPtr superclass(PyObject_Type(obj)); 2410 EXPECT_EQ(PyObject_IsSubclass(subclass, superclass), 1); 2411 EXPECT_EQ(PyErr_Occurred(), nullptr); 2412} 2413 2414TEST_F(AbstractExtensionApiTest, PyObjectIsSubclassWithSupertypeReturnsFalse) { 2415 PyObjectPtr obj(PyLong_FromLong(10)); 2416 PyObjectPtr subclass(PyObject_Type(obj)); 2417 PyObjectPtr superclass(PyObject_Type(Py_True)); 2418 EXPECT_EQ(PyObject_IsSubclass(subclass, superclass), 0); 2419 EXPECT_EQ(PyErr_Occurred(), nullptr); 2420} 2421 2422TEST_F(AbstractExtensionApiTest, PyObjectIsSubclassWithTupleChecksTypes) { 2423 PyObjectPtr obj1(PyList_New(0)); 2424 PyObjectPtr obj2(PyLong_FromLong(10)); 2425 PyObjectPtr subclass(PyObject_Type(Py_True)); 2426 PyObjectPtr superclass(PyTuple_New(3)); 2427 PyTuple_SetItem(superclass, 0, PyObject_Type(obj1)); 2428 PyTuple_SetItem(superclass, 1, PyObject_Type(obj2)); 2429 PyTuple_SetItem(superclass, 2, PySet_New(nullptr)); 2430 EXPECT_EQ(PyObject_IsSubclass(subclass, superclass), 1); 2431 EXPECT_EQ(PyErr_Occurred(), nullptr); 2432} 2433 2434TEST_F(AbstractExtensionApiTest, PyObjectLengthOnNullRaisesSystemError) { 2435 EXPECT_EQ(PyObject_Length(nullptr), -1); 2436 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 2437} 2438 2439TEST_F(AbstractExtensionApiTest, 2440 PyObjectLengthWithoutDunderLenRaisesTypeError) { 2441 PyObjectPtr num(PyLong_FromLong(3)); 2442 ASSERT_EQ(PyObject_Length(num), -1); 2443 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2444} 2445 2446TEST_F(AbstractExtensionApiTest, 2447 PyObjectLengthHintWithDunderLengthReturnsValueOfDunderLength) { 2448 PyRun_SimpleString(R"( 2449class Bar: 2450 def __len__(self): return 1 2451 def __length_hint__(self): return 500 2452obj = Bar() 2453 )"); 2454 PyObjectPtr obj(mainModuleGet("obj")); 2455 EXPECT_EQ(PyObject_LengthHint(obj, 234), 1); 2456 EXPECT_EQ(PyErr_Occurred(), nullptr); 2457} 2458 2459TEST_F(AbstractExtensionApiTest, 2460 PyObjectLengthHintWithDunderLengthRaisingNonTypeErrorRaisesError) { 2461 PyRun_SimpleString(R"( 2462class Bar: 2463 def __len__(self): raise ValueError 2464 def __length_hint__(self): return 500 2465obj = Bar() 2466 )"); 2467 PyObjectPtr obj(mainModuleGet("obj")); 2468 EXPECT_EQ(PyObject_LengthHint(obj, 234), -1); 2469 ASSERT_NE(PyErr_Occurred(), nullptr); 2470 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 2471} 2472 2473TEST_F( 2474 AbstractExtensionApiTest, 2475 PyObjectLengthHintWithDunderLengthRaisingTypeErrorReturnsDunderLengthHintValue) { 2476 PyRun_SimpleString(R"( 2477class Bar: 2478 def __len__(self): raise TypeError 2479 def __length_hint__(self): return 500 2480obj = Bar() 2481 )"); 2482 PyObjectPtr obj(mainModuleGet("obj")); 2483 EXPECT_EQ(PyObject_LengthHint(obj, 234), 500); 2484 EXPECT_EQ(PyErr_Occurred(), nullptr); 2485} 2486 2487TEST_F( 2488 AbstractExtensionApiTest, 2489 PyObjectLengthHintWithoutDunderLengthAndDunderLengthHintReturnsDefaultValue) { 2490 PyRun_SimpleString(R"( 2491class Bar: pass 2492 2493obj = Bar() 2494 )"); 2495 PyObjectPtr obj(mainModuleGet("obj")); 2496 EXPECT_EQ(PyObject_LengthHint(obj, 234), 234); 2497 EXPECT_EQ(PyErr_Occurred(), nullptr); 2498} 2499 2500TEST_F( 2501 AbstractExtensionApiTest, 2502 PyObjectLengthHintWithNotImplementedDunderLengthHintReturnsDefaultValue) { 2503 PyRun_SimpleString(R"( 2504class Bar: 2505 def __length_hint__(self): return NotImplemented 2506 2507obj = Bar() 2508 )"); 2509 PyObjectPtr obj(mainModuleGet("obj")); 2510 EXPECT_EQ(PyObject_LengthHint(obj, 234), 234); 2511 EXPECT_EQ(PyErr_Occurred(), nullptr); 2512} 2513 2514TEST_F( 2515 AbstractExtensionApiTest, 2516 PyObjectLengthHintWithDunderLengthHintRaisingExceptionReturnsNegativeValue) { 2517 PyRun_SimpleString(R"( 2518class Bar: 2519 def __length_hint__(self): raise ValueError 2520 2521obj = Bar() 2522 )"); 2523 PyObjectPtr obj(mainModuleGet("obj")); 2524 EXPECT_EQ(PyObject_LengthHint(obj, 234), -1); 2525 ASSERT_NE(PyErr_Occurred(), nullptr); 2526 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 2527} 2528 2529TEST_F(AbstractExtensionApiTest, 2530 PyObjectLengthHintWithDunderLengthHintReturningNonIntRaisesTypeError) { 2531 PyRun_SimpleString(R"( 2532class Bar: 2533 def __length_hint__(self): return "not int" 2534 2535obj = Bar() 2536 )"); 2537 PyObjectPtr obj(mainModuleGet("obj")); 2538 EXPECT_EQ(PyObject_LengthHint(obj, 234), -1); 2539 ASSERT_NE(PyErr_Occurred(), nullptr); 2540 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2541} 2542 2543TEST_F( 2544 AbstractExtensionApiTest, 2545 PyObjectLengthHintWithDunderLengthHintReturningLargeIntNotFitInWordRaisesOverflowError) { 2546 PyRun_SimpleString(R"( 2547class Bar: 2548 def __length_hint__(self): return 13843149871348971349871398471389473 2549 2550obj = Bar() 2551 )"); 2552 PyObjectPtr obj(mainModuleGet("obj")); 2553 EXPECT_EQ(PyObject_LengthHint(obj, 234), -1); 2554 ASSERT_NE(PyErr_Occurred(), nullptr); 2555 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); 2556} 2557 2558TEST_F( 2559 AbstractExtensionApiTest, 2560 PyObjectLengthHintWithDunderLengthHintReturningNegativeNumberRaisesValueError) { 2561 PyRun_SimpleString(R"( 2562class Bar: 2563 def __length_hint__(self): return -1 2564 2565obj = Bar() 2566 )"); 2567 PyObjectPtr obj(mainModuleGet("obj")); 2568 EXPECT_EQ(PyObject_LengthHint(obj, 234), -1); 2569 ASSERT_NE(PyErr_Occurred(), nullptr); 2570 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 2571} 2572 2573TEST_F(AbstractExtensionApiTest, PyObjectLengthWithNonIntLenRaisesTypeError) { 2574 PyRun_SimpleString(R"( 2575class Foo: 2576 def __len__(self): 2577 return "foo" 2578obj = Foo() 2579 )"); 2580 2581 PyObjectPtr obj(mainModuleGet("obj")); 2582 ASSERT_EQ(PyObject_Length(obj), -1); 2583 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2584} 2585 2586TEST_F(AbstractExtensionApiTest, PyObjectLengthWithoutIndexRaisesTypeError) { 2587 PyRun_SimpleString(R"( 2588class Foo: pass 2589class Bar: 2590 def __len__(self): return Foo() 2591obj = Bar() 2592 )"); 2593 2594 PyObjectPtr obj(mainModuleGet("obj")); 2595 ASSERT_EQ(PyObject_Length(obj), -1); 2596 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2597} 2598 2599TEST_F(AbstractExtensionApiTest, PyObjectLengthWithNonIntIndexRaisesTypeError) { 2600 PyRun_SimpleString(R"( 2601class Foo: 2602 def __index__(self): return None 2603class Bar: 2604 def __len__(self): return Foo() 2605obj = Bar() 2606 )"); 2607 2608 PyObjectPtr obj(mainModuleGet("obj")); 2609 ASSERT_EQ(PyObject_Length(obj), -1); 2610 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2611} 2612 2613TEST_F(AbstractExtensionApiTest, 2614 PyObjectLengthWithIntSubclassLargeRaisesOverflowError) { 2615 PyRun_SimpleString(R"( 2616class Foo(int): pass 2617class Bar: 2618 def __len__(self): return Foo(2**63) 2619obj = Bar() 2620)"); 2621 2622 PyObjectPtr obj(mainModuleGet("obj")); 2623 ASSERT_EQ(PyObject_Length(obj), -1); 2624 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); 2625} 2626 2627TEST_F(AbstractExtensionApiTest, PyObjectLengthWithIntSubclassReturnsValue) { 2628 PyRun_SimpleString(R"( 2629class Foo(int): pass 2630class Bar: 2631 def __len__(self): return Foo(5) 2632obj = Bar() 2633)"); 2634 2635 PyObjectPtr obj(mainModuleGet("obj")); 2636 EXPECT_EQ(PyObject_Length(obj), 5); 2637 EXPECT_EQ(PyErr_Occurred(), nullptr); 2638} 2639 2640TEST_F(AbstractExtensionApiTest, PyObjectLengthWithIndexReturnsValue) { 2641 PyRun_SimpleString(R"( 2642class Foo: 2643 def __index__(self): return 1 2644class Bar: 2645 def __len__(self): return Foo() 2646obj = Bar() 2647 )"); 2648 2649 PyObjectPtr obj(mainModuleGet("obj")); 2650 EXPECT_EQ(PyObject_Length(obj), 1); 2651 EXPECT_EQ(PyErr_Occurred(), nullptr); 2652} 2653 2654TEST_F(AbstractExtensionApiTest, 2655 PyObjectLengthWithNegativeLenRaisesValueError) { 2656 PyRun_SimpleString(R"( 2657class Foo: 2658 def __len__(self): 2659 return -5 2660obj = Foo() 2661 )"); 2662 2663 PyObjectPtr obj(mainModuleGet("obj")); 2664 ASSERT_EQ(PyObject_Length(obj), -1); 2665 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 2666} 2667 2668TEST_F(AbstractExtensionApiTest, 2669 PyObjectLengthWithOverflowRaisesOverflowError) { 2670 PyRun_SimpleString(R"( 2671class Foo: 2672 def __len__(self): 2673 return 0x8000000000000000 2674obj = Foo() 2675 )"); 2676 2677 PyObjectPtr obj(mainModuleGet("obj")); 2678 ASSERT_EQ(PyObject_Length(obj), -1); 2679 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); 2680} 2681 2682TEST_F(AbstractExtensionApiTest, PyObjectLengthWithUnderflowRaisesValueError) { 2683 PyRun_SimpleString(R"( 2684class Foo: 2685 def __len__(self): 2686 return -0x8000000000000001 2687obj = Foo() 2688 )"); 2689 2690 PyObjectPtr obj(mainModuleGet("obj")); 2691 ASSERT_EQ(PyObject_Length(obj), -1); 2692 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 2693} 2694 2695TEST_F(AbstractExtensionApiTest, PyObjectLengthWithEmptyDictReturnsZero) { 2696 PyObjectPtr dict(PyDict_New()); 2697 EXPECT_EQ(PyObject_Length(dict), 0); 2698 EXPECT_EQ(PyErr_Occurred(), nullptr); 2699} 2700 2701TEST_F(AbstractExtensionApiTest, PyObjectLengthWithEmptyListReturnsZero) { 2702 PyObjectPtr list(PyList_New(0)); 2703 EXPECT_EQ(PyObject_Length(list), 0); 2704 EXPECT_EQ(PyErr_Occurred(), nullptr); 2705} 2706 2707TEST_F(AbstractExtensionApiTest, PyObjectLengthWithEmptyStringReturnsZero) { 2708 PyObjectPtr str(PyUnicode_FromString("")); 2709 EXPECT_EQ(PyObject_Length(str), 0); 2710 EXPECT_EQ(PyErr_Occurred(), nullptr); 2711} 2712 2713TEST_F(AbstractExtensionApiTest, PyObjectLengthWithNonEmptyDictReturnsValue) { 2714 PyObjectPtr dict(PyDict_New()); 2715 2716 { 2717 PyObjectPtr value(PyLong_FromLong(3)); 2718 2719 PyObjectPtr key1(PyLong_FromLong(1)); 2720 PyDict_SetItem(dict, key1, value); 2721 2722 PyObjectPtr key2(PyLong_FromLong(2)); 2723 PyDict_SetItem(dict, key2, value); 2724 } 2725 2726 EXPECT_EQ(PyObject_Length(dict), 2); 2727 EXPECT_EQ(PyErr_Occurred(), nullptr); 2728} 2729 2730TEST_F(AbstractExtensionApiTest, PyObjectLengthWithNonEmptyListReturnsValue) { 2731 PyObjectPtr list(PyList_New(3)); 2732 EXPECT_EQ(PyObject_Length(list), 3); 2733 EXPECT_EQ(PyErr_Occurred(), nullptr); 2734} 2735 2736TEST_F(AbstractExtensionApiTest, PyObjectLengthWithNonEmptyStringReturnsValue) { 2737 PyObjectPtr str(PyUnicode_FromString("foo")); 2738 EXPECT_EQ(PyObject_Length(str), 3); 2739 EXPECT_EQ(PyErr_Occurred(), nullptr); 2740} 2741 2742TEST_F(AbstractExtensionApiTest, PyObjectSizeOnNullRaisesSystemError) { 2743 EXPECT_EQ(PyObject_Size(nullptr), -1); 2744 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 2745} 2746 2747TEST_F(AbstractExtensionApiTest, PyObjectTypeOnNullRaisesSystemError) { 2748 EXPECT_EQ(PyObject_Type(nullptr), nullptr); 2749 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 2750} 2751 2752TEST_F(AbstractExtensionApiTest, PyObjectTypeReturnsType) { 2753 PyObjectPtr num(PyLong_FromLong(4)); 2754 PyObjectPtr type(PyObject_Type(num)); 2755 EXPECT_TRUE(PyType_Check(type)); 2756} 2757 2758TEST_F(AbstractExtensionApiTest, PyObjectTypeReturnsSameTypeForSmallAndLarge) { 2759 PyObjectPtr str1(PyUnicode_FromString("short")); 2760 PyObjectPtr str2(PyUnicode_FromString("This is a longer string.")); 2761 PyObjectPtr type1(PyObject_Type(str1)); 2762 PyObjectPtr type2(PyObject_Type(str2)); 2763 EXPECT_EQ(type1, type2); 2764} 2765 2766#ifndef Py_SET_TYPE 2767#define Py_SET_TYPE(obj, type) ((Py_TYPE(obj) = (type)), (void)0) 2768#endif 2769 2770TEST_F(AbstractExtensionApiTest, PySETTYPEWithObjectSetsType) { 2771 PyRun_SimpleString(R"( 2772class C: 2773 pass 2774class D: 2775 pass 2776instance = C() 2777)"); 2778 PyObjectPtr class_c(mainModuleGet("C")); 2779 PyObjectPtr class_d(mainModuleGet("D")); 2780 PyObjectPtr instance(mainModuleGet("instance")); 2781 EXPECT_TRUE(PyObject_IsInstance(instance, class_c)); 2782 // The instance must have an owned reference to D 2783 Py_INCREF(class_d); 2784 Py_SET_TYPE(instance.get(), class_d.asTypeObject()); 2785 EXPECT_TRUE(PyObject_IsInstance(instance, class_d)); 2786} 2787 2788TEST_F(AbstractExtensionApiTest, PySETTYPEWithTypeObjectSetsMetaclass) { 2789 PyRun_SimpleString(R"( 2790class M(type): 2791 pass 2792class C(metaclass=M): 2793 pass 2794class D(type): 2795 pass 2796)"); 2797 PyObjectPtr class_m(mainModuleGet("M")); 2798 PyObjectPtr class_c(mainModuleGet("C")); 2799 PyObjectPtr class_d(mainModuleGet("D")); 2800 EXPECT_TRUE(PyObject_IsInstance(class_c, class_m)); 2801 // The instance must have an owned reference to D 2802 Py_INCREF(class_d); 2803 Py_SET_TYPE(class_c.get(), class_d.asTypeObject()); 2804 EXPECT_TRUE(PyObject_IsInstance(class_c, class_d)); 2805} 2806 2807// Sequence Protocol 2808 2809TEST_F(AbstractExtensionApiTest, 2810 PySequenceBytesToCharpArrayWithNonSequenceRaisesTypeError) { 2811 PyObjectPtr obj(PyLong_FromLong(1)); 2812 EXPECT_EQ(_PySequence_BytesToCharpArray(obj), nullptr); 2813 ASSERT_NE(PyErr_Occurred(), nullptr); 2814 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2815} 2816 2817TEST_F(AbstractExtensionApiTest, 2818 PySequenceBytesToCharpArrayWithEmptyListReturnsArray) { 2819 PyObjectPtr obj(PyList_New(0)); 2820 char* const* array = _PySequence_BytesToCharpArray(obj); 2821 EXPECT_EQ(PyErr_Occurred(), nullptr); 2822 ASSERT_NE(array, nullptr); 2823 EXPECT_EQ(array[0], nullptr); 2824 _Py_FreeCharPArray(array); 2825} 2826 2827TEST_F(AbstractExtensionApiTest, 2828 PySequenceBytesToCharpArrayWithNonBytesItemRaisesTypeError) { 2829 PyObjectPtr obj(PyTuple_New(1)); 2830 PyTuple_SetItem(obj, 0, PyByteArray_FromStringAndSize("foo", 3)); 2831 EXPECT_EQ(_PySequence_BytesToCharpArray(obj), nullptr); 2832 ASSERT_NE(PyErr_Occurred(), nullptr); 2833 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 2834} 2835 2836TEST_F(AbstractExtensionApiTest, 2837 PySequenceBytesToCharpArrayWithBytesSequenceReturnsArray) { 2838 PyObjectPtr obj(PyTuple_New(3)); 2839 PyTuple_SetItem(obj, 0, PyBytes_FromString("foo")); 2840 PyTuple_SetItem(obj, 1, PyBytes_FromString("bar")); 2841 PyTuple_SetItem(obj, 2, PyBytes_FromString("baz")); 2842 char* const* array = _PySequence_BytesToCharpArray(obj); 2843 EXPECT_EQ(PyErr_Occurred(), nullptr); 2844 ASSERT_NE(array, nullptr); 2845 EXPECT_STREQ(array[0], "foo"); 2846 EXPECT_STREQ(array[1], "bar"); 2847 EXPECT_STREQ(array[2], "baz"); 2848 EXPECT_EQ(array[3], nullptr); 2849 _Py_FreeCharPArray(array); 2850} 2851 2852TEST_F(AbstractExtensionApiTest, PySequenceCheckWithoutGetItemReturnsFalse) { 2853 PyRun_SimpleString(R"( 2854class ClassWithoutDunderGetItem: pass 2855 2856obj = ClassWithoutDunderGetItem() 2857)"); 2858 2859 PyObjectPtr obj(mainModuleGet("obj")); 2860 EXPECT_FALSE(PySequence_Check(obj)); 2861} 2862 2863TEST_F(AbstractExtensionApiTest, 2864 PySequenceCheckWithoutGetItemOnClassReturnsFalse) { 2865 PyRun_SimpleString(R"( 2866class ClassWithoutDunderGetItem: pass 2867 2868obj = ClassWithoutDunderGetItem() 2869obj.__getitem__ = lambda self, key : 1 2870)"); 2871 2872 PyObjectPtr obj(mainModuleGet("obj")); 2873 EXPECT_FALSE(PySequence_Check(obj)); 2874} 2875 2876TEST_F(AbstractExtensionApiTest, PySequenceCheckWithNumericReturnsFalse) { 2877 PyObjectPtr num(PyLong_FromLong(3)); 2878 EXPECT_FALSE(PySequence_Check(num)); 2879} 2880 2881TEST_F(AbstractExtensionApiTest, PySequenceCheckWithSetReturnsFalse) { 2882 PyObjectPtr set(PySet_New(nullptr)); 2883 EXPECT_FALSE(PySequence_Check(set)); 2884} 2885 2886TEST_F(AbstractExtensionApiTest, PySequenceCheckWithDictReturnsFalse) { 2887 PyObjectPtr dict(PyDict_New()); 2888 EXPECT_FALSE(PySequence_Check(dict)); 2889} 2890 2891TEST_F(AbstractExtensionApiTest, PySequenceCheckWithDictSubclassReturnsFalse) { 2892 PyRun_SimpleString(R"( 2893class Subclass(dict): pass 2894 2895obj = Subclass() 2896)"); 2897 2898 PyObjectPtr obj(mainModuleGet("obj")); 2899 EXPECT_FALSE(PySequence_Check(obj)); 2900} 2901 2902TEST_F(AbstractExtensionApiTest, PySequenceCheckWithNoneReturnsFalse) { 2903 EXPECT_FALSE(PySequence_Check(Py_None)); 2904} 2905 2906TEST_F(AbstractExtensionApiTest, PySequenceCheckWithGetItemMethodReturnsTrue) { 2907 PyRun_SimpleString(R"( 2908class ClassWithDunderGetItemMethod: 2909 def __getitem__(self, key): 2910 return None 2911 2912obj = ClassWithDunderGetItemMethod() 2913)"); 2914 2915 PyObjectPtr obj(mainModuleGet("obj")); 2916 EXPECT_TRUE(PySequence_Check(obj)); 2917} 2918 2919TEST_F(AbstractExtensionApiTest, PySequenceCheckWithGetItemAttrReturnsTrue) { 2920 PyRun_SimpleString(R"( 2921class ClassWithDunderGetItemAttr: 2922 __getitem__ = 42 2923 2924obj = ClassWithDunderGetItemAttr() 2925)"); 2926 2927 PyObjectPtr obj(mainModuleGet("obj")); 2928 EXPECT_TRUE(PySequence_Check(obj)); 2929} 2930 2931TEST_F(AbstractExtensionApiTest, PySequenceCheckWithStringReturnsTrue) { 2932 PyObjectPtr str(PyUnicode_FromString("foo")); 2933 EXPECT_TRUE(PySequence_Check(str)); 2934} 2935 2936TEST_F(AbstractExtensionApiTest, PySequenceCheckWithListReturnsTrue) { 2937 PyObjectPtr list(PyList_New(3)); 2938 EXPECT_TRUE(PySequence_Check(list)); 2939} 2940 2941TEST_F(AbstractExtensionApiTest, PySequenceConcatWithNullLeftRaises) { 2942 PyObjectPtr tuple(PyTuple_New(0)); 2943 PyObjectPtr result(PySequence_Concat(nullptr, tuple)); 2944 ASSERT_EQ(result, nullptr); 2945 ASSERT_NE(PyErr_Occurred(), nullptr); 2946 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 2947} 2948 2949TEST_F(AbstractExtensionApiTest, PySequenceConcatWithNullRightRaises) { 2950 PyObjectPtr tuple(PyTuple_New(0)); 2951 PyObjectPtr result(PySequence_Concat(tuple, nullptr)); 2952 ASSERT_EQ(result, nullptr); 2953 ASSERT_NE(PyErr_Occurred(), nullptr); 2954 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 2955} 2956 2957TEST_F(AbstractExtensionApiTest, PySequenceConcatCallsDunderAdd) { 2958 PyObjectPtr one(PyLong_FromLong(1)); 2959 PyObjectPtr two(PyLong_FromLong(2)); 2960 PyObjectPtr three(PyLong_FromLong(3)); 2961 PyObjectPtr four(PyLong_FromLong(4)); 2962 PyObjectPtr left(PyTuple_Pack(2, one.get(), two.get())); 2963 PyObjectPtr right(PyTuple_Pack(2, three.get(), four.get())); 2964 PyObjectPtr result(PySequence_Concat(left, right)); 2965 ASSERT_NE(result, nullptr); 2966 ASSERT_TRUE(PyTuple_CheckExact(result)); 2967 ASSERT_EQ(PyTuple_Size(result), 4); 2968 EXPECT_EQ(PyTuple_GetItem(result, 0), PyTuple_GetItem(left, 0)); 2969 EXPECT_EQ(PyTuple_GetItem(result, 1), PyTuple_GetItem(left, 1)); 2970 EXPECT_EQ(PyTuple_GetItem(result, 2), PyTuple_GetItem(right, 0)); 2971 EXPECT_EQ(PyTuple_GetItem(result, 3), PyTuple_GetItem(right, 1)); 2972} 2973 2974TEST_F(AbstractExtensionApiTest, PySequenceRepeatWithNullSeqRaises) { 2975 PyObjectPtr result(PySequence_Repeat(nullptr, 5)); 2976 ASSERT_EQ(result, nullptr); 2977 ASSERT_NE(PyErr_Occurred(), nullptr); 2978 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 2979} 2980 2981TEST_F(AbstractExtensionApiTest, PySequenceRepeatCallsDunderMul) { 2982 PyObjectPtr one(PyLong_FromLong(1)); 2983 PyObjectPtr two(PyLong_FromLong(2)); 2984 PyObjectPtr seq(PyTuple_Pack(2, one.get(), two.get())); 2985 PyObjectPtr result(PySequence_Repeat(seq, 2)); 2986 ASSERT_NE(result, nullptr); 2987 ASSERT_EQ(PyErr_Occurred(), nullptr); 2988 ASSERT_EQ(PyTuple_Size(result), 4); 2989 EXPECT_EQ(PyTuple_GetItem(result, 0), PyTuple_GetItem(seq, 0)); 2990 EXPECT_EQ(PyTuple_GetItem(result, 1), PyTuple_GetItem(seq, 1)); 2991 EXPECT_EQ(PyTuple_GetItem(result, 2), PyTuple_GetItem(seq, 0)); 2992 EXPECT_EQ(PyTuple_GetItem(result, 3), PyTuple_GetItem(seq, 1)); 2993} 2994 2995TEST_F(AbstractExtensionApiTest, PySequenceCountWithNullSeqRaises) { 2996 PyObjectPtr obj(PyLong_FromLong(1)); 2997 EXPECT_EQ(PySequence_Count(nullptr, obj), -1); 2998 ASSERT_NE(PyErr_Occurred(), nullptr); 2999 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3000} 3001 3002TEST_F(AbstractExtensionApiTest, PySequenceCountWithNullObjRaises) { 3003 PyObjectPtr one(PyLong_FromLong(1)); 3004 PyObjectPtr two(PyLong_FromLong(2)); 3005 PyObjectPtr tuple(PyTuple_Pack(2, one.get(), two.get())); 3006 EXPECT_EQ(PySequence_Count(tuple, nullptr), -1); 3007 ASSERT_NE(PyErr_Occurred(), nullptr); 3008 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3009} 3010 3011TEST_F(AbstractExtensionApiTest, PySequenceCountCountsOccurrences) { 3012 PyObjectPtr obj(PyLong_FromLong(2)); 3013 PyObjectPtr one(PyLong_FromLong(1)); 3014 PyObjectPtr two1(PyLong_FromLong(2)); 3015 PyObjectPtr two2(PyLong_FromLong(2)); 3016 PyObjectPtr tuple(PyTuple_Pack(3, one.get(), two1.get(), two2.get())); 3017 EXPECT_EQ(PySequence_Count(tuple, obj), 2); 3018 EXPECT_EQ(PyErr_Occurred(), nullptr); 3019} 3020 3021TEST_F(AbstractExtensionApiTest, PySequenceGetItemCallsDunderGetItem) { 3022 PyRun_SimpleString(R"( 3023class C: 3024 def __getitem__(self, key): 3025 return 7 3026c = C() 3027)"); 3028 PyObjectPtr c(mainModuleGet("c")); 3029 PyObjectPtr result(PySequence_GetItem(c, 0)); 3030 ASSERT_NE(result, nullptr); 3031 ASSERT_EQ(PyErr_Occurred(), nullptr); 3032 EXPECT_EQ(PyLong_AsLong(result), 7); 3033} 3034 3035TEST_F(AbstractExtensionApiTest, PySequenceItemCallsDunderGetItem) { 3036 PyRun_SimpleString(R"( 3037class C: 3038 def __getitem__(self, key): 3039 return 7 3040c = C() 3041)"); 3042 PyObjectPtr c(mainModuleGet("c")); 3043 PyObjectPtr result(PySequence_ITEM(c, 0)); 3044 ASSERT_NE(result, nullptr); 3045 ASSERT_EQ(PyErr_Occurred(), nullptr); 3046 EXPECT_EQ(PyLong_AsLong(result), 7); 3047} 3048 3049TEST_F(AbstractExtensionApiTest, PySequenceItemDunderGetItemRaises) { 3050 PyRun_SimpleString(R"( 3051class C: 3052 def __getitem__(self, key): 3053 raise Exception("foo") 3054c = C() 3055)"); 3056 PyObjectPtr c(mainModuleGet("c")); 3057 PyObjectPtr result(PySequence_ITEM(c, 0)); 3058 ASSERT_EQ(result, nullptr); 3059 ASSERT_NE(PyErr_Occurred(), nullptr); 3060} 3061 3062TEST_F(AbstractExtensionApiTest, PySequenceSetItemWithNullValCallsDelItem) { 3063 PyRun_SimpleString(R"( 3064sideeffect = 0 3065class C: 3066 def __delitem__(self, key): 3067 global sideeffect 3068 sideeffect = 10 3069c = C() 3070)"); 3071 PyObjectPtr c(mainModuleGet("c")); 3072 ASSERT_EQ(PySequence_SetItem(c, 0, nullptr), 0); 3073 ASSERT_EQ(PyErr_Occurred(), nullptr); 3074 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 3075 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 3076} 3077 3078TEST_F(AbstractExtensionApiTest, PySequenceSetItemCallsDunderSetItem) { 3079 PyRun_SimpleString(R"( 3080sideeffect = 0 3081class C: 3082 def __setitem__(self, key, val): 3083 global sideeffect 3084 sideeffect = 10 3085c = C() 3086)"); 3087 PyObjectPtr c(mainModuleGet("c")); 3088 PyObjectPtr val(PyLong_FromLong(4)); 3089 ASSERT_EQ(PySequence_SetItem(c, 0, val), 0); 3090 ASSERT_EQ(PyErr_Occurred(), nullptr); 3091 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 3092 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 3093} 3094 3095TEST_F(AbstractExtensionApiTest, 3096 PySequenceGetItemWithTupleReturnsTupleElement) { 3097 PyObjectPtr tuple(PyTuple_New(2)); 3098 ASSERT_EQ(PyTuple_SetItem(tuple, 0, PyUnicode_FromString("first")), 0); 3099 ASSERT_EQ(PyTuple_SetItem(tuple, 1, PyUnicode_FromString("second")), 0); 3100 3101 PyObjectPtr result(PySequence_GetItem(tuple, 0)); 3102 EXPECT_TRUE(isUnicodeEqualsCStr(result, "first")); 3103 3104 result = PySequence_GetItem(tuple, 1); 3105 EXPECT_TRUE(isUnicodeEqualsCStr(result, "second")); 3106} 3107 3108TEST_F(AbstractExtensionApiTest, PySequenceGetItemWithListReturnsListElement) { 3109 PyObjectPtr list(PyList_New(2)); 3110 ASSERT_EQ(PyList_SetItem(list, 0, PyUnicode_FromString("first")), 0); 3111 ASSERT_EQ(PyList_SetItem(list, 1, PyUnicode_FromString("second")), 0); 3112 3113 PyObjectPtr result(PySequence_GetItem(list, 0)); 3114 EXPECT_TRUE(isUnicodeEqualsCStr(result, "first")); 3115 3116 result = PySequence_GetItem(list, 1); 3117 EXPECT_TRUE(isUnicodeEqualsCStr(result, "second")); 3118} 3119 3120TEST_F(AbstractExtensionApiTest, PySequenceDelItemCallsDunderDelItem) { 3121 PyRun_SimpleString(R"( 3122sideeffect = 0 3123class C: 3124 def __delitem__(self, key): 3125 global sideeffect 3126 sideeffect = 10 3127c = C() 3128)"); 3129 PyObjectPtr c(mainModuleGet("c")); 3130 ASSERT_EQ(PySequence_DelItem(c, 0), 0); 3131 ASSERT_EQ(PyErr_Occurred(), nullptr); 3132 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 3133 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 3134} 3135 3136TEST_F(AbstractExtensionApiTest, PySequenceContainsCallsDunderContains) { 3137 PyRun_SimpleString(R"( 3138class C: 3139 def __getitem__(self, key): 3140 pass 3141 def __contains__(self, key): 3142 return True 3143c = C() 3144)"); 3145 PyObjectPtr c(mainModuleGet("c")); 3146 PyObjectPtr key(PyLong_FromLong(3)); 3147 ASSERT_EQ(PySequence_Contains(c, key), 1); 3148 ASSERT_EQ(PyErr_Occurred(), nullptr); 3149} 3150 3151TEST_F(AbstractExtensionApiTest, PySequenceContainsPropagatesException) { 3152 PyRun_SimpleString(R"( 3153class C: 3154 def __getitem__(self, key): 3155 pass 3156 def __contains__(self, key): 3157 raise ValueError 3158c = C() 3159)"); 3160 PyObjectPtr c(mainModuleGet("c")); 3161 PyObjectPtr key(PyLong_FromLong(3)); 3162 ASSERT_EQ(PySequence_Contains(c, key), -1); 3163 ASSERT_NE(PyErr_Occurred(), nullptr); 3164 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 3165} 3166 3167TEST_F(AbstractExtensionApiTest, PySequenceContainsFallsBackToIterSearch) { 3168 PyRun_SimpleString(R"( 3169class C: 3170 def __getitem__(self, key): 3171 pass 3172 def __iter__(self): 3173 return [1,2,3].__iter__() 3174c = C() 3175)"); 3176 PyObjectPtr c(mainModuleGet("c")); 3177 PyObjectPtr key(PyLong_FromLong(4)); 3178 ASSERT_EQ(PySequence_Contains(c, key), 0); 3179 ASSERT_EQ(PyErr_Occurred(), nullptr); 3180} 3181 3182TEST_F(AbstractExtensionApiTest, PySequenceIndexWithNullObjRaises) { 3183 PyObjectPtr one(PyLong_FromLong(1)); 3184 PyObjectPtr two(PyLong_FromLong(2)); 3185 PyObjectPtr tuple(PyTuple_Pack(2, one.get(), two.get())); 3186 EXPECT_EQ(PySequence_Index(tuple, nullptr), -1); 3187 ASSERT_NE(PyErr_Occurred(), nullptr); 3188 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3189} 3190 3191TEST_F(AbstractExtensionApiTest, PySequenceIndexFindsFirstOccurrence) { 3192 PyObjectPtr one(PyLong_FromLong(1)); 3193 PyObjectPtr two(PyLong_FromLong(2)); 3194 PyObjectPtr tuple(PyTuple_Pack(3, one.get(), two.get(), two.get())); 3195 EXPECT_EQ(PySequence_Index(tuple, two), 1); 3196 EXPECT_EQ(PyErr_Occurred(), nullptr); 3197} 3198 3199TEST_F(AbstractExtensionApiTest, PySequenceFastWithNullObjRaisesSystemError) { 3200 EXPECT_EQ(PySequence_Fast(nullptr, "msg"), nullptr); 3201 ASSERT_NE(PyErr_Occurred(), nullptr); 3202 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3203} 3204 3205TEST_F(AbstractExtensionApiTest, PySequenceFastWithTupleReturnsSameObject) { 3206 PyObjectPtr tuple(PyTuple_New(3)); 3207 PyObjectPtr result(PySequence_Fast(tuple, "msg")); 3208 ASSERT_EQ(PyErr_Occurred(), nullptr); 3209 EXPECT_EQ(tuple, result); 3210} 3211 3212TEST_F(AbstractExtensionApiTest, PySequenceFastWithListReturnsSameObject) { 3213 PyObjectPtr list(PyList_New(3)); 3214 PyObjectPtr result(PySequence_Fast(list, "msg")); 3215 ASSERT_EQ(PyErr_Occurred(), nullptr); 3216 EXPECT_EQ(list, result); 3217} 3218 3219TEST_F(AbstractExtensionApiTest, PySequenceFastWithNonIterableRaisesTypeError) { 3220 ASSERT_EQ(PySequence_Fast(Py_None, "msg"), nullptr); 3221 ASSERT_NE(PyErr_Occurred(), nullptr); 3222 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3223} 3224 3225TEST_F(AbstractExtensionApiTest, PySequenceFastGetSizeWithTupleReturnsSize) { 3226 PyObjectPtr tuple(PyTuple_Pack(3, Py_None, Py_None, Py_None)); 3227 PyObjectPtr fast_seq(PySequence_Fast(tuple, "")); 3228 EXPECT_EQ(PySequence_Fast_GET_SIZE(fast_seq.get()), 3); 3229} 3230 3231TEST_F(AbstractExtensionApiTest, PySequenceFastGetSizeWithListReturnsSize) { 3232 PyObjectPtr list(PyList_New(0)); 3233 for (int i = 0; i < 11; i++) { 3234 PyList_Append(list, Py_None); 3235 } 3236 PyObjectPtr fast_seq(PySequence_Fast(list, "")); 3237 EXPECT_EQ(PySequence_Fast_GET_SIZE(fast_seq.get()), 11); 3238} 3239 3240TEST_F(AbstractExtensionApiTest, PySequenceFastGetItemWithTupleReturnsItem) { 3241 PyObjectPtr number(PyLong_FromLong(42)); 3242 PyObjectPtr tuple(PyTuple_Pack(3, Py_None, Py_None, number.get())); 3243 PyObjectPtr fast_seq(PySequence_Fast(tuple, "")); 3244 EXPECT_TRUE( 3245 isLongEqualsLong(PySequence_Fast_GET_ITEM(fast_seq.get(), 2), 42)); 3246} 3247 3248TEST_F(AbstractExtensionApiTest, PySequenceFastGetItemWithListReturnsItem) { 3249 PyObjectPtr list(PyList_New(0)); 3250 PyList_Append(list, Py_None); 3251 PyObjectPtr number(PyLong_FromLong(42)); 3252 PyList_Append(list, number); 3253 PyList_Append(list, Py_None); 3254 PyObjectPtr fast_seq(PySequence_Fast(list, "")); 3255 EXPECT_TRUE( 3256 isLongEqualsLong(PySequence_Fast_GET_ITEM(fast_seq.get(), 1), 42)); 3257} 3258 3259TEST_F(AbstractExtensionApiTest, PySequenceFastWithIterableReturnsList) { 3260 PyRun_SimpleString(R"( 3261class C: 3262 def __iter__(self): 3263 return (1, 2, 3).__iter__() 3264c = C() 3265)"); 3266 PyObjectPtr c(mainModuleGet("c")); 3267 PyObjectPtr result(PySequence_Fast(c, "msg")); 3268 ASSERT_NE(result, nullptr); 3269 ASSERT_EQ(PyErr_Occurred(), nullptr); 3270 EXPECT_TRUE(PyList_CheckExact(result)); 3271} 3272 3273TEST_F(AbstractExtensionApiTest, 3274 PySequenceInPlaceConcatWithNullLeftRaisesSystemError) { 3275 PyObjectPtr right(PyLong_FromLong(1)); 3276 EXPECT_EQ(PySequence_InPlaceConcat(nullptr, right), nullptr); 3277 ASSERT_NE(PyErr_Occurred(), nullptr); 3278 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3279} 3280 3281TEST_F(AbstractExtensionApiTest, 3282 PySequenceInPlaceConcatWithNullRightRaisesSystemError) { 3283 PyObjectPtr left(PyLong_FromLong(1)); 3284 EXPECT_EQ(PySequence_InPlaceConcat(left, nullptr), nullptr); 3285 ASSERT_NE(PyErr_Occurred(), nullptr); 3286 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3287} 3288 3289TEST_F(AbstractExtensionApiTest, 3290 PySequenceInPlaceConcatWithByteArrayLeftReturnsByteArray) { 3291 PyObjectPtr left(PyByteArray_FromStringAndSize("foo", 3)); 3292 PyObjectPtr right(PyBytes_FromString("bar")); 3293 PyObjectPtr result(PySequence_InPlaceConcat(left, right)); 3294 EXPECT_EQ(PyErr_Occurred(), nullptr); 3295 EXPECT_EQ(result, left); 3296 EXPECT_STREQ(PyByteArray_AsString(left), "foobar"); 3297} 3298 3299TEST_F(AbstractExtensionApiTest, 3300 PySequenceInPlaceConcatWithoutDunderGetItemRaisesTypeError) { 3301 PyRun_SimpleString(R"( 3302class C: pass 3303left = C() 3304)"); 3305 PyObjectPtr left(mainModuleGet("left")); 3306 PyObjectPtr right(PyLong_FromLong(42)); 3307 EXPECT_EQ(PySequence_InPlaceConcat(left, right), nullptr); 3308 ASSERT_NE(PyErr_Occurred(), nullptr); 3309 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3310} 3311 3312TEST_F(AbstractExtensionApiTest, PySequenceInPlaceConcatCallsDunderIadd) { 3313 PyRun_SimpleString(R"( 3314class C(list): 3315 def __add__(self, other): 3316 return 1 3317 def __iadd__(self, other): 3318 return 2 3319left = C() 3320right = (1, 2, 3) 3321)"); 3322 PyObjectPtr left(mainModuleGet("left")); 3323 PyObjectPtr right(mainModuleGet("right")); 3324 PyObjectPtr result(PySequence_InPlaceConcat(left, right)); 3325 EXPECT_EQ(PyErr_Occurred(), nullptr); 3326 ASSERT_TRUE(PyLong_CheckExact(result)); 3327 EXPECT_EQ(PyLong_AsLong(result), 2); 3328} 3329 3330TEST_F(AbstractExtensionApiTest, PySequenceInPlaceConcatCallsDunderAdd) { 3331 PyRun_SimpleString(R"( 3332class C(tuple): 3333 def __add__(self, other): 3334 return 1 3335left = C() 3336right = (1, 2, 3) 3337)"); 3338 PyObjectPtr left(mainModuleGet("left")); 3339 PyObjectPtr right(mainModuleGet("right")); 3340 PyObjectPtr result(PySequence_InPlaceConcat(left, right)); 3341 EXPECT_EQ(PyErr_Occurred(), nullptr); 3342 ASSERT_TRUE(PyLong_CheckExact(result)); 3343 EXPECT_EQ(PyLong_AsLong(result), 1); 3344} 3345 3346TEST_F(AbstractExtensionApiTest, 3347 PySequenceInPlaceRepeatWithNullRaisesSystemError) { 3348 EXPECT_EQ(PySequence_InPlaceRepeat(nullptr, 0), nullptr); 3349 ASSERT_NE(PyErr_Occurred(), nullptr); 3350 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3351} 3352 3353TEST_F(AbstractExtensionApiTest, 3354 PySequenceInPlaceRepeatWithoutDunderGetItemRaisesTypeError) { 3355 PyRun_SimpleString(R"( 3356class C: pass 3357obj = C() 3358)"); 3359 PyObjectPtr obj(mainModuleGet("obj")); 3360 EXPECT_EQ(PySequence_InPlaceRepeat(obj, 42), nullptr); 3361 ASSERT_NE(PyErr_Occurred(), nullptr); 3362 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3363} 3364 3365TEST_F(AbstractExtensionApiTest, PySequenceInPlaceRepeatWithTupleReturnsTuple) { 3366 PyObjectPtr obj(Py_BuildValue("(ii)", 0, 1)); 3367 ASSERT_EQ(PyTuple_Size(obj), 2); 3368 PyObjectPtr result(PySequence_InPlaceRepeat(obj, 3)); 3369 EXPECT_EQ(PyErr_Occurred(), nullptr); 3370 EXPECT_EQ(PyTuple_Size(obj), 2); 3371 ASSERT_TRUE(PyTuple_CheckExact(result)); 3372 EXPECT_EQ(PyTuple_Size(result), 6); 3373} 3374 3375TEST_F(AbstractExtensionApiTest, PySequenceInPlaceRepeatCallsDunderImul) { 3376 PyRun_SimpleString(R"( 3377class C(list): 3378 def __imul__(self, other): 3379 return 1 3380 def __mul__(self, other): 3381 return 2 3382obj = C() 3383)"); 3384 PyObjectPtr obj(mainModuleGet("obj")); 3385 PyObjectPtr result(PySequence_InPlaceRepeat(obj, 0)); 3386 EXPECT_EQ(PyErr_Occurred(), nullptr); 3387 ASSERT_TRUE(PyLong_CheckExact(result)); 3388 EXPECT_EQ(PyLong_AsLong(result), 1); 3389} 3390 3391TEST_F(AbstractExtensionApiTest, PySequenceInPlaceRepeatCallsDunderMul) { 3392 PyRun_SimpleString(R"( 3393class C(tuple): 3394 def __mul__(self, other): 3395 return 1 3396obj = C() 3397)"); 3398 PyObjectPtr obj(mainModuleGet("obj")); 3399 PyObjectPtr result(PySequence_InPlaceRepeat(obj, 0)); 3400 EXPECT_EQ(PyErr_Occurred(), nullptr); 3401 ASSERT_TRUE(PyLong_CheckExact(result)); 3402 EXPECT_EQ(PyLong_AsLong(result), 1); 3403} 3404 3405TEST_F(AbstractExtensionApiTest, PySequenceLengthOnNull) { 3406 EXPECT_EQ(PySequence_Length(nullptr), -1); 3407 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3408} 3409 3410TEST_F(AbstractExtensionApiTest, PySequenceLengthWithNonSequenceReturnsValue) { 3411 PyRun_SimpleString(R"( 3412class Foo: 3413 def __len__(self): 3414 return 1 3415obj = Foo() 3416)"); 3417 3418 PyObjectPtr obj(mainModuleGet("obj")); 3419 EXPECT_EQ(PySequence_Length(obj), 1); 3420 EXPECT_EQ(PyErr_Occurred(), nullptr); 3421} 3422 3423// PySequence_Length fails on `dict` in CPython, but succeeds on subclasses 3424TEST_F(AbstractExtensionApiTest, 3425 PySequenceLengthWithEmptyDictSubclassReturnsZero) { 3426 PyRun_SimpleString(R"( 3427class Foo(dict): 3428 pass 3429obj = Foo() 3430)"); 3431 3432 PyObjectPtr obj(mainModuleGet("obj")); 3433 EXPECT_EQ(PySequence_Length(obj), 0); 3434 EXPECT_EQ(PyErr_Occurred(), nullptr); 3435} 3436 3437TEST_F(AbstractExtensionApiTest, 3438 PySequenceLengthWithNonEmptyDictSubclassReturnsValue) { 3439 PyRun_SimpleString(R"( 3440class Foo(dict): 3441 pass 3442obj = Foo() 3443)"); 3444 3445 PyObjectPtr obj(mainModuleGet("obj")); 3446 PyObjectPtr one(PyLong_FromLong(1)); 3447 PyObjectPtr two(PyLong_FromLong(2)); 3448 3449 ASSERT_EQ(PyDict_SetItem(obj, one, two), 0); 3450 ASSERT_EQ(PyDict_SetItem(obj, two, one), 0); 3451 3452 EXPECT_EQ(PySequence_Length(obj), 2); 3453 EXPECT_EQ(PyErr_Occurred(), nullptr); 3454} 3455 3456TEST_F(AbstractExtensionApiTest, PySequenceListWithNullSeqRaisesSystemError) { 3457 ASSERT_EQ(PySequence_List(nullptr), nullptr); 3458 ASSERT_NE(PyErr_Occurred(), nullptr); 3459 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3460} 3461 3462TEST_F(AbstractExtensionApiTest, PySequenceListWithNonIterableRaisesTypeError) { 3463 ASSERT_EQ(PySequence_List(Py_None), nullptr); 3464 ASSERT_NE(PyErr_Occurred(), nullptr); 3465 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3466} 3467 3468TEST_F(AbstractExtensionApiTest, PySequenceListReturnsList) { 3469 PyRun_SimpleString(R"( 3470class C: 3471 def __iter__(self): 3472 return (1, 2, 3).__iter__() 3473c = C() 3474)"); 3475 PyObjectPtr c(mainModuleGet("c")); 3476 PyObjectPtr result(PySequence_List(c)); 3477 ASSERT_NE(result, nullptr); 3478 ASSERT_EQ(PyErr_Occurred(), nullptr); 3479 EXPECT_TRUE(PyList_CheckExact(result)); 3480 EXPECT_EQ(PyList_Size(result), 3); 3481} 3482 3483TEST_F(AbstractExtensionApiTest, 3484 PySequenceGetSliceWithNullSeqRaisesSystemError) { 3485 EXPECT_EQ(PySequence_GetSlice(nullptr, 1, 2), nullptr); 3486 ASSERT_NE(PyErr_Occurred(), nullptr); 3487 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3488} 3489 3490TEST_F(AbstractExtensionApiTest, 3491 PySequenceGetSliceWithNonIterableRaisesTypeError) { 3492 EXPECT_EQ(PySequence_GetSlice(Py_None, 1, 2), nullptr); 3493 ASSERT_NE(PyErr_Occurred(), nullptr); 3494 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3495} 3496 3497TEST_F(AbstractExtensionApiTest, PySequenceGetSliceCallsDunderGetItem) { 3498 PyRun_SimpleString(R"( 3499class C: 3500 def __getitem__(self, key): 3501 return 7 3502c = C() 3503)"); 3504 PyObjectPtr c(mainModuleGet("c")); 3505 PyObjectPtr result(PySequence_GetSlice(c, 1, 2)); 3506 ASSERT_NE(result, nullptr); 3507 ASSERT_EQ(PyErr_Occurred(), nullptr); 3508 ASSERT_TRUE(PyLong_Check(result)); 3509 EXPECT_EQ(PyLong_AsLong(result), 7); 3510} 3511 3512TEST_F(AbstractExtensionApiTest, 3513 PySequenceSetSliceWithNullSeqRaisesSystemError) { 3514 PyObjectPtr obj(PyList_New(0)); 3515 EXPECT_EQ(PySequence_SetSlice(nullptr, 1, 2, obj), -1); 3516 ASSERT_NE(PyErr_Occurred(), nullptr); 3517 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3518} 3519 3520TEST_F(AbstractExtensionApiTest, 3521 PySequenceSetSliceWithNonIterableRaisesTypeError) { 3522 PyObjectPtr obj(PyList_New(0)); 3523 EXPECT_EQ(PySequence_SetSlice(Py_None, 1, 2, obj), -1); 3524 ASSERT_NE(PyErr_Occurred(), nullptr); 3525 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3526} 3527 3528TEST_F(AbstractExtensionApiTest, PySequenceSetSliceCallsDunderSetItem) { 3529 PyRun_SimpleString(R"( 3530sideeffect = 0 3531class C: 3532 def __setitem__(self, key, value): 3533 global sideeffect 3534 sideeffect = 10 3535c = C() 3536)"); 3537 PyObjectPtr c(mainModuleGet("c")); 3538 PyObjectPtr obj(PyList_New(0)); 3539 ASSERT_EQ(PySequence_SetSlice(c, 1, 2, obj), 0); 3540 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 3541 ASSERT_EQ(PyErr_Occurred(), nullptr); 3542 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 3543} 3544 3545TEST_F(AbstractExtensionApiTest, 3546 PySequenceSetSliceWithNullObjCallsDunderDelItem) { 3547 PyRun_SimpleString(R"( 3548sideeffect = 0 3549class C: 3550 def __delitem__(self, key): 3551 global sideeffect 3552 sideeffect = 10 3553c = C() 3554)"); 3555 PyObjectPtr c(mainModuleGet("c")); 3556 EXPECT_EQ(PySequence_SetSlice(c, 1, 2, nullptr), 0); 3557 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 3558 ASSERT_EQ(PyErr_Occurred(), nullptr); 3559 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 3560} 3561 3562TEST_F(AbstractExtensionApiTest, 3563 PySequenceDelSliceWithNullSeqRaisesSystemError) { 3564 EXPECT_EQ(PySequence_DelSlice(nullptr, 1, 2), -1); 3565 ASSERT_NE(PyErr_Occurred(), nullptr); 3566 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3567} 3568 3569TEST_F(AbstractExtensionApiTest, 3570 PySequenceDelSliceWithNonIterableRaisesTypeError) { 3571 EXPECT_EQ(PySequence_DelSlice(Py_None, 1, 2), -1); 3572 ASSERT_NE(PyErr_Occurred(), nullptr); 3573 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3574} 3575 3576TEST_F(AbstractExtensionApiTest, PySequenceDelSliceCallsDunderDelItem) { 3577 PyRun_SimpleString(R"( 3578sideeffect = 0 3579class C: 3580 def __delitem__(self, key): 3581 global sideeffect 3582 sideeffect = 10 3583c = C() 3584)"); 3585 PyObjectPtr c(mainModuleGet("c")); 3586 EXPECT_EQ(PySequence_DelSlice(c, 1, 2), 0); 3587 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 3588 ASSERT_EQ(PyErr_Occurred(), nullptr); 3589 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 3590} 3591 3592TEST_F(AbstractExtensionApiTest, ObjectDelItemWithNullObjRaisesSystemError) { 3593 PyObjectPtr obj(PyLong_FromLong(1)); 3594 EXPECT_EQ(PyObject_DelItem(nullptr, obj), -1); 3595 ASSERT_NE(PyErr_Occurred(), nullptr); 3596 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3597} 3598 3599TEST_F(AbstractExtensionApiTest, ObjectDelItemWithNullKeyRaisesSystemError) { 3600 PyObjectPtr obj(PyLong_FromLong(1)); 3601 EXPECT_EQ(PyObject_DelItem(obj, nullptr), -1); 3602 ASSERT_NE(PyErr_Occurred(), nullptr); 3603 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3604} 3605 3606TEST_F(AbstractExtensionApiTest, ObjectDelItemCallsDunderDelItem) { 3607 PyRun_SimpleString(R"( 3608sideeffect = 0 3609class C: 3610 def __delitem__(self, key): 3611 global sideeffect 3612 sideeffect = 10 3613 3614c = C() 3615)"); 3616 PyObjectPtr c(mainModuleGet("c")); 3617 PyObjectPtr key(PyLong_FromLong(7)); 3618 EXPECT_EQ(PyObject_DelItem(c, key), 0); 3619 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 3620 EXPECT_EQ(PyErr_Occurred(), nullptr); 3621 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 3622} 3623 3624TEST_F(AbstractExtensionApiTest, ObjectDelItemPropagatesDelItemException) { 3625 PyRun_SimpleString(R"( 3626class C: 3627 def __delitem__(self, key): 3628 raise TypeError 3629 3630c = C() 3631)"); 3632 PyObjectPtr c(mainModuleGet("c")); 3633 PyObjectPtr key(PyLong_FromLong(7)); 3634 EXPECT_EQ(PyObject_DelItem(c, key), -1); 3635 ASSERT_NE(PyErr_Occurred(), nullptr); 3636 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3637} 3638 3639TEST_F(AbstractExtensionApiTest, 3640 ObjectDelItemStringWithNullObjRaisesSystemError) { 3641 EXPECT_EQ(PyObject_DelItemString(nullptr, "hello"), -1); 3642 ASSERT_NE(PyErr_Occurred(), nullptr); 3643 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3644} 3645 3646TEST_F(AbstractExtensionApiTest, 3647 ObjectDelItemStringWithNullKeyRaisesSystemError) { 3648 PyObjectPtr obj(PyLong_FromLong(1)); 3649 EXPECT_EQ(PyObject_DelItemString(obj, nullptr), -1); 3650 ASSERT_NE(PyErr_Occurred(), nullptr); 3651 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3652} 3653 3654TEST_F(AbstractExtensionApiTest, ObjectDelItemStringCallsDunderDelItem) { 3655 PyRun_SimpleString(R"( 3656sideeffect = 0 3657class C: 3658 def __delitem__(self, key): 3659 global sideeffect 3660 sideeffect = 10 3661 3662c = C() 3663)"); 3664 PyObjectPtr c(mainModuleGet("c")); 3665 EXPECT_EQ(PyObject_DelItemString(c, "hello"), 0); 3666 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 3667 EXPECT_EQ(PyErr_Occurred(), nullptr); 3668 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 3669} 3670 3671TEST_F(AbstractExtensionApiTest, 3672 ObjectDelItemStringPropagatesDelitemException) { 3673 PyRun_SimpleString(R"( 3674class C: 3675 def __delitem__(self, key): 3676 raise TypeError 3677 3678c = C() 3679)"); 3680 PyObjectPtr c(mainModuleGet("c")); 3681 EXPECT_EQ(PyObject_DelItemString(c, "hello"), -1); 3682 ASSERT_NE(PyErr_Occurred(), nullptr); 3683 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3684} 3685 3686TEST_F(AbstractExtensionApiTest, PySequenceSizeWithNullRaisesSystemError) { 3687 EXPECT_EQ(PySequence_Size(nullptr), -1); 3688 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3689} 3690 3691TEST_F(AbstractExtensionApiTest, PySequenceTupleWithNullSeqRaisesSystemError) { 3692 EXPECT_EQ(PySequence_Tuple(nullptr), nullptr); 3693 ASSERT_NE(PyErr_Occurred(), nullptr); 3694 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3695} 3696 3697TEST_F(AbstractExtensionApiTest, 3698 PySequenceTupleWithNonIterableRaisesTypeError) { 3699 EXPECT_EQ(PySequence_Tuple(Py_None), nullptr); 3700 ASSERT_NE(PyErr_Occurred(), nullptr); 3701 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3702} 3703 3704TEST_F(AbstractExtensionApiTest, PySequenceTupleReturnsTuple) { 3705 PyRun_SimpleString(R"( 3706class C: 3707 def __iter__(self): 3708 return [1, 2, 3].__iter__() 3709c = C() 3710)"); 3711 PyObjectPtr c(mainModuleGet("c")); 3712 PyObjectPtr result(PySequence_Tuple(c)); 3713 ASSERT_NE(result, nullptr); 3714 ASSERT_EQ(PyErr_Occurred(), nullptr); 3715 EXPECT_TRUE(PyTuple_CheckExact(result)); 3716 EXPECT_EQ(PyTuple_Size(result), 3); 3717} 3718 3719TEST_F(AbstractExtensionApiTest, ObjectGetItemWithNullObjRaisesSystemError) { 3720 PyObjectPtr obj(PyLong_FromLong(1)); 3721 EXPECT_EQ(PyObject_GetItem(nullptr, obj), nullptr); 3722 ASSERT_NE(PyErr_Occurred(), nullptr); 3723 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3724} 3725 3726TEST_F(AbstractExtensionApiTest, ObjectGetItemWithNullKeyRaisesSystemError) { 3727 PyObjectPtr obj(PyLong_FromLong(1)); 3728 EXPECT_EQ(PyObject_GetItem(obj, nullptr), nullptr); 3729 ASSERT_NE(PyErr_Occurred(), nullptr); 3730 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3731} 3732 3733TEST_F(AbstractExtensionApiTest, 3734 ObjectGetItemWithNoDunderGetItemRaisesTypeError) { 3735 PyRun_SimpleString(R"( 3736class C: 3737 pass 3738c = C() 3739)"); 3740 PyObjectPtr c(mainModuleGet("c")); 3741 PyObjectPtr key(PyLong_FromLong(7)); 3742 EXPECT_EQ(PyObject_GetItem(c, key), nullptr); 3743 ASSERT_NE(PyErr_Occurred(), nullptr); 3744 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3745} 3746 3747TEST_F(AbstractExtensionApiTest, 3748 ObjectGetItemWithUncallableDunderGetItemRaisesTypeError) { 3749 PyRun_SimpleString(R"( 3750class C: 3751 __getitem__ = 4 3752c = C() 3753)"); 3754 PyObjectPtr c(mainModuleGet("c")); 3755 PyObjectPtr key(PyLong_FromLong(7)); 3756 EXPECT_EQ(PyObject_GetItem(c, key), nullptr); 3757 ASSERT_NE(PyErr_Occurred(), nullptr); 3758 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3759} 3760 3761TEST_F(AbstractExtensionApiTest, ObjectGetItemCallsDunderGetItem) { 3762 PyRun_SimpleString(R"( 3763class C: 3764 def __getitem__(self, key): 3765 return key 3766c = C() 3767)"); 3768 PyObjectPtr c(mainModuleGet("c")); 3769 PyObjectPtr key(PyLong_FromLong(7)); 3770 PyObjectPtr result(PyObject_GetItem(c, key)); 3771 EXPECT_EQ(result, key); 3772 EXPECT_EQ(PyErr_Occurred(), nullptr); 3773} 3774 3775TEST_F(AbstractExtensionApiTest, ObjectGetItemPropagatesException) { 3776 PyRun_SimpleString(R"( 3777class C: 3778 def __getitem__(self, key): 3779 raise IndexError 3780c = C() 3781)"); 3782 PyObjectPtr c(mainModuleGet("c")); 3783 PyObjectPtr key(PyLong_FromLong(7)); 3784 EXPECT_EQ(PyObject_GetItem(c, key), nullptr); 3785 ASSERT_NE(PyErr_Occurred(), nullptr); 3786 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_IndexError)); 3787} 3788 3789TEST_F(AbstractExtensionApiTest, 3790 MappingGetItemStringWithNullObjRaisesSystemError) { 3791 EXPECT_EQ(PyMapping_GetItemString(nullptr, "hello"), nullptr); 3792 ASSERT_NE(PyErr_Occurred(), nullptr); 3793 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3794} 3795 3796TEST_F(AbstractExtensionApiTest, 3797 MappingGetItemStringWithNullKeyRaisesSystemError) { 3798 PyObjectPtr obj(PyLong_FromLong(1)); 3799 EXPECT_EQ(PyMapping_GetItemString(obj, nullptr), nullptr); 3800 ASSERT_NE(PyErr_Occurred(), nullptr); 3801 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 3802} 3803 3804TEST_F(AbstractExtensionApiTest, 3805 MappingGetItemStringWithNoDunderGetItemRaisesTypeError) { 3806 PyRun_SimpleString(R"( 3807class C: 3808 pass 3809c = C() 3810)"); 3811 PyObjectPtr c(mainModuleGet("c")); 3812 EXPECT_EQ(PyMapping_GetItemString(c, "hello"), nullptr); 3813 ASSERT_NE(PyErr_Occurred(), nullptr); 3814 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3815} 3816 3817TEST_F(AbstractExtensionApiTest, 3818 MappingGetItemStringWithUncallableDunderGetItemRaisesTypeError) { 3819 PyRun_SimpleString(R"( 3820class C: 3821 __getitem__ = 4 3822c = C() 3823)"); 3824 PyObjectPtr c(mainModuleGet("c")); 3825 EXPECT_EQ(PyMapping_GetItemString(c, "hello"), nullptr); 3826 ASSERT_NE(PyErr_Occurred(), nullptr); 3827 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 3828} 3829 3830TEST_F(AbstractExtensionApiTest, MappingGetItemStringCallsDunderGetItem) { 3831 PyRun_SimpleString(R"( 3832class C: 3833 def __getitem__(self, key): 3834 return key 3835c = C() 3836)"); 3837 PyObjectPtr c(mainModuleGet("c")); 3838 const char* key = "hello"; 3839 PyObjectPtr result(PyMapping_GetItemString(c, key)); 3840 EXPECT_EQ(PyErr_Occurred(), nullptr); 3841 EXPECT_TRUE(isUnicodeEqualsCStr(result, key)); 3842} 3843 3844TEST_F(AbstractExtensionApiTest, MappingGetItemStringPropagatesException) { 3845 PyRun_SimpleString(R"( 3846class C: 3847 def __getitem__(self, key): 3848 raise IndexError 3849c = C() 3850)"); 3851 PyObjectPtr c(mainModuleGet("c")); 3852 EXPECT_EQ(PyMapping_GetItemString(c, "hello"), nullptr); 3853 ASSERT_NE(PyErr_Occurred(), nullptr); 3854 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_IndexError)); 3855} 3856 3857TEST_F(AbstractExtensionApiTest, MappingHasKeyWithNullObjReturnsFalse) { 3858 PyObjectPtr obj(PyLong_FromLong(7)); 3859 EXPECT_EQ(PyMapping_HasKey(nullptr, obj), 0); 3860 EXPECT_EQ(PyErr_Occurred(), nullptr); 3861} 3862 3863TEST_F(AbstractExtensionApiTest, MappingHasKeyWithNullKeyReturnsFalse) { 3864 PyObjectPtr obj(PyLong_FromLong(7)); 3865 EXPECT_EQ(PyMapping_HasKey(obj, nullptr), 0); 3866 EXPECT_EQ(PyErr_Occurred(), nullptr); 3867} 3868 3869TEST_F(AbstractExtensionApiTest, MappingHasKeyCallsDunderGetItem) { 3870 PyRun_SimpleString(R"( 3871sideeffect = 0 3872class C: 3873 def __getitem__(self, key): 3874 global sideeffect 3875 sideeffect = 10 3876c = C() 3877)"); 3878 PyObjectPtr c(mainModuleGet("c")); 3879 PyObjectPtr key(PyLong_FromLong(7)); 3880 ASSERT_EQ(PyMapping_HasKey(c, key), 1); 3881 ASSERT_EQ(PyErr_Occurred(), nullptr); 3882 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 3883 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 3884} 3885 3886TEST_F(AbstractExtensionApiTest, 3887 MappingHasKeyReturnsFalseWhenExceptionIsRaised) { 3888 PyRun_SimpleString(R"( 3889class C: 3890 def __getitem__(self, key): 3891 raise IndexError 3892c = C() 3893)"); 3894 PyObjectPtr c(mainModuleGet("c")); 3895 PyObjectPtr key(PyLong_FromLong(7)); 3896 EXPECT_EQ(PyMapping_HasKey(c, key), 0); 3897 EXPECT_EQ(PyErr_Occurred(), nullptr); 3898} 3899 3900TEST_F(AbstractExtensionApiTest, MappingHasKeyStringWithNullObjReturnsFalse) { 3901 EXPECT_EQ(PyMapping_HasKeyString(nullptr, "hello"), 0); 3902 EXPECT_EQ(PyErr_Occurred(), nullptr); 3903} 3904 3905TEST_F(AbstractExtensionApiTest, MappingHasKeyStringWithNullKeyReturnsFalse) { 3906 PyObjectPtr obj(PyLong_FromLong(7)); 3907 EXPECT_EQ(PyMapping_HasKeyString(obj, nullptr), 0); 3908 EXPECT_EQ(PyErr_Occurred(), nullptr); 3909} 3910 3911TEST_F(AbstractExtensionApiTest, MappingHasKeyStringCallsDunderGetItem) { 3912 PyRun_SimpleString(R"( 3913sideeffect = 0 3914class C: 3915 def __getitem__(self, key): 3916 global sideeffect 3917 sideeffect = 10 3918c = C() 3919)"); 3920 PyObjectPtr c(mainModuleGet("c")); 3921 ASSERT_EQ(PyMapping_HasKeyString(c, "hello"), 1); 3922 ASSERT_EQ(PyErr_Occurred(), nullptr); 3923 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 3924 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 3925} 3926 3927TEST_F(AbstractExtensionApiTest, 3928 MappingHasKeyStringReturnsFalseWhenExceptionIsRaised) { 3929 PyRun_SimpleString(R"( 3930class C: 3931 def __getitem__(self, key): 3932 raise IndexError 3933c = C() 3934)"); 3935 PyObjectPtr c(mainModuleGet("c")); 3936 EXPECT_EQ(PyMapping_HasKeyString(c, "hello"), 0); 3937 EXPECT_EQ(PyErr_Occurred(), nullptr); 3938} 3939 3940TEST_F(AbstractExtensionApiTest, MappingKeysWithNoKeysRaisesAttributeError) { 3941 PyRun_SimpleString(R"( 3942class C: 3943 pass 3944c = C() 3945)"); 3946 PyObjectPtr c(mainModuleGet("c")); 3947 EXPECT_EQ(PyMapping_Keys(c), nullptr); 3948 ASSERT_NE(PyErr_Occurred(), nullptr); 3949 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_AttributeError)); 3950} 3951 3952TEST_F(AbstractExtensionApiTest, MappingKeysCallsReturnsListOfKeys) { 3953 PyRun_SimpleString(R"( 3954class C: 3955 def keys(self): 3956 return ["hello", "world"] 3957c = C() 3958)"); 3959 PyObjectPtr c(mainModuleGet("c")); 3960 PyObjectPtr result(PyMapping_Keys(c)); 3961 ASSERT_NE(result, nullptr); 3962 ASSERT_TRUE(PyList_Check(result)); 3963 ASSERT_EQ(PyList_Size(result), 2); 3964 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "hello")); 3965 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "world")); 3966} 3967 3968TEST_F(AbstractExtensionApiTest, MappingKeysCallsReturnsListOfKeysSequence) { 3969 PyRun_SimpleString(R"( 3970class C: 3971 def keys(self): 3972 return ("hello", "world").__iter__() 3973c = C() 3974)"); 3975 PyObjectPtr c(mainModuleGet("c")); 3976 PyObjectPtr result(PyMapping_Keys(c)); 3977 ASSERT_NE(result, nullptr); 3978 ASSERT_TRUE(PyList_Check(result)); 3979 ASSERT_EQ(PyList_Size(result), 2); 3980 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "hello")); 3981 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "world")); 3982} 3983 3984TEST_F(AbstractExtensionApiTest, MappingKeysWithDictSubclassCallsKeys) { 3985 PyRun_SimpleString(R"( 3986class C(dict): 3987 def keys(self): 3988 return ("hello", "world").__iter__() 3989c = C() 3990c["a"] = 1 3991c["b"] = 2 3992c["c"] = 3 3993)"); 3994 PyObjectPtr c(mainModuleGet("c")); 3995 PyObjectPtr result(PyMapping_Keys(c)); 3996 ASSERT_NE(result, nullptr); 3997 ASSERT_TRUE(PyList_Check(result)); 3998 ASSERT_EQ(PyList_Size(result), 2); 3999 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "hello")); 4000 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "world")); 4001} 4002 4003TEST_F(AbstractExtensionApiTest, MappingItemsWithNoItemsRaisesAttributeError) { 4004 PyRun_SimpleString(R"( 4005class C: 4006 pass 4007c = C() 4008)"); 4009 PyObjectPtr c(mainModuleGet("c")); 4010 EXPECT_EQ(PyMapping_Items(c), nullptr); 4011 ASSERT_NE(PyErr_Occurred(), nullptr); 4012 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_AttributeError)); 4013} 4014 4015TEST_F(AbstractExtensionApiTest, MappingItemsCallsReturnsListOfItems) { 4016 PyRun_SimpleString(R"( 4017class C: 4018 def items(self): 4019 return ["hello", "world"] 4020c = C() 4021)"); 4022 PyObjectPtr c(mainModuleGet("c")); 4023 PyObjectPtr result(PyMapping_Items(c)); 4024 ASSERT_NE(result, nullptr); 4025 ASSERT_TRUE(PyList_Check(result)); 4026 ASSERT_EQ(PyList_Size(result), 2); 4027 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "hello")); 4028 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "world")); 4029} 4030 4031TEST_F(AbstractExtensionApiTest, MappingItemsCallsReturnsListOfItemsSequence) { 4032 PyRun_SimpleString(R"( 4033class C: 4034 def items(self): 4035 return ("hello", "world").__iter__() 4036c = C() 4037)"); 4038 PyObjectPtr c(mainModuleGet("c")); 4039 PyObjectPtr result(PyMapping_Items(c)); 4040 ASSERT_NE(result, nullptr); 4041 ASSERT_TRUE(PyList_Check(result)); 4042 ASSERT_EQ(PyList_Size(result), 2); 4043 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "hello")); 4044 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "world")); 4045} 4046 4047TEST_F(AbstractExtensionApiTest, MappingItemsWithDictSubclassCallsItems) { 4048 PyRun_SimpleString(R"( 4049class C(dict): 4050 def items(self): 4051 return ("hello", "world").__iter__() 4052c = C() 4053c["a"] = 1 4054c["b"] = 2 4055c["c"] = 3 4056)"); 4057 PyObjectPtr c(mainModuleGet("c")); 4058 PyObjectPtr result(PyMapping_Items(c)); 4059 ASSERT_NE(result, nullptr); 4060 ASSERT_TRUE(PyList_Check(result)); 4061 ASSERT_EQ(PyList_Size(result), 2); 4062 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "hello")); 4063 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "world")); 4064} 4065 4066TEST_F(AbstractExtensionApiTest, 4067 MappingValuesWithNoValuesRaisesAttributeError) { 4068 PyRun_SimpleString(R"( 4069class C: 4070 pass 4071c = C() 4072)"); 4073 PyObjectPtr c(mainModuleGet("c")); 4074 EXPECT_EQ(PyMapping_Values(c), nullptr); 4075 ASSERT_NE(PyErr_Occurred(), nullptr); 4076 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_AttributeError)); 4077} 4078 4079TEST_F(AbstractExtensionApiTest, MappingValuesCallsReturnsListOfValues) { 4080 PyRun_SimpleString(R"( 4081class C: 4082 def values(self): 4083 return ["hello", "world"] 4084c = C() 4085)"); 4086 PyObjectPtr c(mainModuleGet("c")); 4087 PyObjectPtr result(PyMapping_Values(c)); 4088 ASSERT_NE(result, nullptr); 4089 ASSERT_TRUE(PyList_Check(result)); 4090 ASSERT_EQ(PyList_Size(result), 2); 4091 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "hello")); 4092 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "world")); 4093} 4094 4095TEST_F(AbstractExtensionApiTest, 4096 MappingValuesCallsReturnsListOfValuesSequence) { 4097 PyRun_SimpleString(R"( 4098class C: 4099 def values(self): 4100 return ("hello", "world").__iter__() 4101c = C() 4102)"); 4103 PyObjectPtr c(mainModuleGet("c")); 4104 PyObjectPtr result(PyMapping_Values(c)); 4105 ASSERT_NE(result, nullptr); 4106 ASSERT_TRUE(PyList_Check(result)); 4107 ASSERT_EQ(PyList_Size(result), 2); 4108 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "hello")); 4109 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "world")); 4110} 4111 4112TEST_F(AbstractExtensionApiTest, MappingValuesWithDictSubclassCallsValues) { 4113 PyRun_SimpleString(R"( 4114class C(dict): 4115 def values(self): 4116 return ("hello", "world").__iter__() 4117c = C() 4118c["a"] = 1 4119c["b"] = 2 4120c["c"] = 3 4121)"); 4122 PyObjectPtr c(mainModuleGet("c")); 4123 PyObjectPtr result(PyMapping_Values(c)); 4124 ASSERT_NE(result, nullptr); 4125 ASSERT_TRUE(PyList_Check(result)); 4126 ASSERT_EQ(PyList_Size(result), 2); 4127 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 0), "hello")); 4128 EXPECT_TRUE(isUnicodeEqualsCStr(PyList_GetItem(result, 1), "world")); 4129} 4130 4131TEST_F(AbstractExtensionApiTest, ObjectSetItemWithNullObjRaisesSystemError) { 4132 PyObjectPtr obj(PyLong_FromLong(1)); 4133 EXPECT_EQ(PyObject_SetItem(nullptr, obj, obj), -1); 4134 ASSERT_NE(PyErr_Occurred(), nullptr); 4135 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 4136} 4137 4138TEST_F(AbstractExtensionApiTest, ObjectSetItemWithNullKeyRaisesSystemError) { 4139 PyObjectPtr obj(PyLong_FromLong(1)); 4140 EXPECT_EQ(PyObject_SetItem(obj, nullptr, obj), -1); 4141 ASSERT_NE(PyErr_Occurred(), nullptr); 4142 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 4143} 4144 4145TEST_F(AbstractExtensionApiTest, ObjectSetItemWithNullValueRaisesSystemError) { 4146 PyObjectPtr obj(PyLong_FromLong(1)); 4147 EXPECT_EQ(PyObject_SetItem(obj, obj, nullptr), -1); 4148 ASSERT_NE(PyErr_Occurred(), nullptr); 4149 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 4150} 4151 4152TEST_F(AbstractExtensionApiTest, 4153 ObjectSetItemWithNoDunderSetItemRaisesTypeError) { 4154 PyRun_SimpleString(R"( 4155class C: 4156 pass 4157c = C() 4158)"); 4159 PyObjectPtr c(mainModuleGet("c")); 4160 PyObjectPtr obj(PyLong_FromLong(1)); 4161 EXPECT_EQ(PyObject_SetItem(c, obj, obj), -1); 4162 ASSERT_NE(PyErr_Occurred(), nullptr); 4163 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 4164} 4165 4166TEST_F(AbstractExtensionApiTest, 4167 ObjectSetItemWithUncallableDunderSetItemRaisesTypeError) { 4168 PyRun_SimpleString(R"( 4169class C: 4170 __setitem__ = 4 4171c = C() 4172)"); 4173 PyObjectPtr c(mainModuleGet("c")); 4174 PyObjectPtr obj(PyLong_FromLong(1)); 4175 EXPECT_EQ(PyObject_SetItem(c, obj, obj), -1); 4176 ASSERT_NE(PyErr_Occurred(), nullptr); 4177 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 4178} 4179 4180TEST_F(AbstractExtensionApiTest, ObjectSetItemCallsDunderSetItem) { 4181 PyRun_SimpleString(R"( 4182sideeffect = 0 4183class C: 4184 def __setitem__(self, key, val): 4185 global sideeffect 4186 sideeffect = 10 4187c = C() 4188)"); 4189 PyObjectPtr c(mainModuleGet("c")); 4190 PyObjectPtr obj(PyLong_FromLong(1)); 4191 ASSERT_EQ(PyObject_SetItem(c, obj, obj), 0); 4192 ASSERT_EQ(PyErr_Occurred(), nullptr); 4193 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 4194 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 4195} 4196 4197TEST_F(AbstractExtensionApiTest, ObjectSetItemPropagatesException) { 4198 PyRun_SimpleString(R"( 4199class C: 4200 def __setitem__(self, key, value): 4201 raise IndexError 4202c = C() 4203)"); 4204 PyObjectPtr c(mainModuleGet("c")); 4205 PyObjectPtr obj(PyLong_FromLong(7)); 4206 EXPECT_EQ(PyObject_SetItem(c, obj, obj), -1); 4207 ASSERT_NE(PyErr_Occurred(), nullptr); 4208 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_IndexError)); 4209} 4210 4211TEST_F(AbstractExtensionApiTest, 4212 MappingSetItemStringWithNullObjRaisesSystemError) { 4213 PyObjectPtr obj(PyLong_FromLong(1)); 4214 EXPECT_EQ(PyMapping_SetItemString(nullptr, "hello", obj), -1); 4215 ASSERT_NE(PyErr_Occurred(), nullptr); 4216 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 4217} 4218 4219TEST_F(AbstractExtensionApiTest, 4220 MappingSetItemStringWithNullKeyRaisesSystemError) { 4221 PyObjectPtr obj(PyLong_FromLong(1)); 4222 EXPECT_EQ(PyMapping_SetItemString(obj, nullptr, obj), -1); 4223 ASSERT_NE(PyErr_Occurred(), nullptr); 4224 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 4225} 4226 4227TEST_F(AbstractExtensionApiTest, 4228 MappingSetItemStringWithNullValueRaisesSystemError) { 4229 PyObjectPtr obj(PyLong_FromLong(1)); 4230 EXPECT_EQ(PyMapping_SetItemString(obj, "hello", nullptr), -1); 4231 ASSERT_NE(PyErr_Occurred(), nullptr); 4232 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); 4233} 4234 4235TEST_F(AbstractExtensionApiTest, 4236 MappingSetItemStringWithNoDunderSetItemRaisesTypeError) { 4237 PyRun_SimpleString(R"( 4238class C: 4239 pass 4240c = C() 4241)"); 4242 PyObjectPtr c(mainModuleGet("c")); 4243 PyObjectPtr obj(PyLong_FromLong(1)); 4244 EXPECT_EQ(PyMapping_SetItemString(c, "hello", obj), -1); 4245 ASSERT_NE(PyErr_Occurred(), nullptr); 4246 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 4247} 4248 4249TEST_F(AbstractExtensionApiTest, 4250 MappingSetItemStringWithUncallableDunderSetItemRaisesTypeError) { 4251 PyRun_SimpleString(R"( 4252class C: 4253 __setitem__ = 4 4254c = C() 4255)"); 4256 PyObjectPtr c(mainModuleGet("c")); 4257 PyObjectPtr obj(PyLong_FromLong(1)); 4258 EXPECT_EQ(PyMapping_SetItemString(c, "hello", obj), -1); 4259 ASSERT_NE(PyErr_Occurred(), nullptr); 4260 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 4261} 4262 4263TEST_F(AbstractExtensionApiTest, MappingSetItemStringCallsDunderSetItem) { 4264 PyRun_SimpleString(R"( 4265sideeffect = 0 4266class C: 4267 def __setitem__(self, key, val): 4268 global sideeffect 4269 sideeffect = 10 4270c = C() 4271)"); 4272 PyObjectPtr c(mainModuleGet("c")); 4273 PyObjectPtr obj(PyLong_FromLong(1)); 4274 ASSERT_EQ(PyMapping_SetItemString(c, "hello", obj), 0); 4275 ASSERT_EQ(PyErr_Occurred(), nullptr); 4276 PyObjectPtr sideeffect(mainModuleGet("sideeffect")); 4277 EXPECT_EQ(PyLong_AsLong(sideeffect), 10); 4278} 4279 4280TEST_F(AbstractExtensionApiTest, MappingSetItemStringPropagatesException) { 4281 PyRun_SimpleString(R"( 4282class C: 4283 def __setitem__(self, key, value): 4284 raise IndexError 4285c = C() 4286)"); 4287 PyObjectPtr c(mainModuleGet("c")); 4288 PyObjectPtr obj(PyLong_FromLong(7)); 4289 EXPECT_EQ(PyMapping_SetItemString(c, "hello", obj), -1); 4290 ASSERT_NE(PyErr_Occurred(), nullptr); 4291 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_IndexError)); 4292} 4293 4294TEST_F(AbstractExtensionApiTest, 4295 ObjectFormatWithNonStrFormatSpecRaisesTypeErrorPyro) { 4296 EXPECT_EQ(PyObject_Format(Py_None, Py_None), nullptr); 4297 ASSERT_NE(PyErr_Occurred(), nullptr); 4298 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 4299} 4300 4301TEST_F(AbstractExtensionApiTest, ObjectFormatCallsDunderFormat) { 4302 PyRun_SimpleString(R"( 4303last_arguments = None 4304class C: 4305 def __format__(self, format_spec): 4306 global last_arguments 4307 last_arguments = (self, format_spec) 4308 return "foo" 4309c = C() 4310)"); 4311 PyObjectPtr c(mainModuleGet("c")); 4312 PyObjectPtr fmt(PyUnicode_FromString("foo")); 4313 PyObjectPtr result(PyObject_Format(c, fmt)); 4314 ASSERT_EQ(PyErr_Occurred(), nullptr); 4315 EXPECT_TRUE(isUnicodeEqualsCStr(result, "foo")); 4316 PyObjectPtr last_arguments(mainModuleGet("last_arguments")); 4317 ASSERT_TRUE(PyTuple_Check(last_arguments)); 4318 EXPECT_EQ(PyTuple_GetItem(last_arguments, 0), c); 4319 EXPECT_EQ(PyTuple_GetItem(last_arguments, 1), fmt); 4320} 4321 4322TEST_F(AbstractExtensionApiTest, 4323 ObjectFormatWithDunderFormatReturningNonStrRaisesTypeError) { 4324 PyRun_SimpleString(R"( 4325class C: 4326 def __format__(self, format_spec): 4327 return 7 4328c = C() 4329)"); 4330 PyObjectPtr c(mainModuleGet("c")); 4331 EXPECT_EQ(PyObject_Format(c, nullptr), nullptr); 4332 ASSERT_NE(PyErr_Occurred(), nullptr); 4333 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 4334} 4335 4336} // namespace testing 4337} // namespace py