]> 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 07:42:52 +0000 (07:42 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Sat, 9 Jun 2007 07:42:52 +0000 (07:42 +0000)
Will backport to 2.5.

Include/pyport.h
Lib/test/test_structmembers.py
Misc/NEWS
Modules/_testcapimodule.c
PC/pyconfig.h
Python/structmember.c

index 36d517cd99dac61cf8cb132e0714d48aa8cb135c..2a2950634f067e91bb16dbfb8c50575473fee533 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 33fc776acee3110dea95c6ec01b1573ca18917c6..ef00f94c001bf026ac597c4ccd7da41981963880 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
 from test import test_support
@@ -39,6 +40,23 @@ 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)
+
+
 class TestWarnings(unittest.TestCase):
     def has_warned(self, w):
         self.assert_(w.category is RuntimeWarning)
index ad5fd5ce4908cbb1458faa6f99ff36474be8e291..699f723ef918755b882133290e0eee765b9c5267 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 2.6 alpha 1?
 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 6936d65ca9c6b2579bf92433c271f5e5e334f5d5..314fbf17fb9e961e41de4fcb3f425ccd4cbf7235 100644 (file)
@@ -247,6 +247,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 */
 
 /* ------------------------------------------------------------------------*/
@@ -272,6 +275,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_MIN ULLONG_MIN
 #endif
 
 /* For Windows the Python core is in a DLL by default.  Test
index 94d222a1e4990dfe915869dbcf10990a03023087..17422d0d91538739fd8a9feb11b64d4dbf6a50f3 100644 (file)
@@ -293,31 +293,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,