Patch #1733960: Allow T_LONGLONG to accept ints.

Will backport to 2.5.
This commit is contained in:
Martin v. Löwis 2007-06-09 07:42:52 +00:00
parent 080b598990
commit 6371cd8177
6 changed files with 75 additions and 28 deletions

View File

@ -61,6 +61,9 @@ Used in: PY_LONG_LONG
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
#ifndef PY_LONG_LONG #ifndef PY_LONG_LONG
#define PY_LONG_LONG long long #define PY_LONG_LONG long long
#define PY_LLONG_MIN LLONG_MIN
#define PY_LLONG_MAX LLONG_MAX
#define PY_ULLONG_MAX ULLONG_MAX
#endif #endif
#endif /* HAVE_LONG_LONG */ #endif /* HAVE_LONG_LONG */

View File

@ -2,7 +2,8 @@ from _testcapi import test_structmembersType, \
CHAR_MAX, CHAR_MIN, UCHAR_MAX, \ CHAR_MAX, CHAR_MIN, UCHAR_MAX, \
SHRT_MAX, SHRT_MIN, USHRT_MAX, \ SHRT_MAX, SHRT_MIN, USHRT_MAX, \
INT_MAX, INT_MIN, UINT_MAX, \ INT_MAX, INT_MIN, UINT_MAX, \
LONG_MAX, LONG_MIN, ULONG_MAX LONG_MAX, LONG_MIN, ULONG_MAX, \
LLONG_MAX, LLONG_MIN, ULLONG_MAX
import warnings, exceptions, unittest import warnings, exceptions, unittest
from test import test_support from test import test_support
@ -39,6 +40,23 @@ class ReadWriteTests(unittest.TestCase):
ts.T_ULONG=ULONG_MAX ts.T_ULONG=ULONG_MAX
self.assertEquals(ts.T_ULONG, ULONG_MAX) self.assertEquals(ts.T_ULONG, ULONG_MAX)
## T_LONGLONG and T_ULONGLONG may not be present on some platforms
if hasattr(ts, 'T_LONGLONG'):
ts.T_LONGLONG=LLONG_MAX
self.assertEquals(ts.T_LONGLONG, LLONG_MAX)
ts.T_LONGLONG=LLONG_MIN
self.assertEquals(ts.T_LONGLONG, LLONG_MIN)
ts.T_ULONGLONG=ULLONG_MAX
self.assertEquals(ts.T_ULONGLONG, ULLONG_MAX)
## make sure these will accept a plain int as well as a long
ts.T_LONGLONG=3
self.assertEquals(ts.T_LONGLONG, 3)
ts.T_ULONGLONG=4
self.assertEquals(ts.T_ULONGLONG, 4)
class TestWarnings(unittest.TestCase): class TestWarnings(unittest.TestCase):
def has_warned(self, w): def has_warned(self, w):
self.assert_(w.category is RuntimeWarning) self.assert_(w.category is RuntimeWarning)

View File

@ -12,6 +12,8 @@ What's New in Python 2.6 alpha 1?
Core and builtins Core and builtins
----------------- -----------------
- Patch #1733960: Allow T_LONGLONG to accept ints.
- Prevent expandtabs() on string and unicode objects from causing a segfault when - Prevent expandtabs() on string and unicode objects from causing a segfault when
a large width is passed on 32-bit platforms. a large width is passed on 32-bit platforms.

View File

@ -772,6 +772,10 @@ typedef struct {
unsigned long ulong_member; unsigned long ulong_member;
float float_member; float float_member;
double double_member; double double_member;
#ifdef HAVE_LONG_LONG
PY_LONG_LONG longlong_member;
unsigned PY_LONG_LONG ulonglong_member;
#endif
} all_structmembers; } all_structmembers;
typedef struct { typedef struct {
@ -790,23 +794,40 @@ static struct PyMemberDef test_members[] = {
{"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL}, {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL},
{"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
{"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
#ifdef HAVE_LONG_LONG
{"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL},
{"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL},
#endif
{NULL} {NULL}
}; };
static PyObject *test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs){ static PyObject *test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs){
static char *keywords[]={"T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", "T_INT", "T_UINT", static char *keywords[]={"T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", "T_INT", "T_UINT",
"T_LONG", "T_ULONG", "T_FLOAT", "T_DOUBLE", NULL}; "T_LONG", "T_ULONG", "T_FLOAT", "T_DOUBLE",
#ifdef HAVE_LONG_LONG
"T_LONGLONG", "T_ULONGLONG",
#endif
NULL};
static char *fmt="|bBhHiIlkfd"
#ifdef HAVE_LONG_LONG
"LK"
#endif
;
test_structmembers *ob=PyObject_New(test_structmembers, type); test_structmembers *ob=PyObject_New(test_structmembers, type);
if (ob==NULL) if (ob==NULL)
return NULL; return NULL;
memset(&ob->structmembers, 0, sizeof(all_structmembers)); memset(&ob->structmembers, 0, sizeof(all_structmembers));
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|bBhHiIlkfd", keywords, if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords,
&ob->structmembers.byte_member, &ob->structmembers.ubyte_member, &ob->structmembers.byte_member, &ob->structmembers.ubyte_member,
&ob->structmembers.short_member, &ob->structmembers.ushort_member, &ob->structmembers.short_member, &ob->structmembers.ushort_member,
&ob->structmembers.int_member, &ob->structmembers.uint_member, &ob->structmembers.int_member, &ob->structmembers.uint_member,
&ob->structmembers.long_member, &ob->structmembers.ulong_member, &ob->structmembers.long_member, &ob->structmembers.ulong_member,
&ob->structmembers.float_member, &ob->structmembers.double_member)){ &ob->structmembers.float_member, &ob->structmembers.double_member
#ifdef HAVE_LONG_LONG
,&ob->structmembers.longlong_member, &ob->structmembers.ulonglong_member
#endif
)){
Py_DECREF(ob); Py_DECREF(ob);
return NULL; return NULL;
} }
@ -889,6 +910,9 @@ init_testcapi(void)
PyModule_AddObject(m, "FLT_MIN", PyFloat_FromDouble(FLT_MIN)); PyModule_AddObject(m, "FLT_MIN", PyFloat_FromDouble(FLT_MIN));
PyModule_AddObject(m, "DBL_MAX", PyFloat_FromDouble(DBL_MAX)); PyModule_AddObject(m, "DBL_MAX", PyFloat_FromDouble(DBL_MAX));
PyModule_AddObject(m, "DBL_MIN", PyFloat_FromDouble(DBL_MIN)); PyModule_AddObject(m, "DBL_MIN", PyFloat_FromDouble(DBL_MIN));
PyModule_AddObject(m, "LLONG_MAX", PyLong_FromLongLong(PY_LLONG_MAX));
PyModule_AddObject(m, "LLONG_MIN", PyLong_FromLongLong(PY_LLONG_MIN));
PyModule_AddObject(m, "ULLONG_MAX", PyLong_FromUnsignedLongLong(PY_ULLONG_MAX));
PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyInt_FromSsize_t(PY_SSIZE_T_MAX)); PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyInt_FromSsize_t(PY_SSIZE_T_MAX));
PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN)); PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN));

View File

@ -247,6 +247,9 @@ typedef int pid_t;
#define COMPILER "[gcc]" #define COMPILER "[gcc]"
#define hypot _hypot #define hypot _hypot
#define PY_LONG_LONG long long #define PY_LONG_LONG long long
#define PY_LLONG_MIN LLONG_MIN
#define PY_LLONG_MAX LLONG_MAX
#define PY_ULLONG_MAX ULLONG_MAX
#endif /* GNUC */ #endif /* GNUC */
/* ------------------------------------------------------------------------*/ /* ------------------------------------------------------------------------*/
@ -272,6 +275,9 @@ typedef int pid_t;
#define HAVE_LONG_LONG 1 #define HAVE_LONG_LONG 1
#ifndef PY_LONG_LONG #ifndef PY_LONG_LONG
# define PY_LONG_LONG __int64 # define PY_LONG_LONG __int64
# define PY_LLONG_MAX LLONG_MAX
# define PY_LLONG_MIN LLONG_MIN
# define PY_ULLONG_MIN ULLONG_MIN
#endif #endif
/* For Windows the Python core is in a DLL by default. Test /* For Windows the Python core is in a DLL by default. Test

View File

@ -293,31 +293,25 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
} }
break; break;
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
case T_LONGLONG: case T_LONGLONG:{
if (!PyLong_Check(v)) { PY_LONG_LONG value;
PyErr_BadArgument(); *(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v);
if ((value == -1) && PyErr_Occurred())
return -1; return -1;
} else { break;
PY_LONG_LONG value; }
*(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v); case T_ULONGLONG:{
if ((value == -1) && PyErr_Occurred()) { unsigned PY_LONG_LONG value;
return -1; /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong
} doesn't ??? */
} if (PyLong_Check(v))
break; *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v);
case T_ULONGLONG: else
if (!PyLong_Check(v)) { *(unsigned PY_LONG_LONG*)addr = value = PyInt_AsLong(v);
PyErr_BadArgument(); if ((value == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())
return -1; return -1;
} else { break;
unsigned PY_LONG_LONG value; }
*(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v);
if ((value == (unsigned PY_LONG_LONG)-1) &&
PyErr_Occurred()) {
return -1;
}
}
break;
#endif /* HAVE_LONG_LONG */ #endif /* HAVE_LONG_LONG */
default: default:
PyErr_Format(PyExc_SystemError, PyErr_Format(PyExc_SystemError,