Skip to content

Commit bee1fb0

Browse files
committed
Merged revisions 78918,78920 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r78918 | mark.dickinson | 2010-03-13 11:34:40 +0000 (Sat, 13 Mar 2010) | 4 lines Issue #8014: Fix PyLong_As<c-integer-type> methods not to produce an internal error on non-integer input: they now raise TypeError instead. This is needed for attributes declared via PyMemberDefs. ........ r78920 | mark.dickinson | 2010-03-13 13:23:05 +0000 (Sat, 13 Mar 2010) | 3 lines Issue #8014: Fix incorrect error checks in structmember.c, and re-enable previously failing test_structmember.py tests. ........
1 parent de33fff commit bee1fb0

5 files changed

Lines changed: 61 additions & 13 deletions

File tree

Lib/test/test_structmembers.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
SHRT_MAX, SHRT_MIN, USHRT_MAX, \
44
INT_MAX, INT_MIN, UINT_MAX, \
55
LONG_MAX, LONG_MIN, ULONG_MAX, \
6-
LLONG_MAX, LLONG_MIN, ULLONG_MAX
6+
LLONG_MAX, LLONG_MIN, ULLONG_MAX, \
7+
PY_SSIZE_T_MAX, PY_SSIZE_T_MIN
78

89
import warnings, unittest, sys
910
from test import support
@@ -17,6 +18,7 @@
1718
6, # T_UINT
1819
7, # T_LONG
1920
8, # T_ULONG
21+
23, # T_PYSSIZET
2022
9.99999,# T_FLOAT
2123
10.1010101010, # T_DOUBLE
2224
"hi" # T_STRING_INPLACE
@@ -63,6 +65,12 @@ def test_long(self):
6365
ts.T_ULONG = ULONG_MAX
6466
self.assertEquals(ts.T_ULONG, ULONG_MAX)
6567

68+
def test_py_ssize_t(self):
69+
ts.T_PYSSIZET = PY_SSIZE_T_MAX
70+
self.assertEquals(ts.T_PYSSIZET, PY_SSIZE_T_MAX)
71+
ts.T_PYSSIZET = PY_SSIZE_T_MIN
72+
self.assertEquals(ts.T_PYSSIZET, PY_SSIZE_T_MIN)
73+
6674
@unittest.skipUnless(hasattr(ts, "T_LONGLONG"), "long long not present")
6775
def test_longlong(self):
6876
ts.T_LONGLONG = LLONG_MAX
@@ -79,6 +87,24 @@ def test_longlong(self):
7987
ts.T_ULONGLONG = 4
8088
self.assertEquals(ts.T_ULONGLONG, 4)
8189

90+
def test_bad_assignments(self):
91+
integer_attributes = [
92+
'T_BOOL',
93+
'T_BYTE', 'T_UBYTE',
94+
'T_SHORT', 'T_USHORT',
95+
'T_INT', 'T_UINT',
96+
'T_LONG', 'T_ULONG',
97+
'T_PYSSIZET'
98+
]
99+
if hasattr(ts, 'T_LONGLONG'):
100+
integer_attributes.extend(['T_LONGLONG', 'T_ULONGLONG'])
101+
102+
# issue8014: this produced 'bad argument to internal function'
103+
# internal error
104+
for nonint in None, 3.2j, "full of eels", {}, []:
105+
for attr in integer_attributes:
106+
self.assertRaises(TypeError, setattr, ts, attr, nonint)
107+
82108
def test_inplace_string(self):
83109
self.assertEquals(ts.T_STRING_INPLACE, "hi")
84110
self.assertRaises(TypeError, setattr, ts, "T_STRING_INPLACE", "s")

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 3.1.3?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #8014: Setting a T_UINT or T_PYSSIZET attribute of an object with
16+
PyMemberDefs could produce an internal error; raise TypeError instead.
17+
1518
- Raise a TypeError when trying to delete a T_STRING_INPLACE struct member.
1619

1720
- Issue #8226: sys.setfilesystemencoding() raises a LookupError if the encoding

Modules/_testcapimodule.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,7 @@ typedef struct {
16701670
unsigned int uint_member;
16711671
long long_member;
16721672
unsigned long ulong_member;
1673+
Py_ssize_t pyssizet_member;
16731674
float float_member;
16741675
double double_member;
16751676
char inplace_member[6];
@@ -1694,6 +1695,7 @@ static struct PyMemberDef test_members[] = {
16941695
{"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL},
16951696
{"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL},
16961697
{"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL},
1698+
{"T_PYSSIZET", T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL},
16971699
{"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
16981700
{"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
16991701
{"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL},
@@ -1710,13 +1712,13 @@ test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
17101712
{
17111713
static char *keywords[] = {
17121714
"T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT",
1713-
"T_INT", "T_UINT", "T_LONG", "T_ULONG",
1715+
"T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_PYSSIZET",
17141716
"T_FLOAT", "T_DOUBLE", "T_STRING_INPLACE",
1715-
#ifdef HAVE_LONG_LONG
1717+
#ifdef HAVE_LONG_LONG
17161718
"T_LONGLONG", "T_ULONGLONG",
17171719
#endif
17181720
NULL};
1719-
static char *fmt = "|bbBhHiIlkfds#"
1721+
static char *fmt = "|bbBhHiIlknfds#"
17201722
#ifdef HAVE_LONG_LONG
17211723
"LK"
17221724
#endif
@@ -1735,9 +1737,10 @@ test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
17351737
&ob->structmembers.short_member,
17361738
&ob->structmembers.ushort_member,
17371739
&ob->structmembers.int_member,
1738-
&ob->structmembers.uint_member,
1740+
&ob->structmembers.uint_member,
17391741
&ob->structmembers.long_member,
17401742
&ob->structmembers.ulong_member,
1743+
&ob->structmembers.pyssizet_member,
17411744
&ob->structmembers.float_member,
17421745
&ob->structmembers.double_member,
17431746
&s, &string_len

Objects/longobject.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -440,10 +440,15 @@ PyLong_AsSsize_t(PyObject *vv) {
440440
Py_ssize_t i;
441441
int sign;
442442

443-
if (vv == NULL || !PyLong_Check(vv)) {
443+
if (vv == NULL) {
444444
PyErr_BadInternalCall();
445445
return -1;
446446
}
447+
if (!PyLong_Check(vv)) {
448+
PyErr_SetString(PyExc_TypeError, "an integer is required");
449+
return -1;
450+
}
451+
447452
v = (PyLongObject *)vv;
448453
i = Py_SIZE(v);
449454
switch (i) {
@@ -490,10 +495,15 @@ PyLong_AsUnsignedLong(PyObject *vv)
490495
unsigned long x, prev;
491496
Py_ssize_t i;
492497

493-
if (vv == NULL || !PyLong_Check(vv)) {
498+
if (vv == NULL) {
494499
PyErr_BadInternalCall();
495-
return (unsigned long) -1;
500+
return (unsigned long)-1;
501+
}
502+
if (!PyLong_Check(vv)) {
503+
PyErr_SetString(PyExc_TypeError, "an integer is required");
504+
return (unsigned long)-1;
496505
}
506+
497507
v = (PyLongObject *)vv;
498508
i = Py_SIZE(v);
499509
x = 0;
@@ -528,10 +538,15 @@ PyLong_AsSize_t(PyObject *vv)
528538
size_t x, prev;
529539
Py_ssize_t i;
530540

531-
if (vv == NULL || !PyLong_Check(vv)) {
541+
if (vv == NULL) {
532542
PyErr_BadInternalCall();
533-
return (unsigned long) -1;
543+
return (size_t) -1;
544+
}
545+
if (!PyLong_Check(vv)) {
546+
PyErr_SetString(PyExc_TypeError, "an integer is required");
547+
return (size_t)-1;
534548
}
549+
535550
v = (PyLongObject *)vv;
536551
i = Py_SIZE(v);
537552
x = 0;

Python/structmember.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,13 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
187187
}
188188
case T_UINT:{
189189
unsigned long ulong_val = PyLong_AsUnsignedLong(v);
190-
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
190+
if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) {
191191
/* XXX: For compatibility, accept negative int values
192192
as well. */
193193
PyErr_Clear();
194194
ulong_val = PyLong_AsLong(v);
195-
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
195+
if ((ulong_val == (unsigned long)-1) &&
196+
PyErr_Occurred())
196197
return -1;
197198
*(unsigned int *)addr = (unsigned int)ulong_val;
198199
WARN("Writing negative value into unsigned field");
@@ -216,7 +217,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
216217
as well. */
217218
PyErr_Clear();
218219
*(unsigned long*)addr = PyLong_AsLong(v);
219-
if ((*(unsigned long*)addr == (unsigned int)-1)
220+
if ((*(unsigned long*)addr == (unsigned long)-1)
220221
&& PyErr_Occurred())
221222
return -1;
222223
WARN("Writing negative value into unsigned field");

0 commit comments

Comments
 (0)