Skip to content

Commit e8d54b5

Browse files
committed
bpo-29843: raise TypeError or ValueError when appropriate
1 parent bdf4679 commit e8d54b5

File tree

3 files changed

+38
-25
lines changed

3 files changed

+38
-25
lines changed

Lib/ctypes/test/test_arrays.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,6 @@ class Y(T):
163163
self.assertEqual(Y()._length_, 187)
164164

165165
def test_bad_subclass(self):
166-
import sys
167-
168166
with self.assertRaises(AttributeError):
169167
class T(Array):
170168
pass
@@ -174,29 +172,29 @@ class T(Array):
174172
with self.assertRaises(AttributeError):
175173
class T(Array):
176174
_length_ = 13
177-
with self.assertRaises(OverflowError):
178-
class T(Array):
179-
_type_ = c_int
180-
_length_ = sys.maxsize * 2
181-
with self.assertRaises(AttributeError):
182-
class T(Array):
183-
_type_ = c_int
184-
_length_ = 1.87
185175

186176
def test_bad_length(self):
187-
with self.assertRaises(AttributeError):
177+
import sys
178+
179+
with self.assertRaises(ValueError):
188180
class T(Array):
189181
_type_ = c_int
190-
_length_ = -1 << 1000
191-
with self.assertRaises(AttributeError):
182+
_length_ = - sys.maxsize * 2
183+
with self.assertRaises(ValueError):
192184
class T(Array):
193185
_type_ = c_int
194186
_length_ = -1
187+
with self.assertRaises(TypeError):
188+
class T(Array):
189+
_type_ = c_int
190+
_length_ = 1.87
195191
with self.assertRaises(OverflowError):
196192
class T(Array):
197193
_type_ = c_int
198-
_length_ = 1 << 1000
199-
# _length_ might be zero.
194+
_length_ = sys.maxsize * 2
195+
196+
def test_zero_length(self):
197+
# _length_ can be zero.
200198
class T(Array):
201199
_type_ = c_int
202200
_length_ = 0
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
Raise `AttributeError` instead of `OverflowError` in case of a negative
2-
``_length_`` in a `ctypes.Array` subclass. Original patch by Oren Milman.
1+
Raise `ValueError` instead of `OverflowError` in case of a negative
2+
``_length_`` in a `ctypes.Array` subclass. Also raise `TypeError`
3+
instead of `OverflowError` for non-integer ``_length_``.
4+
Original patch by Oren Milman.

Modules/_ctypes/_ctypes.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,14 +1405,27 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
14051405
type_attr = NULL;
14061406

14071407
length_attr = PyObject_GetAttrString((PyObject *)result, "_length_");
1408-
if (!length_attr ||
1409-
!PyLong_Check(length_attr) ||
1410-
_PyLong_Sign(length_attr) == -1)
1411-
{
1412-
PyErr_SetString(PyExc_AttributeError,
1413-
"class must define a '_length_' attribute, "
1414-
"which must be a positive integer");
1415-
Py_XDECREF(length_attr);
1408+
if (!length_attr) {
1409+
if (!PyErr_Occurred() ||
1410+
PyErr_ExceptionMatches(PyExc_AttributeError))
1411+
{
1412+
PyErr_SetString(PyExc_AttributeError,
1413+
"class must define a '_length_' attribute");
1414+
}
1415+
goto error;
1416+
}
1417+
1418+
if (!PyLong_Check(length_attr)) {
1419+
Py_DECREF(length_attr);
1420+
PyErr_SetString(PyExc_TypeError,
1421+
"The '_length_' attribute must be an integer");
1422+
goto error;
1423+
}
1424+
1425+
if (_PyLong_Sign(length_attr) == -1) {
1426+
Py_DECREF(length_attr);
1427+
PyErr_SetString(PyExc_ValueError,
1428+
"The '_length_' attribute must not be negative");
14161429
goto error;
14171430
}
14181431

0 commit comments

Comments
 (0)