(root)/
Python-3.12.0/
Modules/
_testcapi/
long.c
       1  #include "parts.h"
       2  
       3  
       4  static PyObject *
       5  raiseTestError(const char* test_name, const char* msg)
       6  {
       7      PyErr_Format(PyExc_AssertionError, "%s: %s", test_name, msg);
       8      return NULL;
       9  }
      10  
      11  /* Tests of PyLong_{As, From}{Unsigned,}Long(), and
      12     PyLong_{As, From}{Unsigned,}LongLong().
      13  
      14     Note that the meat of the test is contained in testcapi_long.h.
      15     This is revolting, but delicate code duplication is worse:  "almost
      16     exactly the same" code is needed to test long long, but the ubiquitous
      17     dependence on type names makes it impossible to use a parameterized
      18     function.  A giant macro would be even worse than this.  A C++ template
      19     would be perfect.
      20  
      21     The "report an error" functions are deliberately not part of the #include
      22     file:  if the test fails, you can set a breakpoint in the appropriate
      23     error function directly, and crawl back from there in the debugger.
      24  */
      25  
      26  #define UNBIND(X)  Py_DECREF(X); (X) = NULL
      27  
      28  static PyObject *
      29  raise_test_long_error(const char* msg)
      30  {
      31      return raiseTestError("test_long_api", msg);
      32  }
      33  
      34  #define TESTNAME        test_long_api_inner
      35  #define TYPENAME        long
      36  #define F_S_TO_PY       PyLong_FromLong
      37  #define F_PY_TO_S       PyLong_AsLong
      38  #define F_U_TO_PY       PyLong_FromUnsignedLong
      39  #define F_PY_TO_U       PyLong_AsUnsignedLong
      40  
      41  #include "testcapi_long.h"
      42  
      43  static PyObject *
      44  test_long_api(PyObject* self, PyObject *Py_UNUSED(ignored))
      45  {
      46      return TESTNAME(raise_test_long_error);
      47  }
      48  
      49  #undef TESTNAME
      50  #undef TYPENAME
      51  #undef F_S_TO_PY
      52  #undef F_PY_TO_S
      53  #undef F_U_TO_PY
      54  #undef F_PY_TO_U
      55  
      56  static PyObject *
      57  raise_test_longlong_error(const char* msg)
      58  {
      59      return raiseTestError("test_longlong_api", msg);
      60  }
      61  
      62  #define TESTNAME        test_longlong_api_inner
      63  #define TYPENAME        long long
      64  #define F_S_TO_PY       PyLong_FromLongLong
      65  #define F_PY_TO_S       PyLong_AsLongLong
      66  #define F_U_TO_PY       PyLong_FromUnsignedLongLong
      67  #define F_PY_TO_U       PyLong_AsUnsignedLongLong
      68  
      69  #include "testcapi_long.h"
      70  
      71  static PyObject *
      72  test_longlong_api(PyObject* self, PyObject *args)
      73  {
      74      return TESTNAME(raise_test_longlong_error);
      75  }
      76  
      77  #undef TESTNAME
      78  #undef TYPENAME
      79  #undef F_S_TO_PY
      80  #undef F_PY_TO_S
      81  #undef F_U_TO_PY
      82  #undef F_PY_TO_U
      83  
      84  /* Test the PyLong_AsLongAndOverflow API. General conversion to PY_LONG
      85     is tested by test_long_api_inner. This test will concentrate on proper
      86     handling of overflow.
      87  */
      88  
      89  static PyObject *
      90  test_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
      91  {
      92      PyObject *num, *one, *temp;
      93      long value;
      94      int overflow;
      95  
      96      /* Test that overflow is set properly for a large value. */
      97      /* num is a number larger than LONG_MAX even on 64-bit platforms */
      98      num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
      99      if (num == NULL)
     100          return NULL;
     101      overflow = 1234;
     102      value = PyLong_AsLongAndOverflow(num, &overflow);
     103      Py_DECREF(num);
     104      if (value == -1 && PyErr_Occurred())
     105          return NULL;
     106      if (value != -1)
     107          return raiseTestError("test_long_and_overflow",
     108              "return value was not set to -1");
     109      if (overflow != 1)
     110          return raiseTestError("test_long_and_overflow",
     111              "overflow was not set to 1");
     112  
     113      /* Same again, with num = LONG_MAX + 1 */
     114      num = PyLong_FromLong(LONG_MAX);
     115      if (num == NULL)
     116          return NULL;
     117      one = PyLong_FromLong(1L);
     118      if (one == NULL) {
     119          Py_DECREF(num);
     120          return NULL;
     121      }
     122      temp = PyNumber_Add(num, one);
     123      Py_DECREF(one);
     124      Py_SETREF(num, temp);
     125      if (num == NULL)
     126          return NULL;
     127      overflow = 0;
     128      value = PyLong_AsLongAndOverflow(num, &overflow);
     129      Py_DECREF(num);
     130      if (value == -1 && PyErr_Occurred())
     131          return NULL;
     132      if (value != -1)
     133          return raiseTestError("test_long_and_overflow",
     134              "return value was not set to -1");
     135      if (overflow != 1)
     136          return raiseTestError("test_long_and_overflow",
     137              "overflow was not set to 1");
     138  
     139      /* Test that overflow is set properly for a large negative value. */
     140      /* num is a number smaller than LONG_MIN even on 64-bit platforms */
     141      num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
     142      if (num == NULL)
     143          return NULL;
     144      overflow = 1234;
     145      value = PyLong_AsLongAndOverflow(num, &overflow);
     146      Py_DECREF(num);
     147      if (value == -1 && PyErr_Occurred())
     148          return NULL;
     149      if (value != -1)
     150          return raiseTestError("test_long_and_overflow",
     151              "return value was not set to -1");
     152      if (overflow != -1)
     153          return raiseTestError("test_long_and_overflow",
     154              "overflow was not set to -1");
     155  
     156      /* Same again, with num = LONG_MIN - 1 */
     157      num = PyLong_FromLong(LONG_MIN);
     158      if (num == NULL)
     159          return NULL;
     160      one = PyLong_FromLong(1L);
     161      if (one == NULL) {
     162          Py_DECREF(num);
     163          return NULL;
     164      }
     165      temp = PyNumber_Subtract(num, one);
     166      Py_DECREF(one);
     167      Py_SETREF(num, temp);
     168      if (num == NULL)
     169          return NULL;
     170      overflow = 0;
     171      value = PyLong_AsLongAndOverflow(num, &overflow);
     172      Py_DECREF(num);
     173      if (value == -1 && PyErr_Occurred())
     174          return NULL;
     175      if (value != -1)
     176          return raiseTestError("test_long_and_overflow",
     177              "return value was not set to -1");
     178      if (overflow != -1)
     179          return raiseTestError("test_long_and_overflow",
     180              "overflow was not set to -1");
     181  
     182      /* Test that overflow is cleared properly for small values. */
     183      num = PyLong_FromString("FF", NULL, 16);
     184      if (num == NULL)
     185          return NULL;
     186      overflow = 1234;
     187      value = PyLong_AsLongAndOverflow(num, &overflow);
     188      Py_DECREF(num);
     189      if (value == -1 && PyErr_Occurred())
     190          return NULL;
     191      if (value != 0xFF)
     192          return raiseTestError("test_long_and_overflow",
     193              "expected return value 0xFF");
     194      if (overflow != 0)
     195          return raiseTestError("test_long_and_overflow",
     196              "overflow was not cleared");
     197  
     198      num = PyLong_FromString("-FF", NULL, 16);
     199      if (num == NULL)
     200          return NULL;
     201      overflow = 0;
     202      value = PyLong_AsLongAndOverflow(num, &overflow);
     203      Py_DECREF(num);
     204      if (value == -1 && PyErr_Occurred())
     205          return NULL;
     206      if (value != -0xFF)
     207          return raiseTestError("test_long_and_overflow",
     208              "expected return value 0xFF");
     209      if (overflow != 0)
     210          return raiseTestError("test_long_and_overflow",
     211              "overflow was set incorrectly");
     212  
     213      num = PyLong_FromLong(LONG_MAX);
     214      if (num == NULL)
     215          return NULL;
     216      overflow = 1234;
     217      value = PyLong_AsLongAndOverflow(num, &overflow);
     218      Py_DECREF(num);
     219      if (value == -1 && PyErr_Occurred())
     220          return NULL;
     221      if (value != LONG_MAX)
     222          return raiseTestError("test_long_and_overflow",
     223              "expected return value LONG_MAX");
     224      if (overflow != 0)
     225          return raiseTestError("test_long_and_overflow",
     226              "overflow was not cleared");
     227  
     228      num = PyLong_FromLong(LONG_MIN);
     229      if (num == NULL)
     230          return NULL;
     231      overflow = 0;
     232      value = PyLong_AsLongAndOverflow(num, &overflow);
     233      Py_DECREF(num);
     234      if (value == -1 && PyErr_Occurred())
     235          return NULL;
     236      if (value != LONG_MIN)
     237          return raiseTestError("test_long_and_overflow",
     238              "expected return value LONG_MIN");
     239      if (overflow != 0)
     240          return raiseTestError("test_long_and_overflow",
     241              "overflow was not cleared");
     242  
     243      Py_RETURN_NONE;
     244  }
     245  
     246  /* Test the PyLong_AsLongLongAndOverflow API. General conversion to
     247     long long is tested by test_long_api_inner. This test will
     248     concentrate on proper handling of overflow.
     249  */
     250  
     251  static PyObject *
     252  test_long_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored))
     253  {
     254      PyObject *num, *one, *temp;
     255      long long value;
     256      int overflow;
     257  
     258      /* Test that overflow is set properly for a large value. */
     259      /* num is a number larger than LLONG_MAX on a typical machine. */
     260      num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
     261      if (num == NULL)
     262          return NULL;
     263      overflow = 1234;
     264      value = PyLong_AsLongLongAndOverflow(num, &overflow);
     265      Py_DECREF(num);
     266      if (value == -1 && PyErr_Occurred())
     267          return NULL;
     268      if (value != -1)
     269          return raiseTestError("test_long_long_and_overflow",
     270              "return value was not set to -1");
     271      if (overflow != 1)
     272          return raiseTestError("test_long_long_and_overflow",
     273              "overflow was not set to 1");
     274  
     275      /* Same again, with num = LLONG_MAX + 1 */
     276      num = PyLong_FromLongLong(LLONG_MAX);
     277      if (num == NULL)
     278          return NULL;
     279      one = PyLong_FromLong(1L);
     280      if (one == NULL) {
     281          Py_DECREF(num);
     282          return NULL;
     283      }
     284      temp = PyNumber_Add(num, one);
     285      Py_DECREF(one);
     286      Py_SETREF(num, temp);
     287      if (num == NULL)
     288          return NULL;
     289      overflow = 0;
     290      value = PyLong_AsLongLongAndOverflow(num, &overflow);
     291      Py_DECREF(num);
     292      if (value == -1 && PyErr_Occurred())
     293          return NULL;
     294      if (value != -1)
     295          return raiseTestError("test_long_long_and_overflow",
     296              "return value was not set to -1");
     297      if (overflow != 1)
     298          return raiseTestError("test_long_long_and_overflow",
     299              "overflow was not set to 1");
     300  
     301      /* Test that overflow is set properly for a large negative value. */
     302      /* num is a number smaller than LLONG_MIN on a typical platform */
     303      num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
     304      if (num == NULL)
     305          return NULL;
     306      overflow = 1234;
     307      value = PyLong_AsLongLongAndOverflow(num, &overflow);
     308      Py_DECREF(num);
     309      if (value == -1 && PyErr_Occurred())
     310          return NULL;
     311      if (value != -1)
     312          return raiseTestError("test_long_long_and_overflow",
     313              "return value was not set to -1");
     314      if (overflow != -1)
     315          return raiseTestError("test_long_long_and_overflow",
     316              "overflow was not set to -1");
     317  
     318      /* Same again, with num = LLONG_MIN - 1 */
     319      num = PyLong_FromLongLong(LLONG_MIN);
     320      if (num == NULL)
     321          return NULL;
     322      one = PyLong_FromLong(1L);
     323      if (one == NULL) {
     324          Py_DECREF(num);
     325          return NULL;
     326      }
     327      temp = PyNumber_Subtract(num, one);
     328      Py_DECREF(one);
     329      Py_SETREF(num, temp);
     330      if (num == NULL)
     331          return NULL;
     332      overflow = 0;
     333      value = PyLong_AsLongLongAndOverflow(num, &overflow);
     334      Py_DECREF(num);
     335      if (value == -1 && PyErr_Occurred())
     336          return NULL;
     337      if (value != -1)
     338          return raiseTestError("test_long_long_and_overflow",
     339              "return value was not set to -1");
     340      if (overflow != -1)
     341          return raiseTestError("test_long_long_and_overflow",
     342              "overflow was not set to -1");
     343  
     344      /* Test that overflow is cleared properly for small values. */
     345      num = PyLong_FromString("FF", NULL, 16);
     346      if (num == NULL)
     347          return NULL;
     348      overflow = 1234;
     349      value = PyLong_AsLongLongAndOverflow(num, &overflow);
     350      Py_DECREF(num);
     351      if (value == -1 && PyErr_Occurred())
     352          return NULL;
     353      if (value != 0xFF)
     354          return raiseTestError("test_long_long_and_overflow",
     355              "expected return value 0xFF");
     356      if (overflow != 0)
     357          return raiseTestError("test_long_long_and_overflow",
     358              "overflow was not cleared");
     359  
     360      num = PyLong_FromString("-FF", NULL, 16);
     361      if (num == NULL)
     362          return NULL;
     363      overflow = 0;
     364      value = PyLong_AsLongLongAndOverflow(num, &overflow);
     365      Py_DECREF(num);
     366      if (value == -1 && PyErr_Occurred())
     367          return NULL;
     368      if (value != -0xFF)
     369          return raiseTestError("test_long_long_and_overflow",
     370              "expected return value 0xFF");
     371      if (overflow != 0)
     372          return raiseTestError("test_long_long_and_overflow",
     373              "overflow was set incorrectly");
     374  
     375      num = PyLong_FromLongLong(LLONG_MAX);
     376      if (num == NULL)
     377          return NULL;
     378      overflow = 1234;
     379      value = PyLong_AsLongLongAndOverflow(num, &overflow);
     380      Py_DECREF(num);
     381      if (value == -1 && PyErr_Occurred())
     382          return NULL;
     383      if (value != LLONG_MAX)
     384          return raiseTestError("test_long_long_and_overflow",
     385              "expected return value LLONG_MAX");
     386      if (overflow != 0)
     387          return raiseTestError("test_long_long_and_overflow",
     388              "overflow was not cleared");
     389  
     390      num = PyLong_FromLongLong(LLONG_MIN);
     391      if (num == NULL)
     392          return NULL;
     393      overflow = 0;
     394      value = PyLong_AsLongLongAndOverflow(num, &overflow);
     395      Py_DECREF(num);
     396      if (value == -1 && PyErr_Occurred())
     397          return NULL;
     398      if (value != LLONG_MIN)
     399          return raiseTestError("test_long_long_and_overflow",
     400              "expected return value LLONG_MIN");
     401      if (overflow != 0)
     402          return raiseTestError("test_long_long_and_overflow",
     403              "overflow was not cleared");
     404  
     405      Py_RETURN_NONE;
     406  }
     407  
     408  /* Test the PyLong_As{Size,Ssize}_t API. At present this just tests that
     409     non-integer arguments are handled correctly. It should be extended to
     410     test overflow handling.
     411   */
     412  
     413  static PyObject *
     414  test_long_as_size_t(PyObject *self, PyObject *Py_UNUSED(ignored))
     415  {
     416      size_t out_u;
     417      Py_ssize_t out_s;
     418  
     419      Py_INCREF(Py_None);
     420  
     421      out_u = PyLong_AsSize_t(Py_None);
     422      if (out_u != (size_t)-1 || !PyErr_Occurred())
     423          return raiseTestError("test_long_as_size_t",
     424                                "PyLong_AsSize_t(None) didn't complain");
     425      if (!PyErr_ExceptionMatches(PyExc_TypeError))
     426          return raiseTestError("test_long_as_size_t",
     427                                "PyLong_AsSize_t(None) raised "
     428                                "something other than TypeError");
     429      PyErr_Clear();
     430  
     431      out_s = PyLong_AsSsize_t(Py_None);
     432      if (out_s != (Py_ssize_t)-1 || !PyErr_Occurred())
     433          return raiseTestError("test_long_as_size_t",
     434                                "PyLong_AsSsize_t(None) didn't complain");
     435      if (!PyErr_ExceptionMatches(PyExc_TypeError))
     436          return raiseTestError("test_long_as_size_t",
     437                                "PyLong_AsSsize_t(None) raised "
     438                                "something other than TypeError");
     439      PyErr_Clear();
     440  
     441      /* Py_INCREF(Py_None) omitted - we already have a reference to it. */
     442      return Py_None;
     443  }
     444  
     445  static PyObject *
     446  test_long_as_unsigned_long_long_mask(PyObject *self,
     447                                       PyObject *Py_UNUSED(ignored))
     448  {
     449      unsigned long long res = PyLong_AsUnsignedLongLongMask(NULL);
     450  
     451      if (res != (unsigned long long)-1 || !PyErr_Occurred()) {
     452          return raiseTestError("test_long_as_unsigned_long_long_mask",
     453                                "PyLong_AsUnsignedLongLongMask(NULL) didn't "
     454                                "complain");
     455      }
     456      if (!PyErr_ExceptionMatches(PyExc_SystemError)) {
     457          return raiseTestError("test_long_as_unsigned_long_long_mask",
     458                                "PyLong_AsUnsignedLongLongMask(NULL) raised "
     459                                "something other than SystemError");
     460      }
     461      PyErr_Clear();
     462      Py_RETURN_NONE;
     463  }
     464  
     465  /* Test the PyLong_AsDouble API. At present this just tests that
     466     non-integer arguments are handled correctly.
     467   */
     468  
     469  static PyObject *
     470  test_long_as_double(PyObject *self, PyObject *Py_UNUSED(ignored))
     471  {
     472      double out;
     473  
     474      Py_INCREF(Py_None);
     475  
     476      out = PyLong_AsDouble(Py_None);
     477      if (out != -1.0 || !PyErr_Occurred())
     478          return raiseTestError("test_long_as_double",
     479                                "PyLong_AsDouble(None) didn't complain");
     480      if (!PyErr_ExceptionMatches(PyExc_TypeError))
     481          return raiseTestError("test_long_as_double",
     482                                "PyLong_AsDouble(None) raised "
     483                                "something other than TypeError");
     484      PyErr_Clear();
     485  
     486      /* Py_INCREF(Py_None) omitted - we already have a reference to it. */
     487      return Py_None;
     488  }
     489  
     490  /* Simple test of _PyLong_NumBits and _PyLong_Sign. */
     491  static PyObject *
     492  test_long_numbits(PyObject *self, PyObject *Py_UNUSED(ignored))
     493  {
     494      struct triple {
     495          long input;
     496          size_t nbits;
     497          int sign;
     498      } testcases[] = {{0, 0, 0},
     499                       {1L, 1, 1},
     500                       {-1L, 1, -1},
     501                       {2L, 2, 1},
     502                       {-2L, 2, -1},
     503                       {3L, 2, 1},
     504                       {-3L, 2, -1},
     505                       {4L, 3, 1},
     506                       {-4L, 3, -1},
     507                       {0x7fffL, 15, 1},          /* one Python int digit */
     508               {-0x7fffL, 15, -1},
     509               {0xffffL, 16, 1},
     510               {-0xffffL, 16, -1},
     511               {0xfffffffL, 28, 1},
     512               {-0xfffffffL, 28, -1}};
     513      size_t i;
     514  
     515      for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) {
     516          size_t nbits;
     517          int sign;
     518          PyObject *plong;
     519  
     520          plong = PyLong_FromLong(testcases[i].input);
     521          if (plong == NULL)
     522              return NULL;
     523          nbits = _PyLong_NumBits(plong);
     524          sign = _PyLong_Sign(plong);
     525  
     526          Py_DECREF(plong);
     527          if (nbits != testcases[i].nbits)
     528              return raiseTestError("test_long_numbits",
     529                              "wrong result for _PyLong_NumBits");
     530          if (sign != testcases[i].sign)
     531              return raiseTestError("test_long_numbits",
     532                              "wrong result for _PyLong_Sign");
     533      }
     534      Py_RETURN_NONE;
     535  }
     536  
     537  static PyObject *
     538  check_long_compact_api(PyObject *self, PyObject *arg)
     539  {
     540      assert(PyLong_Check(arg));
     541      int is_compact = PyUnstable_Long_IsCompact((PyLongObject*)arg);
     542      Py_ssize_t value = -1;
     543      if (is_compact) {
     544          value = PyUnstable_Long_CompactValue((PyLongObject*)arg);
     545      }
     546      return Py_BuildValue("in", is_compact, value);
     547  }
     548  
     549  static PyMethodDef test_methods[] = {
     550      {"test_long_and_overflow",  test_long_and_overflow,          METH_NOARGS},
     551      {"test_long_api",           test_long_api,                   METH_NOARGS},
     552      {"test_long_as_double",     test_long_as_double,             METH_NOARGS},
     553      {"test_long_as_size_t",     test_long_as_size_t,             METH_NOARGS},
     554      {"test_long_as_unsigned_long_long_mask", test_long_as_unsigned_long_long_mask, METH_NOARGS},
     555      {"test_long_long_and_overflow",test_long_long_and_overflow,  METH_NOARGS},
     556      {"test_long_numbits",       test_long_numbits,               METH_NOARGS},
     557      {"test_longlong_api",       test_longlong_api,               METH_NOARGS},
     558      {"call_long_compact_api",   check_long_compact_api,          METH_O},
     559      {NULL},
     560  };
     561  
     562  int
     563  _PyTestCapi_Init_Long(PyObject *mod)
     564  {
     565      if (PyModule_AddFunctions(mod, test_methods) < 0) {
     566          return -1;
     567      }
     568  
     569      return 0;
     570  }