diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/ctypes/test/test_arrays.py index 4ed566b48e6..6e562cfd24e 100644 --- a/Lib/ctypes/test/test_arrays.py +++ b/Lib/ctypes/test/test_arrays.py @@ -1,4 +1,6 @@ import unittest +from test.support import bigmemtest, _2G +import sys from ctypes import * from ctypes.test import need_symbol @@ -181,5 +183,10 @@ class ArrayTestCase(unittest.TestCase): _type_ = c_int _length_ = 1.87 + @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform') + @bigmemtest(size=_2G, memuse=1, dry_run=False) + def test_large_array(self, size): + c_char * size + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2017-09-29-16-40-38.bpo-16865.l-f6I_.rst b/Misc/NEWS.d/next/Library/2017-09-29-16-40-38.bpo-16865.l-f6I_.rst new file mode 100644 index 00000000000..afaff736bf1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-09-29-16-40-38.bpo-16865.l-f6I_.rst @@ -0,0 +1 @@ +Support arrays >=2GiB in :mod:`ctypes`. Patch by Segev Finer. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 93e8d8d4233..66bce151eb7 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1390,8 +1390,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) StgDictObject *stgdict; StgDictObject *itemdict; PyObject *length_attr, *type_attr; - long length; - int overflow; + Py_ssize_t length; Py_ssize_t itemsize, itemalign; /* create the new instance (which is a class, @@ -1413,14 +1412,15 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_XDECREF(length_attr); goto error; } - length = PyLong_AsLongAndOverflow(length_attr, &overflow); - if (overflow) { - PyErr_SetString(PyExc_OverflowError, - "The '_length_' attribute is too large"); - Py_DECREF(length_attr); + length = PyLong_AsSsize_t(length_attr); + Py_DECREF(length_attr); + if (length == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_SetString(PyExc_OverflowError, + "The '_length_' attribute is too large"); + } goto error; } - Py_DECREF(length_attr); type_attr = PyObject_GetAttrString((PyObject *)result, "_type_"); if (!type_attr) {