LCOV - code coverage report
Current view: | top level - Modules/_testcapi - testcapi_long.h (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 0 | 97 | 0.0 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 0 | 2 | 0.0 %
|  |  | Branches: | 0 | 72 | 0.0 %

               Branch data     Line data    Source code
           1                 :            : /* Poor-man's template.  Macros used:
           2                 :            :    TESTNAME     name of the test (like test_long_api_inner)
           3                 :            :    TYPENAME     the signed type (like long)
           4                 :            :    F_S_TO_PY    convert signed to pylong; TYPENAME -> PyObject*
           5                 :            :    F_PY_TO_S    convert pylong to signed; PyObject* -> TYPENAME
           6                 :            :    F_U_TO_PY    convert unsigned to pylong; unsigned TYPENAME -> PyObject*
           7                 :            :    F_PY_TO_U    convert pylong to unsigned; PyObject* -> unsigned TYPENAME
           8                 :            : */
           9                 :            :
          10                 :            : static PyObject *
          11                 :          0 : TESTNAME(PyObject *error(const char*))
          12                 :            : {
          13                 :          0 :     const int NBITS = sizeof(TYPENAME) * 8;
          14                 :            :     unsigned TYPENAME base;
          15                 :            :     PyObject *pyresult;
          16                 :            :     int i;
          17                 :            :
          18                 :            :     /* Note:  This test lets PyObjects leak if an error is raised.  Since
          19                 :            :        an error should never be raised, leaks are impossible <wink>. */
          20                 :            :
          21                 :            :     /* Test native -> PyLong -> native roundtrip identity.
          22                 :            :      * Generate all powers of 2, and test them and their negations,
          23                 :            :      * plus the numbers +-1 off from them.
          24                 :            :      */
          25                 :          0 :     base = 1;
          26                 :          0 :     for (i = 0;
          27         [ #  # ]:          0 :          i < NBITS + 1;  /* on last, base overflows to 0 */
          28                 :          0 :          ++i, base <<= 1)
          29                 :            :     {
          30                 :            :         int j;
          31         [ #  # ]:          0 :         for (j = 0; j < 6; ++j) {
          32                 :            :             TYPENAME in, out;
          33                 :            :             unsigned TYPENAME uin, uout;
          34                 :            :
          35                 :            :             /* For 0, 1, 2 use base; for 3, 4, 5 use -base */
          36         [ #  # ]:          0 :             uin = j < 3 ? base : 0U - base;
          37                 :            :
          38                 :            :             /* For 0 & 3, subtract 1.
          39                 :            :              * For 1 & 4, leave alone.
          40                 :            :              * For 2 & 5, add 1.
          41                 :            :              */
          42                 :          0 :             uin += (unsigned TYPENAME)(TYPENAME)(j % 3 - 1);
          43                 :            :
          44                 :          0 :             pyresult = F_U_TO_PY(uin);
          45         [ #  # ]:          0 :             if (pyresult == NULL)
          46                 :          0 :                 return error(
          47                 :            :                  "unsigned unexpected null result");
          48                 :            :
          49                 :          0 :             uout = F_PY_TO_U(pyresult);
          50   [ #  #  #  # ]:          0 :             if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred())
          51                 :          0 :                 return error(
          52                 :            :                     "unsigned unexpected -1 result");
          53         [ #  # ]:          0 :             if (uout != uin)
          54                 :          0 :                 return error(
          55                 :            :                     "unsigned output != input");
          56                 :          0 :             UNBIND(pyresult);
          57                 :            :
          58                 :          0 :             in = (TYPENAME)uin;
          59                 :          0 :             pyresult = F_S_TO_PY(in);
          60         [ #  # ]:          0 :             if (pyresult == NULL)
          61                 :          0 :                 return error(
          62                 :            :                     "signed unexpected null result");
          63                 :            :
          64                 :          0 :             out = F_PY_TO_S(pyresult);
          65   [ #  #  #  # ]:          0 :             if (out == (TYPENAME)-1 && PyErr_Occurred())
          66                 :          0 :                 return error(
          67                 :            :                     "signed unexpected -1 result");
          68         [ #  # ]:          0 :             if (out != in)
          69                 :          0 :                 return error(
          70                 :            :                     "signed output != input");
          71                 :          0 :             UNBIND(pyresult);
          72                 :            :         }
          73                 :            :     }
          74                 :            :
          75                 :            :     /* Overflow tests.  The loop above ensured that all limit cases that
          76                 :            :      * should not overflow don't overflow, so all we need to do here is
          77                 :            :      * provoke one-over-the-limit cases (not exhaustive, but sharp).
          78                 :            :      */
          79                 :            :     {
          80                 :            :         PyObject *one, *x, *y;
          81                 :            :         TYPENAME out;
          82                 :            :         unsigned TYPENAME uout;
          83                 :            :
          84                 :          0 :         one = PyLong_FromLong(1);
          85         [ #  # ]:          0 :         if (one == NULL)
          86                 :          0 :             return error(
          87                 :            :                 "unexpected NULL from PyLong_FromLong");
          88                 :            :
          89                 :            :         /* Unsigned complains about -1? */
          90                 :          0 :         x = PyNumber_Negative(one);
          91         [ #  # ]:          0 :         if (x == NULL)
          92                 :          0 :             return error(
          93                 :            :                 "unexpected NULL from PyNumber_Negative");
          94                 :            :
          95                 :          0 :         uout = F_PY_TO_U(x);
          96   [ #  #  #  # ]:          0 :         if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
          97                 :          0 :             return error(
          98                 :            :                 "PyLong_AsUnsignedXXX(-1) didn't complain");
          99         [ #  # ]:          0 :         if (!PyErr_ExceptionMatches(PyExc_OverflowError))
         100                 :          0 :             return error(
         101                 :            :                 "PyLong_AsUnsignedXXX(-1) raised "
         102                 :            :                 "something other than OverflowError");
         103                 :          0 :         PyErr_Clear();
         104                 :          0 :         UNBIND(x);
         105                 :            :
         106                 :            :         /* Unsigned complains about 2**NBITS? */
         107                 :          0 :         y = PyLong_FromLong((long)NBITS);
         108         [ #  # ]:          0 :         if (y == NULL)
         109                 :          0 :             return error(
         110                 :            :                 "unexpected NULL from PyLong_FromLong");
         111                 :            :
         112                 :          0 :         x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */
         113                 :          0 :         UNBIND(y);
         114         [ #  # ]:          0 :         if (x == NULL)
         115                 :          0 :             return error(
         116                 :            :                 "unexpected NULL from PyNumber_Lshift");
         117                 :            :
         118                 :          0 :         uout = F_PY_TO_U(x);
         119   [ #  #  #  # ]:          0 :         if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
         120                 :          0 :             return error(
         121                 :            :                 "PyLong_AsUnsignedXXX(2**NBITS) didn't "
         122                 :            :                 "complain");
         123         [ #  # ]:          0 :         if (!PyErr_ExceptionMatches(PyExc_OverflowError))
         124                 :          0 :             return error(
         125                 :            :                 "PyLong_AsUnsignedXXX(2**NBITS) raised "
         126                 :            :                 "something other than OverflowError");
         127                 :          0 :         PyErr_Clear();
         128                 :            :
         129                 :            :         /* Signed complains about 2**(NBITS-1)?
         130                 :            :            x still has 2**NBITS. */
         131                 :          0 :         y = PyNumber_Rshift(x, one); /* 2**(NBITS-1) */
         132                 :          0 :         UNBIND(x);
         133         [ #  # ]:          0 :         if (y == NULL)
         134                 :          0 :             return error(
         135                 :            :                 "unexpected NULL from PyNumber_Rshift");
         136                 :            :
         137                 :          0 :         out = F_PY_TO_S(y);
         138   [ #  #  #  # ]:          0 :         if (out != (TYPENAME)-1 || !PyErr_Occurred())
         139                 :          0 :             return error(
         140                 :            :                 "PyLong_AsXXX(2**(NBITS-1)) didn't "
         141                 :            :                 "complain");
         142         [ #  # ]:          0 :         if (!PyErr_ExceptionMatches(PyExc_OverflowError))
         143                 :          0 :             return error(
         144                 :            :                 "PyLong_AsXXX(2**(NBITS-1)) raised "
         145                 :            :                 "something other than OverflowError");
         146                 :          0 :         PyErr_Clear();
         147                 :            :
         148                 :            :         /* Signed complains about -2**(NBITS-1)-1?;
         149                 :            :            y still has 2**(NBITS-1). */
         150                 :          0 :         x = PyNumber_Negative(y);  /* -(2**(NBITS-1)) */
         151                 :          0 :         UNBIND(y);
         152         [ #  # ]:          0 :         if (x == NULL)
         153                 :          0 :             return error(
         154                 :            :                 "unexpected NULL from PyNumber_Negative");
         155                 :            :
         156                 :          0 :         y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */
         157                 :          0 :         UNBIND(x);
         158         [ #  # ]:          0 :         if (y == NULL)
         159                 :          0 :             return error(
         160                 :            :                 "unexpected NULL from PyNumber_Subtract");
         161                 :            :
         162                 :          0 :         out = F_PY_TO_S(y);
         163   [ #  #  #  # ]:          0 :         if (out != (TYPENAME)-1 || !PyErr_Occurred())
         164                 :          0 :             return error(
         165                 :            :                 "PyLong_AsXXX(-2**(NBITS-1)-1) didn't "
         166                 :            :                 "complain");
         167         [ #  # ]:          0 :         if (!PyErr_ExceptionMatches(PyExc_OverflowError))
         168                 :          0 :             return error(
         169                 :            :                 "PyLong_AsXXX(-2**(NBITS-1)-1) raised "
         170                 :            :                 "something other than OverflowError");
         171                 :          0 :         PyErr_Clear();
         172                 :          0 :         UNBIND(y);
         173                 :            :
         174                 :          0 :         Py_XDECREF(x);
         175                 :          0 :         Py_XDECREF(y);
         176                 :          0 :         Py_DECREF(one);
         177                 :            :     }
         178                 :            :
         179                 :            :     /* Test F_PY_TO_{S,U} on non-pylong input. This should raise a TypeError. */
         180                 :            :     {
         181                 :            :         TYPENAME out;
         182                 :            :         unsigned TYPENAME uout;
         183                 :            :
         184                 :          0 :         Py_INCREF(Py_None);
         185                 :            :
         186                 :          0 :         out = F_PY_TO_S(Py_None);
         187   [ #  #  #  # ]:          0 :         if (out != (TYPENAME)-1 || !PyErr_Occurred())
         188                 :          0 :             return error("PyLong_AsXXX(None) didn't complain");
         189         [ #  # ]:          0 :         if (!PyErr_ExceptionMatches(PyExc_TypeError))
         190                 :          0 :             return error("PyLong_AsXXX(None) raised "
         191                 :            :                          "something other than TypeError");
         192                 :          0 :         PyErr_Clear();
         193                 :            :
         194                 :          0 :         uout = F_PY_TO_U(Py_None);
         195   [ #  #  #  # ]:          0 :         if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
         196                 :          0 :             return error("PyLong_AsXXX(None) didn't complain");
         197         [ #  # ]:          0 :         if (!PyErr_ExceptionMatches(PyExc_TypeError))
         198                 :          0 :             return error("PyLong_AsXXX(None) raised "
         199                 :            :                          "something other than TypeError");
         200                 :          0 :         PyErr_Clear();
         201                 :            :
         202                 :          0 :         Py_DECREF(Py_None);
         203                 :            :     }
         204                 :            :
         205                 :          0 :     return Py_NewRef(Py_None);
         206                 :            : }

Generated by: LCOV version 1.14