Skip to content

Commit 735abad

Browse files
segevfinerserhiy-storchaka
authored andcommitted
bpo-16865: Support arrays >=2GB in ctypes. (GH-3006)
1 parent d063b84 commit 735abad

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

Lib/ctypes/test/test_arrays.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import unittest
2+
from test.support import bigmemtest, _2G
3+
import sys
24
from ctypes import *
35

46
from ctypes.test import need_symbol
@@ -181,5 +183,10 @@ class T(Array):
181183
_type_ = c_int
182184
_length_ = 1.87
183185

186+
@unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
187+
@bigmemtest(size=_2G, memuse=1, dry_run=False)
188+
def test_large_array(self, size):
189+
c_char * size
190+
184191
if __name__ == '__main__':
185192
unittest.main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support arrays >=2GiB in :mod:`ctypes`. Patch by Segev Finer.

Modules/_ctypes/_ctypes.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,8 +1390,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
13901390
StgDictObject *stgdict;
13911391
StgDictObject *itemdict;
13921392
PyObject *length_attr, *type_attr;
1393-
long length;
1394-
int overflow;
1393+
Py_ssize_t length;
13951394
Py_ssize_t itemsize, itemalign;
13961395

13971396
/* create the new instance (which is a class,
@@ -1413,14 +1412,15 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
14131412
Py_XDECREF(length_attr);
14141413
goto error;
14151414
}
1416-
length = PyLong_AsLongAndOverflow(length_attr, &overflow);
1417-
if (overflow) {
1418-
PyErr_SetString(PyExc_OverflowError,
1419-
"The '_length_' attribute is too large");
1420-
Py_DECREF(length_attr);
1415+
length = PyLong_AsSsize_t(length_attr);
1416+
Py_DECREF(length_attr);
1417+
if (length == -1 && PyErr_Occurred()) {
1418+
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
1419+
PyErr_SetString(PyExc_OverflowError,
1420+
"The '_length_' attribute is too large");
1421+
}
14211422
goto error;
14221423
}
1423-
Py_DECREF(length_attr);
14241424

14251425
type_attr = PyObject_GetAttrString((PyObject *)result, "_type_");
14261426
if (!type_attr) {

0 commit comments

Comments
 (0)