]> granicus.if.org Git - python/commitdiff
Patch #1733960: Allow T_LONGLONG to accept ints.
authorMartin v. Löwis <martin@v.loewis.de>
Sat, 9 Jun 2007 08:01:33 +0000 (08:01 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Sat, 9 Jun 2007 08:01:33 +0000 (08:01 +0000)
Include/pyport.h
Lib/test/test_structmembers.py
Misc/NEWS
Modules/_testcapimodule.c
PC/pyconfig.h
Python/structmember.c

index 6fe3f0b528f4e9aa39f926be2142e67d097fb63b..8c8b0f722b2bc5bdc6cf3f831c72bf81d8474604 100644 (file)
@@ -61,6 +61,9 @@ Used in:  PY_LONG_LONG
 #ifdef HAVE_LONG_LONG
 #ifndef PY_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 /* HAVE_LONG_LONG */
 
index 7fcf785eb0d158bfcef0bafe53935df9e57cf6cb..751afe9472a7aef73f7e7653bcfe2e5bd4041e86 100644 (file)
@@ -2,7 +2,8 @@ from _testcapi import test_structmembersType, \
     CHAR_MAX, CHAR_MIN, UCHAR_MAX, \
     SHRT_MAX, SHRT_MIN, USHRT_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, test.test_warnings
 from test import test_support
@@ -39,6 +40,24 @@ class ReadWriteTests(unittest.TestCase):
         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)
+
+
+
 def test_main(verbose=None):
     test_support.run_unittest(
         ReadWriteTests
index 22f05abd2ee0c4a9d47c15d815fd51e9c8f733ac..93cc32d8acf5df1f537f20a3080c32123881f274 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 2.5.2c1?
 Core and builtins
 -----------------
 
+- Patch #1733960: Allow T_LONGLONG to accept ints.
+
 - Prevent expandtabs() on string and unicode objects from causing a segfault when
   a large width is passed on 32-bit platforms.
 
index b11f0aebfc1135a0a52ffc2f40d3ceaa1c9f55b4..84dc1e1c0850ef5d985215a5b3fa882bd1f5f609 100644 (file)
@@ -772,6 +772,10 @@ typedef struct {
        unsigned long ulong_member;
        float float_member;
        double double_member;
+#ifdef HAVE_LONG_LONG
+       PY_LONG_LONG longlong_member;
+       unsigned PY_LONG_LONG ulonglong_member;
+#endif
 } all_structmembers;
 
 typedef struct {
@@ -790,23 +794,40 @@ static struct PyMemberDef test_members[] = {
        {"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_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}
 };
 
 
 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",
-               "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);
        if (ob==NULL)
                return NULL;
        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.short_member, &ob->structmembers.ushort_member,
                &ob->structmembers.int_member, &ob->structmembers.uint_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);
                return NULL;
                }
@@ -889,6 +910,9 @@ init_testcapi(void)
        PyModule_AddObject(m, "FLT_MIN", PyFloat_FromDouble(FLT_MIN));
        PyModule_AddObject(m, "DBL_MAX", PyFloat_FromDouble(DBL_MAX));
        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_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN));
 
index 20201d09ac6532371afa107c7a50322834960219..6c925cf8c383085f433924e7548384c6fae742b5 100644 (file)
@@ -234,6 +234,9 @@ typedef int pid_t;
 #define COMPILER "[gcc]"
 #define hypot _hypot
 #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 */
 
 /* ------------------------------------------------------------------------*/
@@ -259,6 +262,9 @@ typedef int pid_t;
 #define HAVE_LONG_LONG 1
 #ifndef PY_LONG_LONG
 #      define PY_LONG_LONG __int64
+#      define PY_LLONG_MAX LLONG_MAX
+#      define PY_LLONG_MIN LLONG_MIN
+#      define PY_ULLONG_MAX ULLONG_MAX
 #endif
 
 /* For Windows the Python core is in a DLL by default.  Test
index 03934c0c844929872f7ea9a293898a2fbf48b534..8275589f15418b132757725b2ace2104d266e6ed 100644 (file)
@@ -277,31 +277,25 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
                }
                break;
 #ifdef HAVE_LONG_LONG
-       case T_LONGLONG:
-               if (!PyLong_Check(v)) {
-                       PyErr_BadArgument();
+       case T_LONGLONG:{
+               PY_LONG_LONG value;
+               *(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v);
+               if ((value == -1) && PyErr_Occurred())
                        return -1;
-               } else {
-                        PY_LONG_LONG value;
-                        *(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v);
-                        if ((value == -1) && PyErr_Occurred()) {
-                                return -1;
-                        }
-                }
-                break;
-       case T_ULONGLONG:
-                if (!PyLong_Check(v)) {
-                        PyErr_BadArgument();
-                        return -1;
-                } else {
-                        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;
+               break;
+               }
+       case T_ULONGLONG:{
+               unsigned PY_LONG_LONG value;
+               /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong
+                       doesn't ??? */
+               if (PyLong_Check(v))
+                       *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v);
+               else
+                       *(unsigned PY_LONG_LONG*)addr = value = PyInt_AsLong(v);
+               if ((value == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())
+                       return -1;
+               break;
+               }
 #endif /* HAVE_LONG_LONG */
        default:
                PyErr_Format(PyExc_SystemError,