]> granicus.if.org Git - python/commitdiff
Implement stage B0 of PEP 237: add warnings for operations that
authorGuido van Rossum <guido@python.org>
Sun, 11 Aug 2002 04:24:12 +0000 (04:24 +0000)
committerGuido van Rossum <guido@python.org>
Sun, 11 Aug 2002 04:24:12 +0000 (04:24 +0000)
currently return inconsistent results for ints and longs; in
particular: hex/oct/%u/%o/%x/%X of negative short ints, and x<<n that
either loses bits or changes sign.  (No warnings for repr() of a long,
though that will also change to lose the trailing 'L' eventually.)

This introduces some warnings in the test suite; I'll take care of
those later.

Objects/intobject.c
Objects/stringobject.c
Objects/unicodeobject.c
Python/compile.c

index 4f43b111e502d44aa2106db57e2bd482aa5f451e..728f798a5b66602f2ac584751307806cb58ff488 100644 (file)
@@ -659,7 +659,7 @@ int_invert(PyIntObject *v)
 static PyObject *
 int_lshift(PyIntObject *v, PyIntObject *w)
 {
-       register long a, b;
+       long a, b, c;
        CONVERT_TO_LONG(v, a);
        CONVERT_TO_LONG(w, b);
        if (b < 0) {
@@ -669,10 +669,20 @@ int_lshift(PyIntObject *v, PyIntObject *w)
        if (a == 0 || b == 0)
                return int_pos(v);
        if (b >= LONG_BIT) {
+               if (PyErr_Warn(PyExc_DeprecationWarning,
+                              "x<<y losing bits or changing sign "
+                              "will return a long in Python 2.4 and up") < 0)
+                       return NULL;
                return PyInt_FromLong(0L);
        }
-       a = (long)((unsigned long)a << b);
-       return PyInt_FromLong(a);
+       c = (long)((unsigned long)a << b);
+       if ((c >> b) != a || (c < 0 && a > 0)) {
+               if (PyErr_Warn(PyExc_DeprecationWarning,
+                              "x<<y losing bits or changing sign "
+                              "will return a long in Python 2.4 and up") < 0)
+                       return NULL;
+       }
+       return PyInt_FromLong(c);
 }
 
 static PyObject *
@@ -761,6 +771,12 @@ int_oct(PyIntObject *v)
 {
        char buf[100];
        long x = v -> ob_ival;
+       if (x < 0) {
+               if (PyErr_Warn(PyExc_DeprecationWarning,
+                              "hex()/oct() of negative int will return "
+                              "a signed string in Python 2.4 and up") < 0)
+                       return NULL;
+       }
        if (x == 0)
                strcpy(buf, "0");
        else
@@ -773,6 +789,12 @@ int_hex(PyIntObject *v)
 {
        char buf[100];
        long x = v -> ob_ival;
+       if (x < 0) {
+               if (PyErr_Warn(PyExc_DeprecationWarning,
+                              "hex()/oct() of negative int will return "
+                              "a signed string in Python 2.4 and up") < 0)
+                       return NULL;
+       }
        PyOS_snprintf(buf, sizeof(buf), "0x%lx", x);
        return PyString_FromString(buf);
 }
index 1d5277c0c78e3064b5a6b61c59037fad7a7bd441..1bbd201047f7daac21e74e51f4957999cd143bd6 100644 (file)
@@ -3311,6 +3311,12 @@ formatint(char *buf, size_t buflen, int flags,
                PyErr_SetString(PyExc_TypeError, "int argument required");
                return -1;
        }
+       if (x < 0 && type != 'd' && type != 'i') {
+               if (PyErr_Warn(PyExc_DeprecationWarning,
+                              "%u/%o/%x/%X of negative int will return "
+                              "a signed string in Python 2.4 and up") < 0)
+                       return -1;
+       }
        if (prec < 0)
                prec = 1;
 
index d6fd62af8040a2ee3bd8e005aa012ea1b2f357b1..145186e0dffb2093ca1ac5f9280e938383e67cca 100644 (file)
@@ -5219,6 +5219,10 @@ int usprintf(register Py_UNICODE *buffer, char *format, ...)
     return len;
 }
 
+/* XXX To save some code duplication, formatfloat/long/int could have been
+   shared with stringobject.c, converting from 8-bit to Unicode after the
+   formatting is done. */
+
 static int
 formatfloat(Py_UNICODE *buf,
            size_t buflen,
@@ -5294,6 +5298,12 @@ formatint(Py_UNICODE *buf,
     x = PyInt_AsLong(v);
     if (x == -1 && PyErr_Occurred())
         return -1;
+    if (x < 0 && type != 'd' && type != 'i') {
+       if (PyErr_Warn(PyExc_DeprecationWarning,
+                      "%u/%o/%x/%X of negative int will return "
+                      "a signed string in Python 2.4 and up") < 0)
+           return -1;
+    }
     if (prec < 0)
         prec = 1;
 
index 79756eab0ec0881285c8c737ddf1fdfc95344f92..e547e03b260095cb1b633cd49815ad6861772f25 100644 (file)
@@ -1154,8 +1154,16 @@ parsenumber(struct compiling *co, char *s)
 #endif
        if (*end == 'l' || *end == 'L')
                return PyLong_FromString(s, (char **)0, 0);
-       if (s[0] == '0')
+       if (s[0] == '0') {
                x = (long) PyOS_strtoul(s, &end, 0);
+               if (x < 0 && errno == 0) {
+                       if (PyErr_Warn(PyExc_DeprecationWarning,
+                                      "hex/oct constants > sys.maxint "
+                                      "will return positive values "
+                                      "in Python 2.4 and up") < 0)
+                               return NULL;
+               }
+       }
        else
                x = PyOS_strtol(s, &end, 0);
        if (*end == '\0') {