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.
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 @@
 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 @@
 	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 @@
 {
 	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 @@
 {
 	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 @@
 		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 @@
     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 @@
     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;