Index: Doc/library/array.rst =================================================================== --- Doc/library/array.rst (revision 73761) +++ Doc/library/array.rst (working copy) @@ -15,34 +15,47 @@ :dfn:`type code`, which is a single character. The following type codes are defined: -+-----------+----------------+-------------------+-----------------------+ -| Type code | C Type | Python Type | Minimum size in bytes | -+===========+================+===================+=======================+ -| ``'c'`` | char | character | 1 | -+-----------+----------------+-------------------+-----------------------+ -| ``'b'`` | signed char | int | 1 | -+-----------+----------------+-------------------+-----------------------+ -| ``'B'`` | unsigned char | int | 1 | -+-----------+----------------+-------------------+-----------------------+ -| ``'u'`` | Py_UNICODE | Unicode character | 2 | -+-----------+----------------+-------------------+-----------------------+ -| ``'h'`` | signed short | int | 2 | -+-----------+----------------+-------------------+-----------------------+ -| ``'H'`` | unsigned short | int | 2 | -+-----------+----------------+-------------------+-----------------------+ -| ``'i'`` | signed int | int | 2 | -+-----------+----------------+-------------------+-----------------------+ -| ``'I'`` | unsigned int | long | 2 | -+-----------+----------------+-------------------+-----------------------+ -| ``'l'`` | signed long | int | 4 | -+-----------+----------------+-------------------+-----------------------+ -| ``'L'`` | unsigned long | long | 4 | -+-----------+----------------+-------------------+-----------------------+ -| ``'f'`` | float | float | 4 | -+-----------+----------------+-------------------+-----------------------+ -| ``'d'`` | double | float | 8 | -+-----------+----------------+-------------------+-----------------------+ ++-----------+--------------------+-------------------+-----------------------+-------+ +| Type code | C Type | Python Type | Minimum size in bytes | Notes | ++===========+====================+===================+=======================+=======+ +| ``'c'`` | char | character | 1 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'b'`` | signed char | int | 1 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'B'`` | unsigned char | int | 1 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'u'`` | Py_UNICODE | Unicode character | 2 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'h'`` | signed short | int | 2 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'H'`` | unsigned short | int | 2 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'i'`` | signed int | int | 2 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'I'`` | unsigned int | long | 2 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'l'`` | signed long | int | 4 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'L'`` | unsigned long | long | 4 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'q'`` | signed long long | long | 8 | \(1) | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'Q'`` | unsigned long long | long | 8 | \(1) | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'f'`` | float | float | 4 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +| ``'d'`` | double | float | 8 | | ++-----------+--------------------+-------------------+-----------------------+-------+ +Notes: + +(1) + The ``'q'`` and ``'Q'`` type codes are available only if + the platform C compiler supports C :ctype:`long long`, or, on Windows, + :ctype:`__int64`. + + .. versionadded:: 2.7 + 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. The values stored for ``'L'`` and Index: Lib/test/test_array.py =================================================================== --- Lib/test/test_array.py (revision 73761) +++ Lib/test/test_array.py (working copy) @@ -6,9 +6,17 @@ import unittest from test import test_support from weakref import proxy -import array, cStringIO +import array, cStringIO, struct from cPickle import loads, dumps, HIGHEST_PROTOCOL +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 @@ -18,6 +26,8 @@ tests = [] # list to accumulate all tests typecodes = "cubBhHiIlLfd" +if have_long_long: + typecodes += 'qQ' class BadConstructorTest(unittest.TestCase): @@ -976,6 +986,17 @@ minitemsize = 4 tests.append(UnsignedLongTest) +if have_long_long: + class LongLongTest(SignedNumberTest): + typecode = 'q' + minitemsize = 8 + tests.append(LongLongTest) + + 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] Index: Modules/arraymodule.c =================================================================== --- Modules/arraymodule.c (revision 73761) +++ Modules/arraymodule.c (working copy) @@ -355,7 +355,59 @@ return 0; } +#ifdef HAVE_LONG_LONG + static PyObject * +q_getitem(arrayobject *ap, int i) +{ + return PyLong_FromLongLong(((PY_LONG_LONG *)ap->ob_item)[i]); +} + +static int +q_setitem(arrayobject *ap, int 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, int i) +{ + return PyLong_FromUnsignedLongLong(((unsigned PY_LONG_LONG *)ap->ob_item)[i]); +} + +static int +QQ_setitem(arrayobject *ap, int 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) { return PyFloat_FromDouble((double) ((float *)ap->ob_item)[i]); @@ -403,6 +455,10 @@ {'I', sizeof(int), II_getitem, II_setitem}, {'l', sizeof(long), l_getitem, l_setitem}, {'L', sizeof(long), LL_getitem, LL_setitem}, +#ifdef HAVE_LONG_LONG + {'q', sizeof(PY_LONG_LONG), q_getitem, q_setitem}, + {'Q', sizeof(PY_LONG_LONG), QQ_getitem, QQ_setitem}, +#endif {'f', sizeof(float), f_getitem, f_setitem}, {'d', sizeof(double), d_getitem, d_setitem}, {'\0', 0, 0, 0} /* Sentinel */ @@ -2008,7 +2064,11 @@ } } PyErr_SetString(PyExc_ValueError, +#ifdef HAVE_LONG_LONG + "bad typecode (must be c, b, B, u, h, H, i, I, l, L, q, Q, f or d)"); +#else "bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d)"); +#endif return NULL; } @@ -2032,6 +2092,8 @@ 'I' unsigned integer 2 \n\ 'l' signed integer 4 \n\ 'L' unsigned integer 4 \n\ + 'q' signed integer 8 \n\ + 'Q' unsigned integer 8 \n\ 'f' floating point 4 \n\ 'd' floating point 8 \n\ \n\