Issue #1172711: Add 'long long' support to the array module.
Initial patch by Oren Tirosh and Hirokazu Yamamoto.
This commit is contained in:
parent
4ad6ed7d4d
commit
1c9f0c93ad
|
@ -14,37 +14,49 @@ them is constrained. The type is specified at object creation time by using a
|
|||
:dfn:`type code`, which is a single character. The following type codes are
|
||||
defined:
|
||||
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| Type code | C Type | Python Type | Minimum size in bytes |
|
||||
+===========+================+===================+=======================+
|
||||
| ``'b'`` | signed char | int | 1 |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| ``'B'`` | unsigned char | int | 1 |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| ``'u'`` | Py_UNICODE | Unicode character | 2 (see note) |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| ``'h'`` | signed short | int | 2 |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| ``'H'`` | unsigned short | int | 2 |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| ``'i'`` | signed int | int | 2 |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| ``'I'`` | unsigned int | int | 2 |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| ``'l'`` | signed long | int | 4 |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| ``'L'`` | unsigned long | int | 4 |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| ``'f'`` | float | float | 4 |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
| ``'d'`` | double | float | 8 |
|
||||
+-----------+----------------+-------------------+-----------------------+
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| Type code | C Type | Python Type | Minimum size in bytes | Notes |
|
||||
+===========+====================+===================+=======================+=======+
|
||||
| ``'b'`` | signed char | int | 1 | |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'B'`` | unsigned char | int | 1 | |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'u'`` | Py_UNICODE | Unicode character | 2 | \(1) |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'h'`` | signed short | int | 2 | |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'H'`` | unsigned short | int | 2 | |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'i'`` | signed int | int | 2 | |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'I'`` | unsigned int | int | 2 | |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'l'`` | signed long | int | 4 | |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'L'`` | unsigned long | int | 4 | |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'q'`` | signed long long | int | 8 | \(2) |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'Q'`` | unsigned long long | int | 8 | \(2) |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'f'`` | float | float | 4 | |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
| ``'d'`` | double | float | 8 | |
|
||||
+-----------+--------------------+-------------------+-----------------------+-------+
|
||||
|
||||
.. note::
|
||||
Notes:
|
||||
|
||||
The ``'u'`` typecode corresponds to Python's unicode character. On narrow
|
||||
(1)
|
||||
The ``'u'`` type code corresponds to Python's unicode character. On narrow
|
||||
Unicode builds this is 2-bytes, on wide builds this is 4-bytes.
|
||||
|
||||
(2)
|
||||
The ``'q'`` and ``'Q'`` type codes are available only if
|
||||
the platform C compiler used to build Python supports C :ctype:`long long`,
|
||||
or, on Windows, :ctype:`__int64`.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
|
||||
The actual representation of values is determined by the machine architecture
|
||||
(strictly speaking, by the C implementation). The actual size can be accessed
|
||||
through the :attr:`itemsize` attribute.
|
||||
|
|
|
@ -16,6 +16,13 @@ import warnings
|
|||
import array
|
||||
from array import _array_reconstructor as array_reconstructor
|
||||
|
||||
try:
|
||||
# Try to determine availability of long long independently
|
||||
# of the array module under test
|
||||
struct.calcsize('@q')
|
||||
have_long_long = True
|
||||
except struct.error:
|
||||
have_long_long = False
|
||||
|
||||
class ArraySubclass(array.array):
|
||||
pass
|
||||
|
@ -26,6 +33,8 @@ class ArraySubclassWithKwargs(array.array):
|
|||
|
||||
tests = [] # list to accumulate all tests
|
||||
typecodes = "ubBhHiIlLfd"
|
||||
if have_long_long:
|
||||
typecodes += 'qQ'
|
||||
|
||||
class BadConstructorTest(unittest.TestCase):
|
||||
|
||||
|
@ -1205,6 +1214,18 @@ class UnsignedLongTest(UnsignedNumberTest):
|
|||
minitemsize = 4
|
||||
tests.append(UnsignedLongTest)
|
||||
|
||||
@unittest.skipIf(not have_long_long, 'need long long support')
|
||||
class LongLongTest(SignedNumberTest):
|
||||
typecode = 'q'
|
||||
minitemsize = 8
|
||||
tests.append(LongLongTest)
|
||||
|
||||
@unittest.skipIf(not have_long_long, 'need long long support')
|
||||
class UnsignedLongLongTest(UnsignedNumberTest):
|
||||
typecode = 'Q'
|
||||
minitemsize = 8
|
||||
tests.append(UnsignedLongLongTest)
|
||||
|
||||
class FPTest(NumberTest):
|
||||
example = [-42.0, 0, 42, 1e5, -1e10]
|
||||
smallerexample = [-42.0, 0, 42, 1e5, -2e10]
|
||||
|
|
|
@ -1287,6 +1287,9 @@ Tools/Demos
|
|||
Extension Modules
|
||||
-----------------
|
||||
|
||||
- Issue #1172711: Add 'long long' support to the array module.
|
||||
Initial patch by Oren Tirosh and Hirokazu Yamamoto.
|
||||
|
||||
- Issue #12483: ctypes: Fix a crash when the destruction of a callback
|
||||
object triggers the garbage collector.
|
||||
|
||||
|
|
|
@ -356,6 +356,59 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
|
||||
static PyObject *
|
||||
q_getitem(arrayobject *ap, Py_ssize_t i)
|
||||
{
|
||||
return PyLong_FromLongLong(((PY_LONG_LONG *)ap->ob_item)[i]);
|
||||
}
|
||||
|
||||
static int
|
||||
q_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
|
||||
{
|
||||
PY_LONG_LONG x;
|
||||
if (!PyArg_Parse(v, "L;array item must be integer", &x))
|
||||
return -1;
|
||||
if (i >= 0)
|
||||
((PY_LONG_LONG *)ap->ob_item)[i] = x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
QQ_getitem(arrayobject *ap, Py_ssize_t i)
|
||||
{
|
||||
return PyLong_FromUnsignedLongLong(
|
||||
((unsigned PY_LONG_LONG *)ap->ob_item)[i]);
|
||||
}
|
||||
|
||||
static int
|
||||
QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
|
||||
{
|
||||
unsigned PY_LONG_LONG x;
|
||||
if (PyLong_Check(v)) {
|
||||
x = PyLong_AsUnsignedLongLong(v);
|
||||
if (x == (unsigned PY_LONG_LONG) -1 && PyErr_Occurred())
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
PY_LONG_LONG y;
|
||||
if (!PyArg_Parse(v, "L;array item must be integer", &y))
|
||||
return -1;
|
||||
if (y < 0) {
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"unsigned long long is less than minimum");
|
||||
return -1;
|
||||
}
|
||||
x = (unsigned PY_LONG_LONG)y;
|
||||
}
|
||||
|
||||
if (i >= 0)
|
||||
((unsigned PY_LONG_LONG *)ap->ob_item)[i] = x;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
f_getitem(arrayobject *ap, Py_ssize_t i)
|
||||
{
|
||||
|
@ -406,6 +459,10 @@ static struct arraydescr descriptors[] = {
|
|||
{'I', sizeof(int), II_getitem, II_setitem, "I", 1, 0},
|
||||
{'l', sizeof(long), l_getitem, l_setitem, "l", 1, 1},
|
||||
{'L', sizeof(long), LL_getitem, LL_setitem, "L", 1, 0},
|
||||
#ifdef HAVE_LONG_LONG
|
||||
{'q', sizeof(PY_LONG_LONG), q_getitem, q_setitem, "q", 1, 1},
|
||||
{'Q', sizeof(PY_LONG_LONG), QQ_getitem, QQ_setitem, "Q", 1, 0},
|
||||
#endif
|
||||
{'f', sizeof(float), f_getitem, f_setitem, "f", 0, 0},
|
||||
{'d', sizeof(double), d_getitem, d_setitem, "d", 0, 0},
|
||||
{'\0', 0, 0, 0, 0, 0, 0} /* Sentinel */
|
||||
|
@ -1655,6 +1712,16 @@ typecode_to_mformat_code(int typecode)
|
|||
intsize = sizeof(long);
|
||||
is_signed = 0;
|
||||
break;
|
||||
#if HAVE_LONG_LONG
|
||||
case 'q':
|
||||
intsize = sizeof(PY_LONG_LONG);
|
||||
is_signed = 1;
|
||||
break;
|
||||
case 'Q':
|
||||
intsize = sizeof(PY_LONG_LONG);
|
||||
is_signed = 0;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return UNKNOWN_FORMAT;
|
||||
}
|
||||
|
@ -2501,7 +2568,11 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
}
|
||||
}
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
#ifdef HAVE_LONG_LONG
|
||||
"bad typecode (must be b, B, u, h, H, i, I, l, L, q, Q, f or d)");
|
||||
#else
|
||||
"bad typecode (must be b, B, u, h, H, i, I, l, L, f or d)");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2524,12 +2595,18 @@ is a single character. The following type codes are defined:\n\
|
|||
'I' unsigned integer 2 \n\
|
||||
'l' signed integer 4 \n\
|
||||
'L' unsigned integer 4 \n\
|
||||
'q' signed integer 8 (see note) \n\
|
||||
'Q' unsigned integer 8 (see note) \n\
|
||||
'f' floating point 4 \n\
|
||||
'd' floating point 8 \n\
|
||||
\n\
|
||||
NOTE: The 'u' typecode corresponds to Python's unicode character. On \n\
|
||||
NOTE: The 'u' type code corresponds to Python's unicode character. On \n\
|
||||
narrow builds this is 2-bytes on wide builds this is 4-bytes.\n\
|
||||
\n\
|
||||
NOTE: The 'q' and 'Q' type codes are only available if the platform \n\
|
||||
C compiler used to build Python supports 'long long', or, on Windows, \n\
|
||||
'__int64'.\n\
|
||||
\n\
|
||||
The constructor is:\n\
|
||||
\n\
|
||||
array(typecode [, initializer]) -- create a new array\n\
|
||||
|
|
Loading…
Reference in New Issue