summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-08-11 04:24:12 (GMT)
committerGuido van Rossum <guido@python.org>2002-08-11 04:24:12 (GMT)
commit078151da901bebce6eb232d958fbbb1e5ced4399 (patch)
treed25483ba545d58138518591645e60caa20a7262b
parentd92ae840e940db2fc8e9ec6293fe22dbb73f4514 (diff)
downloadcpython-078151da901bebce6eb232d958fbbb1e5ced4399.zip
cpython-078151da901bebce6eb232d958fbbb1e5ced4399.tar.gz
cpython-078151da901bebce6eb232d958fbbb1e5ced4399.tar.bz2
Implement stage B0 of PEP 237: add warnings for operations that
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.
-rw-r--r--Objects/intobject.c28
-rw-r--r--Objects/stringobject.c6
-rw-r--r--Objects/unicodeobject.c10
-rw-r--r--Python/compile.c10
4 files changed, 50 insertions, 4 deletions
diff --git a/Objects/intobject.c b/Objects/intobject.c
index 4f43b11..728f798 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -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);
}
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 1d5277c..1bbd201 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -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;
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index d6fd62a..145186e 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -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;
diff --git a/Python/compile.c b/Python/compile.c
index 79756ea..e547e03 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -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') {