ext/Objects/longobject-test.cpp (952 lines of code) (raw):

// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) #include <cmath> #include "Python.h" #include "gtest/gtest.h" #include "capi-fixture.h" #include "capi-testing.h" namespace py { namespace testing { using LongExtensionApiTest = ExtensionApi; TEST_F(LongExtensionApiTest, GCDWithSameNumberReturnsSameNumber) { PyObjectPtr dividend(PyLong_FromLong(3)); PyObjectPtr divisor(PyLong_FromLong(3)); EXPECT_EQ(PyLong_AsLong(_PyLong_GCD(dividend, divisor)), 3); } TEST_F(LongExtensionApiTest, GCDWithDifferentNumbersReturnsGCD) { PyObjectPtr dividend(PyLong_FromLong(3)); PyObjectPtr divisor(PyLong_FromLong(6)); EXPECT_EQ(PyLong_AsLong(_PyLong_GCD(dividend, divisor)), 3); } TEST_F(LongExtensionApiTest, GCDWithOneNegativeReturnsPositive) { PyObjectPtr dividend(PyLong_FromLong(-3)); PyObjectPtr divisor(PyLong_FromLong(3)); EXPECT_EQ(PyLong_AsLong(_PyLong_GCD(dividend, divisor)), 3); } TEST_F(LongExtensionApiTest, GCDWithBothNegativeReturnsPositive) { PyObjectPtr dividend(PyLong_FromLong(-1)); PyObjectPtr divisor(PyLong_FromLong(-2)); EXPECT_EQ(PyLong_AsLong(_PyLong_GCD(dividend, divisor)), 1); } TEST_F(LongExtensionApiTest, GCDWithZeroAndThreeReturnsThree) { PyObjectPtr dividend(PyLong_FromLong(0)); PyObjectPtr divisor(PyLong_FromLong(3)); EXPECT_EQ(PyLong_AsLong(_PyLong_GCD(dividend, divisor)), 3); } TEST_F(LongExtensionApiTest, GCDWithThreeAndZeroReturnsThree) { PyObjectPtr dividend(PyLong_FromLong(3)); PyObjectPtr divisor(PyLong_FromLong(0)); EXPECT_EQ(PyLong_AsLong(_PyLong_GCD(dividend, divisor)), 3); } TEST_F(LongExtensionApiTest, GCDWithZeroandNegativeReturnsOne) { PyObjectPtr dividend(PyLong_FromLong(0)); PyObjectPtr divisor(PyLong_FromLong(-1)); EXPECT_EQ(PyLong_AsLong(_PyLong_GCD(dividend, divisor)), 1); } TEST_F(LongExtensionApiTest, GCDWithsSameLargeIntsReturnsSame) { PyObjectPtr dividend(PyLong_FromString("7FFFFFFFFFFFFFFF", nullptr, 16)); PyObjectPtr divisor(PyLong_FromString("7FFFFFFFFFFFFFFF", nullptr, 16)); PyObjectPtr expected(PyLong_FromString("7FFFFFFFFFFFFFFF", nullptr, 16)); int res = PyObject_RichCompareBool(_PyLong_GCD(dividend, divisor), expected, Py_EQ); EXPECT_EQ(res, 1); } TEST_F(LongExtensionApiTest, GCDWithLargeIntsReturnsGCD) { PyObjectPtr dividend(PyLong_FromString("7FFFFFFFFFFFFFFF", nullptr, 16)); PyObjectPtr divisor(PyLong_FromString("FFFFFFFFFFFFFFFE", nullptr, 16)); PyObjectPtr expected(PyLong_FromString("7FFFFFFFFFFFFFFF", nullptr, 16)); int res = PyObject_RichCompareBool(_PyLong_GCD(dividend, divisor), expected, Py_EQ); EXPECT_EQ(res, 1); } TEST_F(LongExtensionApiTest, GCDWithLargeIntsReturnsSmallIntGCD) { PyObjectPtr dividend(PyLong_FromString("FFFFFFFFFFFFFFFE", nullptr, 16)); PyObjectPtr divisor(PyLong_FromString("10000000000000002", nullptr, 16)); EXPECT_EQ(PyLong_AsLong(_PyLong_GCD(dividend, divisor)), 2); } TEST_F(LongExtensionApiTest, CheckWithIntReturnsTrue) { PyObjectPtr pylong(PyLong_FromLong(10)); EXPECT_TRUE(PyLong_Check(pylong)); EXPECT_TRUE(PyLong_CheckExact(pylong)); pylong = PyLong_FromLongLong(10); EXPECT_TRUE(PyLong_Check(pylong)); EXPECT_TRUE(PyLong_CheckExact(pylong)); pylong = PyLong_FromUnsignedLong(10); EXPECT_TRUE(PyLong_Check(pylong)); EXPECT_TRUE(PyLong_CheckExact(pylong)); pylong = PyLong_FromUnsignedLongLong(10); EXPECT_TRUE(PyLong_Check(pylong)); EXPECT_TRUE(PyLong_CheckExact(pylong)); pylong = PyLong_FromSsize_t(10); EXPECT_TRUE(PyLong_Check(pylong)); EXPECT_TRUE(PyLong_CheckExact(pylong)); } TEST_F(LongExtensionApiTest, CheckWithIntSubclass) { PyRun_SimpleString(R"( class X(int): pass x = X() )"); PyObjectPtr x(mainModuleGet("x")); EXPECT_TRUE(PyLong_Check(x)); EXPECT_FALSE(PyLong_CheckExact(x)); } TEST_F(LongExtensionApiTest, CheckExactWithBoolReturnsFalse) { EXPECT_TRUE(PyLong_Check(Py_False)); EXPECT_TRUE(PyLong_Check(Py_True)); EXPECT_FALSE(PyLong_CheckExact(Py_False)); EXPECT_FALSE(PyLong_CheckExact(Py_True)); } TEST_F(LongExtensionApiTest, CheckWithTypeReturnsFalse) { PyObjectPtr pylong(PyLong_FromLong(10)); PyObject* type = reinterpret_cast<PyObject*>(Py_TYPE(pylong)); EXPECT_FALSE(PyLong_Check(type)); EXPECT_FALSE(PyLong_CheckExact(type)); } TEST_F(LongExtensionApiTest, AsDoubleWithNullRaisesSystemError) { EXPECT_EQ(PyLong_AsDouble(nullptr), -1.0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); } TEST_F(LongExtensionApiTest, AsDoubleWithNonIntRaisesTypeError) { PyObjectPtr obj(PyList_New(0)); EXPECT_EQ(PyLong_AsDouble(obj), -1.0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, AsDoubleWithSmallIntReturnsDouble) { PyObjectPtr obj(PyLong_FromLong(10)); EXPECT_EQ(PyLong_AsDouble(obj), 10.0); EXPECT_EQ(PyErr_Occurred(), nullptr); } TEST_F(LongExtensionApiTest, AsDoubleWithNegativeIntReturnsDouble) { PyObjectPtr obj(PyLong_FromLong(-40)); EXPECT_EQ(PyLong_AsDouble(obj), -40.0); EXPECT_EQ(PyErr_Occurred(), nullptr); } TEST_F(LongExtensionApiTest, AsDoubleWithLargeIntReturnsDouble) { unsigned char bytes[9] = {1}; double expected = std::pow(2, 64); PyObjectPtr obj(_PyLong_FromByteArray(bytes, sizeof(bytes), false, false)); EXPECT_EQ(PyLong_AsDouble(obj), expected); EXPECT_EQ(PyErr_Occurred(), nullptr); } TEST_F(LongExtensionApiTest, AsDoubleWithIntSubclassReturnsDouble) { PyRun_SimpleString(R"( class X(int): pass x = X(42) )"); PyObjectPtr x(mainModuleGet("x")); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(PyLong_AsDouble(x), 42.0); } TEST_F(LongExtensionApiTest, AsDoubleWithOverflowRaisesOverflowError) { unsigned char bytes[129] = {1}; PyObjectPtr obj(_PyLong_FromByteArray(bytes, sizeof(bytes), false, false)); EXPECT_EQ(PyLong_AsDouble(obj), -1.0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); } TEST_F(LongExtensionApiTest, AsIntWithNullRaisesSystemError) { ASSERT_EQ(_PyLong_AsInt(nullptr), -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); } TEST_F(LongExtensionApiTest, AsIntWithNonIntegerRaisesTypeError) { ASSERT_EQ(_PyLong_AsInt(Py_None), -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, AsIntWithLongMaxRaisesOverflowError) { PyObjectPtr num(PyLong_FromLongLong(static_cast<long long>(INT_MAX) + 1)); ASSERT_EQ(_PyLong_AsInt(num), -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); } TEST_F(LongExtensionApiTest, AsIntWithIntSubclassReturnsInt) { PyRun_SimpleString(R"( class X(int): pass x = X(42) )"); PyObjectPtr x(mainModuleGet("x")); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(_PyLong_AsInt(x), 42); } TEST_F(LongExtensionApiTest, AsIntWithInvalidDunderIntRaisesTypeError) { PyRun_SimpleString(R"( class X: def __int__(self): return "" x = X() )"); PyObjectPtr x(mainModuleGet("x")); ASSERT_EQ(_PyLong_AsInt(x), -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, AsIntWithValidDunderIntReturnsInt) { PyRun_SimpleString(R"( class X: def __int__(self): return 42 x = X() )"); PyObjectPtr x(mainModuleGet("x")); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(_PyLong_AsInt(x), 42); } TEST_F(LongExtensionApiTest, AsLongWithNullReturnsNegative) { long res = PyLong_AsLong(nullptr); EXPECT_EQ(res, -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_SystemError)); } TEST_F(LongExtensionApiTest, AsLongWithNonIntegerReturnsNegative) { long res = PyLong_AsLong(Py_None); EXPECT_EQ(res, -1); EXPECT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, AsLongWithIntSubclassReturnsLong) { PyRun_SimpleString(R"( class X(int): pass x = X(42) )"); PyObjectPtr x(mainModuleGet("x")); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(PyLong_AsLong(x), 42); } TEST_F(LongExtensionApiTest, AsLongWithInvalidDunderInt) { PyRun_SimpleString(R"( class X: def __int__(self): return "not an int" x = X() )"); PyObjectPtr x(mainModuleGet("x")); EXPECT_EQ(PyLong_AsLong(x), -1l); EXPECT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, AsLongWithValidDunderInt) { PyRun_SimpleString(R"( class X: def __int__(self): return -7 x = X() )"); PyObjectPtr x(mainModuleGet("x")); EXPECT_EQ(PyLong_AsLong(x), -7); EXPECT_EQ(PyErr_Occurred(), nullptr); } TEST_F(LongExtensionApiTest, AsLongWithBoolReturnsLong) { EXPECT_EQ(PyLong_AsLong(Py_True), 1); EXPECT_EQ(PyLong_AsLong(Py_False), 0); } TEST_F(LongExtensionApiTest, FromStringReturnsLong) { PyObjectPtr long0(PyLong_FromString("1", nullptr, 10)); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyLong_CheckExact(long0)); EXPECT_EQ(PyLong_AsSsize_t(long0), 1); PyObjectPtr long1(PyLong_FromString("1000", nullptr, 10)); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyLong_CheckExact(long1)); EXPECT_EQ(PyLong_AsSsize_t(long1), 1000); PyObjectPtr long2(PyLong_FromString("100", nullptr, 2)); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyLong_CheckExact(long2)); EXPECT_EQ(PyLong_AsSsize_t(long2), 4); } TEST_F(LongExtensionApiTest, FromStringWithInvalidIntRaisesValueError) { EXPECT_EQ(PyLong_FromString("foo", nullptr, 10), nullptr); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); } TEST_F(LongExtensionApiTest, FromLongReturnsLong) { const int val = 10; PyObjectPtr pylong(PyLong_FromLong(val)); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyLong_CheckExact(pylong)); EXPECT_EQ(PyLong_AsLong(pylong), val); EXPECT_EQ(PyLong_AsLongLong(pylong), val); EXPECT_EQ(PyLong_AsSsize_t(pylong), val); auto const val2 = std::numeric_limits<long>::min(); PyObjectPtr pylong2(PyLong_FromLong(val2)); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyLong_CheckExact(pylong2)); EXPECT_EQ(PyLong_AsLong(pylong2), val2); auto const val3 = std::numeric_limits<long>::max(); PyObjectPtr pylong3(PyLong_FromLong(val3)); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyLong_CheckExact(pylong3)); EXPECT_EQ(PyLong_AsLong(pylong3), val3); } TEST_F(LongExtensionApiTest, FromUnsignedReturnsLong) { auto const ulmax = std::numeric_limits<unsigned long>::max(); PyObjectPtr pylong(PyLong_FromUnsignedLong(ulmax)); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyLong_CheckExact(pylong)); EXPECT_EQ(PyLong_AsUnsignedLong(pylong), ulmax); EXPECT_EQ(PyLong_AsUnsignedLongLong(pylong), ulmax); EXPECT_EQ(PyLong_AsSize_t(pylong), ulmax); auto const ullmax = std::numeric_limits<unsigned long long>::max(); PyObjectPtr pylong2(PyLong_FromUnsignedLongLong(ullmax)); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyLong_CheckExact(pylong2)); EXPECT_EQ(PyLong_AsUnsignedLongLong(pylong2), ullmax); auto const uval = 1234UL; PyObjectPtr pylong3(PyLong_FromUnsignedLong(uval)); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyLong_CheckExact(pylong3)); EXPECT_EQ(PyLong_AsUnsignedLong(pylong3), uval); } static PyObject* lshift(long num, long shift) { PyObject* num_obj = PyLong_FromLong(num); PyObject* shift_obj = PyLong_FromLong(shift); PyObject* result = PyNumber_Lshift(num_obj, shift_obj); Py_DECREF(num_obj); Py_DECREF(shift_obj); return result; } TEST_F(LongExtensionApiTest, NumBitsWithZeroReturnsZero) { PyObjectPtr num(PyLong_FromLong(0)); EXPECT_EQ(_PyLong_NumBits(num), size_t{0}); } TEST_F(LongExtensionApiTest, NumBitsWithOneReturnsOne) { PyObjectPtr num(PyLong_FromLong(1)); EXPECT_EQ(_PyLong_NumBits(num), size_t{1}); } TEST_F(LongExtensionApiTest, NumBitsWithNegativeOneReturnsOne) { PyObjectPtr num(PyLong_FromLong(-1)); EXPECT_EQ(_PyLong_NumBits(num), size_t{1}); } TEST_F(LongExtensionApiTest, NumBitsWithTwoReturnsTwo) { PyObjectPtr num(PyLong_FromLong(2)); EXPECT_EQ(_PyLong_NumBits(num), size_t{2}); } TEST_F(LongExtensionApiTest, NumBitsWithNegativeTwoReturnsTwo) { PyObjectPtr num(PyLong_FromLong(-2)); EXPECT_EQ(_PyLong_NumBits(num), size_t{2}); } TEST_F(LongExtensionApiTest, NumBitsWithThreeReturnsTwo) { PyObjectPtr num(PyLong_FromLong(3)); EXPECT_EQ(_PyLong_NumBits(num), size_t{2}); } TEST_F(LongExtensionApiTest, NumBitsWithNegativeThreeReturnsTwo) { PyObjectPtr num(PyLong_FromLong(-3)); EXPECT_EQ(_PyLong_NumBits(num), size_t{2}); } TEST_F(LongExtensionApiTest, NumBitsWithFourReturnsThree) { PyObjectPtr num(PyLong_FromLong(4)); EXPECT_EQ(_PyLong_NumBits(num), size_t{3}); } TEST_F(LongExtensionApiTest, NumBitsWithNegativeFourReturnsThree) { PyObjectPtr num(PyLong_FromLong(-4)); EXPECT_EQ(_PyLong_NumBits(num), size_t{3}); } TEST_F(LongExtensionApiTest, NumBitsCpythonTests) { PyObjectPtr i0(PyLong_FromLong(0x7fffL)); EXPECT_EQ(_PyLong_NumBits(i0), size_t{15}); PyObjectPtr negative_i0(PyLong_FromLong(-0x7fffL)); EXPECT_EQ(_PyLong_NumBits(negative_i0), size_t{15}); PyObjectPtr i1(PyLong_FromLong(0xffffL)); EXPECT_EQ(_PyLong_NumBits(i1), size_t{16}); PyObjectPtr negative_i1(PyLong_FromLong(-0xffffL)); EXPECT_EQ(_PyLong_NumBits(negative_i1), size_t{16}); PyObjectPtr i2(PyLong_FromLong(0xfffffffL)); EXPECT_EQ(_PyLong_NumBits(i2), size_t{28}); PyObjectPtr negative_i2(PyLong_FromLong(-0xfffffffL)); EXPECT_EQ(_PyLong_NumBits(negative_i2), size_t{28}); PyObjectPtr i3(PyLong_FromLong(PY_SSIZE_T_MAX)); EXPECT_EQ(_PyLong_NumBits(i3), size_t{63}); PyObjectPtr negative_i3(PyLong_FromLong(PY_SSIZE_T_MIN)); EXPECT_EQ(_PyLong_NumBits(negative_i3), size_t{64}); } TEST_F(LongExtensionApiTest, Overflow) { PyObjectPtr pylong(lshift(1, 100)); EXPECT_EQ(PyLong_AsUnsignedLong(pylong), -1UL); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); PyErr_Clear(); EXPECT_EQ(PyLong_AsLong(pylong), -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); PyErr_Clear(); EXPECT_EQ(PyLong_AsSsize_t(pylong), -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); PyErr_Clear(); pylong = PyLong_FromLong(-123); EXPECT_EQ(PyLong_AsUnsignedLongLong(pylong), -1ULL); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); } TEST_F(LongExtensionApiTest, AsLongAndOverflow) { auto const ulmax = std::numeric_limits<unsigned long>::max(); auto const lmax = std::numeric_limits<long>::max(); PyObjectPtr pylong(PyLong_FromUnsignedLong(ulmax)); ASSERT_EQ(PyErr_Occurred(), nullptr); int overflow = 0; EXPECT_EQ(PyLong_AsLongAndOverflow(pylong, &overflow), -1); EXPECT_EQ(overflow, 1); overflow = 0; EXPECT_EQ(PyLong_AsLongLongAndOverflow(pylong, &overflow), -1); EXPECT_EQ(overflow, 1); pylong = PyLong_FromLong(lmax); ASSERT_EQ(PyErr_Occurred(), nullptr); overflow = 1; EXPECT_EQ(PyLong_AsLongAndOverflow(pylong, &overflow), lmax); EXPECT_EQ(overflow, 0); overflow = 1; EXPECT_EQ(PyLong_AsLongLongAndOverflow(pylong, &overflow), lmax); EXPECT_EQ(overflow, 0); pylong = lshift(-1, 100); overflow = 0; EXPECT_EQ(PyLong_AsLongAndOverflow(pylong, &overflow), -1); EXPECT_EQ(overflow, -1); overflow = 0; EXPECT_EQ(PyLong_AsLongLongAndOverflow(pylong, &overflow), -1); EXPECT_EQ(overflow, -1); } TEST_F(LongExtensionApiTest, AsUnsignedLongMaskWithMax) { auto const ulmax = std::numeric_limits<unsigned long>::max(); PyObjectPtr pylong(PyLong_FromUnsignedLong(ulmax)); EXPECT_EQ(PyLong_AsUnsignedLongMask(pylong), ulmax); EXPECT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(PyLong_AsUnsignedLongLongMask(pylong), ulmax); EXPECT_EQ(PyErr_Occurred(), nullptr); auto const ullmax = std::numeric_limits<unsigned long long>::max(); pylong = PyLong_FromUnsignedLongLong(ullmax); EXPECT_EQ(PyLong_AsUnsignedLongLongMask(pylong), ullmax); EXPECT_EQ(PyErr_Occurred(), nullptr); } TEST_F(LongExtensionApiTest, AsUnsignedLongMaskWithLargeInt) { PyObjectPtr largeint(lshift(1, 100)); PyObjectPtr pylong(PyNumber_Or(largeint, PyObjectPtr(PyLong_FromLong(123)))); EXPECT_EQ(PyLong_AsUnsignedLongMask(pylong), 123UL); EXPECT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(PyLong_AsUnsignedLongLongMask(pylong), 123ULL); EXPECT_EQ(PyErr_Occurred(), nullptr); } TEST_F(LongExtensionApiTest, AsUnsignedLongMaskWithNegative) { PyObjectPtr pylong(PyLong_FromLong(-17)); EXPECT_EQ(PyLong_AsUnsignedLongMask(pylong), -17UL); EXPECT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(PyLong_AsUnsignedLongLongMask(pylong), -17ULL); EXPECT_EQ(PyErr_Occurred(), nullptr); } TEST_F(LongExtensionApiTest, FromLongWithZeroReturnsZero) { PyObjectPtr pylong(PyLong_FromLong(0)); ASSERT_EQ(PyErr_Occurred(), nullptr); ASSERT_TRUE(PyLong_CheckExact(pylong)); EXPECT_EQ(PyLong_AsLong(pylong), 0); } TEST_F(LongExtensionApiTest, AsByteArrayUnsignedWithNegativeRaisesOverflowError) { PyObjectPtr num(PyLong_FromLong(-1)); PyLongObject* obj = num.asLongObject(); unsigned char dst[1]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, false), -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); } TEST_F(LongExtensionApiTest, AsByteArrayUnsignedWithZeroWritesZero) { PyObjectPtr num(PyLong_FromLong(0)); PyLongObject* obj = num.asLongObject(); unsigned char dst[1]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, false), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0); } TEST_F(LongExtensionApiTest, AsByteArrayUnsignedWritesMaxUnsignedByte) { PyObjectPtr num(PyLong_FromLong(0xff)); PyLongObject* obj = num.asLongObject(); unsigned char dst[1]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, false), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0xff); } TEST_F(LongExtensionApiTest, AsByteArrayUnsignedOverflowWritesByteAndRaisesOverflowError) { PyObjectPtr num(PyLong_FromLong(0x0100)); PyLongObject* obj = num.asLongObject(); unsigned char dst[1]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, true), -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); EXPECT_EQ(dst[0], 0x00); } TEST_F(LongExtensionApiTest, AsByteArrayUnsignedWritesBytesBigEndian) { PyObjectPtr num(PyLong_FromLong(0xface)); PyLongObject* obj = num.asLongObject(); unsigned char dst[3]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, false), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0x00); EXPECT_EQ(dst[1], 0xfa); EXPECT_EQ(dst[2], 0xce); } TEST_F(LongExtensionApiTest, AsByteArrayUnsigedWritesBytesLittleEndian) { PyObjectPtr num(PyLong_FromLong(0xface)); PyLongObject* obj = num.asLongObject(); unsigned char dst[3]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), true, false), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0xce); EXPECT_EQ(dst[1], 0xfa); EXPECT_EQ(dst[2], 0x00); } TEST_F(LongExtensionApiTest, AsByteArraySignedWritesMaxSignedByte) { PyObjectPtr num(PyLong_FromLong(0x7f)); PyLongObject* obj = num.asLongObject(); unsigned char dst[1]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, true), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0x7f); } TEST_F(LongExtensionApiTest, AsByteArraySignedWritesMinSignedByte) { PyObjectPtr num(PyLong_FromLong(-0x80)); PyLongObject* obj = num.asLongObject(); unsigned char dst[1]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, true), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0x80); } TEST_F(LongExtensionApiTest, AsByteArraySignedOverflowWritesByteAndRaisesOverflowError) { PyObjectPtr num(PyLong_FromLong(0x80)); PyLongObject* obj = num.asLongObject(); unsigned char dst[1]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, true), -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); EXPECT_EQ(dst[0], 0x80); } TEST_F(LongExtensionApiTest, AsByteArraySignedUnderflowWritesByteAndRaisesOverflowError) { PyObjectPtr num(PyLong_FromLong(-0x81)); PyLongObject* obj = num.asLongObject(); unsigned char dst[1]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, true), -1); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); EXPECT_EQ(dst[0], 0x7f); } TEST_F(LongExtensionApiTest, AsByteArraySignedPositiveWritesBytesBigEndian) { PyObjectPtr num(PyLong_FromLong(0xface)); PyLongObject* obj = num.asLongObject(); unsigned char dst[3]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, true), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0x00); EXPECT_EQ(dst[1], 0xfa); EXPECT_EQ(dst[2], 0xce); } TEST_F(LongExtensionApiTest, AsByteArraySignedPositiveWritesBytesLittleEndian) { PyObjectPtr num(PyLong_FromLong(0xface)); PyLongObject* obj = num.asLongObject(); unsigned char dst[3]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), true, true), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0xce); EXPECT_EQ(dst[1], 0xfa); EXPECT_EQ(dst[2], 0x00); } TEST_F(LongExtensionApiTest, AsByteArraySignedNegativeWritesBytesBigEndian) { PyObjectPtr num(PyLong_FromLong(-0xface)); PyLongObject* obj = num.asLongObject(); unsigned char dst[3]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, true), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0xff); EXPECT_EQ(dst[1], 0x05); EXPECT_EQ(dst[2], 0x32); } TEST_F(LongExtensionApiTest, AsByteArraySignedNegativeWritesBytesLittleEndian) { PyObjectPtr num(PyLong_FromLong(-0xface)); PyLongObject* obj = num.asLongObject(); unsigned char dst[3]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), true, true), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0x32); EXPECT_EQ(dst[1], 0x05); EXPECT_EQ(dst[2], 0xff); } TEST_F(LongExtensionApiTest, AsByteArrayWithIntSubclassWritesBytes) { PyRun_SimpleString(R"( class X(int): pass x = X(0xface) )"); PyObjectPtr x(mainModuleGet("x")); PyLongObject* obj = x.asLongObject(); unsigned char dst[3]; ASSERT_EQ(_PyLong_AsByteArray(obj, dst, sizeof(dst), false, true), 0); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(dst[0], 0x00); EXPECT_EQ(dst[1], 0xfa); EXPECT_EQ(dst[2], 0xce); } TEST_F(LongExtensionApiTest, CopyWithIntReturnsInt) { PyObjectPtr x(PyLong_FromLong(42)); PyObjectPtr result(_PyLong_Copy(x.asLongObject())); EXPECT_TRUE(PyLong_CheckExact(result)); EXPECT_TRUE(isLongEqualsLong(result, 42)); } TEST_F(LongExtensionApiTest, CopyWithIntSubclassReturnsExactInt) { PyRun_SimpleString(R"( class X(int): pass x = X(42) )"); PyObjectPtr x(mainModuleGet("x")); PyObjectPtr result(_PyLong_Copy(x.asLongObject())); EXPECT_TRUE(PyLong_CheckExact(result)); EXPECT_TRUE(isLongEqualsLong(result, 42)); } TEST_F(LongExtensionApiTest, DivmodNearWithNonIntDividendRaisesTypeError) { PyObjectPtr a(PyUnicode_FromString("not an int")); PyObjectPtr b(PyLong_FromLong(0)); ASSERT_EQ(_PyLong_DivmodNear(a, b), nullptr); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, DivmodNearWithNonIntDivisorRaisesTypeError) { PyObjectPtr a(PyLong_FromLong(0)); PyObjectPtr b(PyUnicode_FromString("not an int")); ASSERT_EQ(_PyLong_DivmodNear(a, b), nullptr); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, DivmodNearWithZeroDivisorRaisesZeroDivisionError) { PyObjectPtr a(PyLong_FromLong(0)); PyObjectPtr b(PyLong_FromLong(0)); ASSERT_EQ(_PyLong_DivmodNear(a, b), nullptr); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ZeroDivisionError)); } TEST_F(LongExtensionApiTest, DivmodNearRoundsToEven) { PyObjectPtr a(PyLong_FromLong(44)); PyObjectPtr b(PyLong_FromLong(8)); PyObjectPtr result(_PyLong_DivmodNear(a, b)); ASSERT_TRUE(PyTuple_CheckExact(result)); ASSERT_EQ(PyTuple_Size(result), 2); PyObject* quotient = PyTuple_GetItem(result, 0); ASSERT_TRUE(PyLong_CheckExact(quotient)); EXPECT_EQ(PyLong_AsLong(quotient), 6); PyObject* remainder = PyTuple_GetItem(result, 1); ASSERT_TRUE(PyLong_CheckExact(remainder)); EXPECT_EQ(PyLong_AsLong(remainder), -4); } TEST_F(LongExtensionApiTest, DivmodNearWithNegativeDividendReturnsTuple) { PyObjectPtr a(PyLong_FromLong(-43)); PyObjectPtr b(PyLong_FromLong(5)); PyObjectPtr result(_PyLong_DivmodNear(a, b)); ASSERT_TRUE(PyTuple_CheckExact(result)); ASSERT_EQ(PyTuple_Size(result), 2); PyObject* quotient = PyTuple_GetItem(result, 0); ASSERT_TRUE(PyLong_CheckExact(quotient)); EXPECT_EQ(PyLong_AsLong(quotient), -9); PyObject* remainder = PyTuple_GetItem(result, 1); ASSERT_TRUE(PyLong_CheckExact(remainder)); EXPECT_EQ(PyLong_AsLong(remainder), 2); } TEST_F(LongExtensionApiTest, DivmodNearWithNegativeDivisorReturnsTuple) { PyObjectPtr a(PyLong_FromLong(43)); PyObjectPtr b(PyLong_FromLong(-5)); PyObjectPtr result(_PyLong_DivmodNear(a, b)); ASSERT_TRUE(PyTuple_CheckExact(result)); ASSERT_EQ(PyTuple_Size(result), 2); PyObject* quotient = PyTuple_GetItem(result, 0); ASSERT_TRUE(PyLong_CheckExact(quotient)); EXPECT_EQ(PyLong_AsLong(quotient), -9); PyObject* remainder = PyTuple_GetItem(result, 1); ASSERT_TRUE(PyLong_CheckExact(remainder)); EXPECT_EQ(PyLong_AsLong(remainder), -2); } TEST_F(LongExtensionApiTest, DivmodNearWithNegativesReturnsTuple) { PyObjectPtr a(PyLong_FromLong(-43)); PyObjectPtr b(PyLong_FromLong(-5)); PyObjectPtr result(_PyLong_DivmodNear(a, b)); ASSERT_TRUE(PyTuple_CheckExact(result)); ASSERT_EQ(PyTuple_Size(result), 2); PyObject* quotient = PyTuple_GetItem(result, 0); ASSERT_TRUE(PyLong_CheckExact(quotient)); EXPECT_EQ(PyLong_AsLong(quotient), 9); PyObject* remainder = PyTuple_GetItem(result, 1); ASSERT_TRUE(PyLong_CheckExact(remainder)); EXPECT_EQ(PyLong_AsLong(remainder), 2); } TEST_F(LongExtensionApiTest, FromByteArrayWithZeroSizeReturnsZero) { PyObjectPtr num(_PyLong_FromByteArray(nullptr, 0, false, false)); ASSERT_EQ(PyErr_Occurred(), nullptr); ASSERT_TRUE(PyLong_CheckExact(num)); EXPECT_EQ(PyLong_AsLong(num), 0); } TEST_F(LongExtensionApiTest, FromByteArrayBigEndianUnsignedReturnsBytes) { const unsigned char source[] = {0x2c, 0xff, 0x00, 0x42}; PyObjectPtr num(_PyLong_FromByteArray(source, 4, false, false)); ASSERT_EQ(PyErr_Occurred(), nullptr); ASSERT_TRUE(PyLong_CheckExact(num)); EXPECT_EQ(PyLong_AsLong(num), 0x2cff0042); } TEST_F(LongExtensionApiTest, FromByteArrayLittleEndianUnsignedReturnsBytes) { const unsigned char source[] = {0x2c, 0xff, 0x00, 0x42}; PyObjectPtr num(_PyLong_FromByteArray(source, 4, true, false)); ASSERT_EQ(PyErr_Occurred(), nullptr); ASSERT_TRUE(PyLong_CheckExact(num)); EXPECT_EQ(PyLong_AsLong(num), 0x4200ff2c); } TEST_F(LongExtensionApiTest, FromByteArrayBigEndianSignedPositiveReturnsBytes) { const unsigned char source[] = {0x2c, 0xff, 0x00, 0x42}; PyObjectPtr num(_PyLong_FromByteArray(source, 4, false, true)); ASSERT_EQ(PyErr_Occurred(), nullptr); ASSERT_TRUE(PyLong_CheckExact(num)); EXPECT_EQ(PyLong_AsLong(num), 0x2cff0042); } TEST_F(LongExtensionApiTest, FromByteArrayBigEndianSignedNegativeReturnsBytes) { const unsigned char source[] = {0xff, 0x2c, 0x00, 0x42}; PyObjectPtr num(_PyLong_FromByteArray(source, 4, false, true)); ASSERT_EQ(PyErr_Occurred(), nullptr); ASSERT_TRUE(PyLong_CheckExact(num)); EXPECT_EQ(PyLong_AsLong(num), -0x00d3ffbe); } TEST_F(LongExtensionApiTest, FromByteArrayReturnsBytesWithSize) { const unsigned char source[] = {0x01, 0x02, 0x03}; PyObjectPtr num(_PyLong_FromByteArray(source, 2, true, true)); ASSERT_EQ(PyErr_Occurred(), nullptr); ASSERT_TRUE(PyLong_CheckExact(num)); EXPECT_EQ(PyLong_AsLong(num), 0x0201); } TEST_F(LongExtensionApiTest, SignZeroReturnsZero) { PyObjectPtr zero(PyLong_FromLong(0)); ASSERT_EQ(_PyLong_Sign(zero), 0); } TEST_F(LongExtensionApiTest, SignPositiveLongReturnsOne) { PyObjectPtr positive1(PyLong_FromLong(1)); ASSERT_EQ(_PyLong_Sign(positive1), 1); PyObjectPtr positive1234(PyLong_FromLong(1234)); ASSERT_EQ(_PyLong_Sign(positive1234), 1); } TEST_F(LongExtensionApiTest, SignNegativeReturnsNegativeOne) { PyObjectPtr negative1(PyLong_FromLong(-1)); ASSERT_EQ(_PyLong_Sign(negative1), -1); PyObjectPtr negative5678(PyLong_FromLong(-5678)); ASSERT_EQ(_PyLong_Sign(negative5678), -1); } TEST_F(LongExtensionApiTest, SignWithIntSubclassReturnsSign) { PyRun_SimpleString(R"( class X(int): pass a = X(-42) b = X(0) c = X(42) )"); PyObjectPtr a(mainModuleGet("a")); PyObjectPtr b(mainModuleGet("b")); PyObjectPtr c(mainModuleGet("c")); EXPECT_EQ(_PyLong_Sign(a), -1); EXPECT_EQ(_PyLong_Sign(b), 0); EXPECT_EQ(_PyLong_Sign(c), 1); } TEST_F(LongExtensionApiTest, FromVoidPtrReturnsLong) { unsigned long long max_as_int = std::numeric_limits<unsigned long long>::max(); void* max_as_ptr = reinterpret_cast<void*>(max_as_int); PyObjectPtr pylong(PyLong_FromVoidPtr(max_as_ptr)); EXPECT_EQ(PyLong_AsVoidPtr(pylong), max_as_ptr); EXPECT_EQ(PyLong_AsUnsignedLongLong(pylong), max_as_int); unsigned long long zero_as_int = 0ULL; void* zero_as_ptr = reinterpret_cast<void*>(zero_as_int); pylong = PyLong_FromVoidPtr(zero_as_ptr); EXPECT_EQ(PyLong_AsVoidPtr(pylong), zero_as_ptr); EXPECT_EQ(PyLong_AsUnsignedLongLong(pylong), zero_as_int); unsigned long long num_as_int = 1234ULL; void* num_as_ptr = reinterpret_cast<void*>(num_as_int); pylong = PyLong_FromVoidPtr(num_as_ptr); EXPECT_EQ(PyLong_AsVoidPtr(pylong), num_as_ptr); EXPECT_EQ(PyLong_AsUnsignedLongLong(pylong), num_as_int); } TEST_F(LongExtensionApiTest, FromDoubleReturnsLong) { PyObjectPtr pylong(PyLong_FromDouble(12.34)); ASSERT_EQ(PyErr_Occurred(), nullptr); ASSERT_EQ(PyLong_Check(pylong), 1); EXPECT_EQ(PyLong_AsLong(pylong), 12); } TEST_F(LongExtensionApiTest, FromDoubleRaisesAndReturnsNull) { PyObjectPtr pylong( PyLong_FromDouble(std::numeric_limits<double>::infinity())); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_EQ(pylong, nullptr); } TEST_F(LongExtensionApiTest, LshiftWithZeroReturnsZero) { PyObjectPtr result(_PyLong_Lshift(_PyLong_Zero, 10)); EXPECT_TRUE(isLongEqualsLong(result, 0)); } TEST_F(LongExtensionApiTest, LshiftWithNonzeroShiftsBits) { PyObjectPtr pos_result(_PyLong_Lshift(_PyLong_One, 10)); EXPECT_TRUE(isLongEqualsLong(pos_result, 1024)); PyObjectPtr neg(PyLong_FromLong(-5)); PyObjectPtr neg_result(_PyLong_Lshift(neg, 4)); EXPECT_TRUE(isLongEqualsLong(neg_result, -80)); } TEST_F(LongExtensionApiTest, OneIsOne) { EXPECT_TRUE(isLongEqualsLong(_PyLong_One, 1)); } TEST_F(LongExtensionApiTest, RshiftWithZeroReturnsZero) { PyObjectPtr result(_PyLong_Rshift(_PyLong_Zero, 10)); EXPECT_TRUE(isLongEqualsLong(result, 0)); } TEST_F(LongExtensionApiTest, RshiftWithNonzeroShiftsBits) { PyObjectPtr pos(PyLong_FromLong(257)); PyObjectPtr pos_result(_PyLong_Rshift(pos, 3)); EXPECT_TRUE(isLongEqualsLong(pos_result, 32)); PyObjectPtr neg(PyLong_FromLong(-17)); PyObjectPtr neg_result(_PyLong_Rshift(neg, 2)); EXPECT_TRUE(isLongEqualsLong(neg_result, -5)); } TEST_F(LongExtensionApiTest, SizeTConverterWithNonIntRaisesTypeError) { size_t ignored; PyObjectPtr tuple(PyTuple_New(0)); EXPECT_EQ(_PyLong_Size_t_Converter(tuple, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, SizeTConverterWithNegativeRaisesValueError) { size_t ignored; PyObjectPtr negative(PyLong_FromLong(-10)); EXPECT_EQ(_PyLong_Size_t_Converter(negative, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); } TEST_F(LongExtensionApiTest, SizeTConverterWithLargeIntRaisesOverflowError) { size_t ignored; PyObjectPtr large(PyLong_FromString("10000000000000002", nullptr, 16)); EXPECT_EQ(_PyLong_Size_t_Converter(large, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); } TEST_F(LongExtensionApiTest, SizeTConverterSetsSizeT) { size_t result; PyObjectPtr num(PyLong_FromLong(42)); EXPECT_EQ(_PyLong_Size_t_Converter(num, &result), 1); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(result, static_cast<unsigned>(42)); } TEST_F(LongExtensionApiTest, UnsignedIntConverterWithNonIntRaisesTypeError) { unsigned int ignored; PyObjectPtr tuple(PyTuple_New(0)); EXPECT_EQ(_PyLong_UnsignedInt_Converter(tuple, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, UnsignedIntConverterWithNegativeRaisesValueError) { unsigned int ignored; PyObjectPtr negative(PyLong_FromLong(-10)); EXPECT_EQ(_PyLong_UnsignedInt_Converter(negative, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); } TEST_F(LongExtensionApiTest, UnsignedIntConverterWithLargeIntRaisesOverflowError) { unsigned int ignored; PyObjectPtr large(PyLong_FromString("10000000000000002", nullptr, 16)); EXPECT_EQ(_PyLong_UnsignedInt_Converter(large, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); } TEST_F(LongExtensionApiTest, UnsignedIntConverterSetsUnsignedInt) { unsigned int result; PyObjectPtr num(PyLong_FromLong(42)); EXPECT_EQ(_PyLong_UnsignedInt_Converter(num, &result), 1); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(result, static_cast<unsigned>(42)); } TEST_F(LongExtensionApiTest, UnsignedLongConverterWithNonIntRaisesTypeError) { unsigned long ignored; PyObjectPtr tuple(PyTuple_New(0)); EXPECT_EQ(_PyLong_UnsignedLong_Converter(tuple, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, UnsignedLongConverterWithNegativeRaisesValueError) { unsigned long ignored; PyObjectPtr negative(PyLong_FromLong(-10)); EXPECT_EQ(_PyLong_UnsignedLong_Converter(negative, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); } TEST_F(LongExtensionApiTest, UnsignedLongConverterWithLargeIntRaisesOverflowError) { unsigned long ignored; PyObjectPtr large(PyLong_FromString("10000000000000002", nullptr, 16)); EXPECT_EQ(_PyLong_UnsignedLong_Converter(large, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); } TEST_F(LongExtensionApiTest, UnsignedLongConverterSetsUnsignedLong) { unsigned long result; PyObjectPtr num(PyLong_FromLong(42)); EXPECT_EQ(_PyLong_UnsignedLong_Converter(num, &result), 1); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(result, static_cast<unsigned>(42)); } TEST_F(LongExtensionApiTest, UnsignedLongLongConverterWithNonIntRaisesTypeError) { unsigned long long ignored; PyObjectPtr tuple(PyTuple_New(0)); EXPECT_EQ(_PyLong_UnsignedLongLong_Converter(tuple, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, UnsignedLongLongConverterWithNegativeRaisesValueError) { unsigned long long ignored; PyObjectPtr negative(PyLong_FromLong(-10)); EXPECT_EQ(_PyLong_UnsignedLongLong_Converter(negative, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); } TEST_F(LongExtensionApiTest, UnsignedLongLongConverterWithLargeIntRaisesOverflowError) { unsigned long long ignored; PyObjectPtr large(PyLong_FromString("10000000000000002", nullptr, 16)); EXPECT_EQ(_PyLong_UnsignedLongLong_Converter(large, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); } TEST_F(LongExtensionApiTest, UnsignedLongLongConverterSetsUnsignedLongLong) { unsigned long long result; PyObjectPtr num(PyLong_FromLong(42)); EXPECT_EQ(_PyLong_UnsignedLongLong_Converter(num, &result), 1); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(result, static_cast<unsigned>(42)); } TEST_F(LongExtensionApiTest, UnsignedShortConverterWithNonIntRaisesTypeError) { unsigned short ignored; PyObjectPtr tuple(PyTuple_New(0)); EXPECT_EQ(_PyLong_UnsignedShort_Converter(tuple, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); } TEST_F(LongExtensionApiTest, UnsignedShortConverterWithNegativeRaisesValueError) { unsigned short ignored; PyObjectPtr negative(PyLong_FromLong(-10)); EXPECT_EQ(_PyLong_UnsignedShort_Converter(negative, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); } TEST_F(LongExtensionApiTest, UnsignedShortConverterWithLargeIntRaisesOverflowError) { unsigned short ignored; PyObjectPtr large(PyLong_FromString("10000000000000002", nullptr, 16)); EXPECT_EQ(_PyLong_UnsignedShort_Converter(large, &ignored), 0); ASSERT_NE(PyErr_Occurred(), nullptr); EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_OverflowError)); } TEST_F(LongExtensionApiTest, UnsignedShortConverterSetsUnsignedShort) { unsigned short result; PyObjectPtr num(PyLong_FromLong(42)); EXPECT_EQ(_PyLong_UnsignedShort_Converter(num, &result), 1); ASSERT_EQ(PyErr_Occurred(), nullptr); EXPECT_EQ(result, static_cast<unsigned>(42)); } TEST_F(LongExtensionApiTest, ZeroIsZero) { EXPECT_TRUE(isLongEqualsLong(_PyLong_Zero, 0)); } } // namespace testing } // namespace py