Commit 6c9e1305 authored by Guido van Rossum's avatar Guido van Rossum

- Removed FutureWarnings related to hex/oct literals and conversions

  and left shifts.  (Thanks to Kalle Svensson for SF patch 849227.)
  This addresses most of the remaining semantic changes promised by
  PEP 237, except for repr() of a long, which still shows the trailing
  'L'.  The PEP appears to promise warnings for operations that
  changed semantics compared to Python 2.3, but this is not
  implemented; we've suffered through enough warnings related to
  hex/oct literals and I think it's best to be silent now.
parent 37e13637
...@@ -580,25 +580,23 @@ allowed as suffix for long integers, it is strongly recommended to always ...@@ -580,25 +580,23 @@ allowed as suffix for long integers, it is strongly recommended to always
use \character{L}, since the letter \character{l} looks too much like the use \character{L}, since the letter \character{l} looks too much like the
digit \character{1}. digit \character{1}.
Plain integer decimal literals that are above the largest representable Plain integer literals that are above the largest representable plain
plain integer (e.g., 2147483647 when using 32-bit arithmetic) are accepted integer (e.g., 2147483647 when using 32-bit arithmetic) are accepted
as if they were long integers instead. Octal and hexadecimal literals as if they were long integers instead.\footnote{In versions of Python
behave similarly, but when in the range just above the largest representable prior to 2.4, octal and hexadecimal literals in the range just above
plain integer but below the largest unsigned 32-bit number (on a machine the largest representable plain integer but below the largest unsigned
using 32-bit arithmetic), 4294967296, they are taken as the negative plain 32-bit number (on a machine using 32-bit arithmetic), 4294967296, were
integer obtained by subtracting 4294967296 from their unsigned value. There taken as the negative plain integer obtained by subtracting 4294967296
is no limit for long integer literals apart from what can be stored in from their unsigned value.} There is no limit for long integer
available memory. For example, 0xdeadbeef is taken, on a 32-bit machine, literals apart from what can be stored in available memory.
as the value -559038737, while 0xdeadbeeffeed is taken as the value
244837814107885L.
Some examples of plain integer literals (first row) and long integer Some examples of plain integer literals (first row) and long integer
literals (second and third rows): literals (second and third rows):
\begin{verbatim} \begin{verbatim}
7 2147483647 0177 0x80000000 7 2147483647 0177
3L 79228162514264337593543950336L 0377L 0x100000000L 3L 79228162514264337593543950336L 0377L 0x100000000L
79228162514264337593543950336 0xdeadbeeffeed 79228162514264337593543950336 0xdeadbeef
\end{verbatim} \end{verbatim}
......
...@@ -437,8 +437,7 @@ class BuiltinTest(unittest.TestCase): ...@@ -437,8 +437,7 @@ class BuiltinTest(unittest.TestCase):
def test_hex(self): def test_hex(self):
self.assertEqual(hex(16), '0x10') self.assertEqual(hex(16), '0x10')
self.assertEqual(hex(16L), '0x10L') self.assertEqual(hex(16L), '0x10L')
self.assertEqual(len(hex(-1)), len(hex(sys.maxint))) self.assertEqual(hex(-16), '-0x10')
self.assert_(hex(-16) in ('0xfffffff0', '0xfffffffffffffff0'))
self.assertEqual(hex(-16L), '-0x10L') self.assertEqual(hex(-16L), '-0x10L')
self.assertRaises(TypeError, hex, {}) self.assertRaises(TypeError, hex, {})
...@@ -757,7 +756,7 @@ class BuiltinTest(unittest.TestCase): ...@@ -757,7 +756,7 @@ class BuiltinTest(unittest.TestCase):
def test_oct(self): def test_oct(self):
self.assertEqual(oct(100), '0144') self.assertEqual(oct(100), '0144')
self.assertEqual(oct(100L), '0144L') self.assertEqual(oct(100L), '0144L')
self.assert_(oct(-100) in ('037777777634', '01777777777777777777634')) self.assertEqual(oct(-100), '-0144')
self.assertEqual(oct(-100L), '-0144L') self.assertEqual(oct(-100L), '-0144L')
self.assertRaises(TypeError, oct, ()) self.assertRaises(TypeError, oct, ())
......
...@@ -119,15 +119,18 @@ if 1: ...@@ -119,15 +119,18 @@ if 1:
def test_unary_minus(self): def test_unary_minus(self):
# Verify treatment of unary minus on negative numbers SF bug #660455 # Verify treatment of unary minus on negative numbers SF bug #660455
warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning) if sys.maxint == 2147483647:
warnings.filterwarnings("ignore", "hex.* of negative int", FutureWarning) # 32-bit machine
# XXX Of course the following test will have to be changed in Python 2.4 all_one_bits = '0xffffffff'
# This test is in a <string> so the filterwarnings() can affect it self.assertEqual(eval(all_one_bits), 4294967295L)
all_one_bits = '0xffffffff' self.assertEqual(eval("-" + all_one_bits), -4294967295L)
if sys.maxint != 2147483647: elif sys.maxint == 9223372036854775807:
# 64-bit machine
all_one_bits = '0xffffffffffffffff' all_one_bits = '0xffffffffffffffff'
self.assertEqual(eval(all_one_bits), -1) self.assertEqual(eval(all_one_bits), 18446744073709551615L)
self.assertEqual(eval("-" + all_one_bits), 1) self.assertEqual(eval("-" + all_one_bits), -18446744073709551615L)
else:
self.fail("How many bits *does* this machine have???")
def test_sequence_unpacking_error(self): def test_sequence_unpacking_error(self):
# Verify sequence packing/unpacking with "or". SF bug #757818 # Verify sequence packing/unpacking with "or". SF bug #757818
......
...@@ -183,12 +183,12 @@ testboth("%#X", 0, "0X0") ...@@ -183,12 +183,12 @@ testboth("%#X", 0, "0X0")
testboth("%#X", 0L, "0X0") testboth("%#X", 0L, "0X0")
testboth("%x", 0x42, "42") testboth("%x", 0x42, "42")
# testboth("%x", -0x42, "ffffffbe") # specific to 32-bit boxes; see below testboth("%x", -0x42, "-42")
testboth("%x", 0x42L, "42") testboth("%x", 0x42L, "42")
testboth("%x", -0x42L, "-42") testboth("%x", -0x42L, "-42")
testboth("%o", 042, "42") testboth("%o", 042, "42")
# testboth("%o", -042, "37777777736") # specific to 32-bit boxes; see below testboth("%o", -042, "-42")
testboth("%o", 042L, "42") testboth("%o", 042L, "42")
testboth("%o", -042L, "-42") testboth("%o", -042L, "-42")
...@@ -238,6 +238,3 @@ if sys.maxint == 2**32-1: ...@@ -238,6 +238,3 @@ if sys.maxint == 2**32-1:
pass pass
else: else:
raise TestFailed, '"%*d"%(sys.maxint, -127) should fail' raise TestFailed, '"%*d"%(sys.maxint, -127) should fail'
# (different things go wrong on a 64 bit box...)
testboth("%x", -0x42, "ffffffbe")
testboth("%o", -042, "37777777736")
...@@ -39,20 +39,20 @@ except ImportError: ...@@ -39,20 +39,20 @@ except ImportError:
if maxint == 2147483647: if maxint == 2147483647:
# The following test will start to fail in Python 2.4; # The following test will start to fail in Python 2.4;
# change the 020000000000 to -020000000000 # change the 020000000000 to -020000000000
if -2147483647-1 != 020000000000: raise TestFailed, 'max negative int' if -2147483647-1 != -020000000000: raise TestFailed, 'max negative int'
# XXX -2147483648 # XXX -2147483648
if 037777777777 != -1: raise TestFailed, 'oct -1' if 037777777777 < 0: raise TestFailed, 'large oct'
if 0xffffffff != -1: raise TestFailed, 'hex -1' if 0xffffffff < 0: raise TestFailed, 'large hex'
for s in '2147483648', '040000000000', '0x100000000': for s in '2147483648', '040000000000', '0x100000000':
try: try:
x = eval(s) x = eval(s)
except OverflowError: except OverflowError:
print "OverflowError on huge integer literal " + `s` print "OverflowError on huge integer literal " + `s`
elif eval('maxint == 9223372036854775807'): elif eval('maxint == 9223372036854775807'):
if eval('-9223372036854775807-1 != 01000000000000000000000'): if eval('-9223372036854775807-1 != -01000000000000000000000'):
raise TestFailed, 'max negative int' raise TestFailed, 'max negative int'
if eval('01777777777777777777777') != -1: raise TestFailed, 'oct -1' if eval('01777777777777777777777') < 0: raise TestFailed, 'large oct'
if eval('0xffffffffffffffff') != -1: raise TestFailed, 'hex -1' if eval('0xffffffffffffffff') < 0: raise TestFailed, 'large hex'
for s in '9223372036854775808', '02000000000000000000000', \ for s in '9223372036854775808', '02000000000000000000000', \
'0x10000000000000000': '0x10000000000000000':
try: try:
......
"""Test correct treatment of hex/oct constants. """Test correct treatment of hex/oct constants.
This is complex because of changes due to PEP 237. This is complex because of changes due to PEP 237.
Some of these tests will have to change in Python 2.4!
""" """
import sys import sys
...@@ -41,31 +39,28 @@ class TextHexOct(unittest.TestCase): ...@@ -41,31 +39,28 @@ class TextHexOct(unittest.TestCase):
self.assertEqual(-0x7fffffffffffffff, -9223372036854775807) self.assertEqual(-0x7fffffffffffffff, -9223372036854775807)
def test_hex_unsigned(self): def test_hex_unsigned(self):
# This test is in a <string> so we can ignore the warnings
exec """if 1:
if platform_long_is_32_bits: if platform_long_is_32_bits:
# Positive-looking constants with negavive values # Positive constants
self.assertEqual(0x80000000, -2147483648L) self.assertEqual(0x80000000, 2147483648L)
self.assertEqual(0xffffffff, -1) self.assertEqual(0xffffffff, 4294967295L)
# Ditto with a minus sign and parentheses # Ditto with a minus sign and parentheses
self.assertEqual(-(0x80000000), 2147483648L) self.assertEqual(-(0x80000000), -2147483648L)
self.assertEqual(-(0xffffffff), 1) self.assertEqual(-(0xffffffff), -4294967295L)
# Ditto with a minus sign and NO parentheses # Ditto with a minus sign and NO parentheses
# This failed in Python 2.2 through 2.2.2 and in 2.3a1 # This failed in Python 2.2 through 2.2.2 and in 2.3a1
self.assertEqual(-0x80000000, 2147483648L) self.assertEqual(-0x80000000, -2147483648L)
self.assertEqual(-0xffffffff, 1) self.assertEqual(-0xffffffff, -4294967295L)
else: else:
# Positive-looking constants with negavive values # Positive constants
self.assertEqual(0x8000000000000000, -9223372036854775808L) self.assertEqual(0x8000000000000000, 9223372036854775808L)
self.assertEqual(0xffffffffffffffff, -1) self.assertEqual(0xffffffffffffffff, 18446744073709551615L)
# Ditto with a minus sign and parentheses # Ditto with a minus sign and parentheses
self.assertEqual(-(0x8000000000000000), 9223372036854775808L) self.assertEqual(-(0x8000000000000000), -9223372036854775808L)
self.assertEqual(-(0xffffffffffffffff), 1) self.assertEqual(-(0xffffffffffffffff), -18446744073709551615L)
# Ditto with a minus sign and NO parentheses # Ditto with a minus sign and NO parentheses
# This failed in Python 2.2 through 2.2.2 and in 2.3a1 # This failed in Python 2.2 through 2.2.2 and in 2.3a1
self.assertEqual(-0x8000000000000000, 9223372036854775808L) self.assertEqual(-0x8000000000000000, -9223372036854775808L)
self.assertEqual(-0xffffffffffffffff, 1) self.assertEqual(-0xffffffffffffffff, -18446744073709551615L)
\n"""
def test_oct_baseline(self): def test_oct_baseline(self):
# Baseline tests # Baseline tests
...@@ -91,31 +86,28 @@ class TextHexOct(unittest.TestCase): ...@@ -91,31 +86,28 @@ class TextHexOct(unittest.TestCase):
self.assertEqual(-0777777777777777777777, -9223372036854775807) self.assertEqual(-0777777777777777777777, -9223372036854775807)
def test_oct_unsigned(self): def test_oct_unsigned(self):
# This test is in a <string> so we can ignore the warnings
exec """if 1:
if platform_long_is_32_bits: if platform_long_is_32_bits:
# Positive-looking constants with negavive values # Positive constants
self.assertEqual(020000000000, -2147483648L) self.assertEqual(020000000000, 2147483648L)
self.assertEqual(037777777777, -1) self.assertEqual(037777777777, 4294967295L)
# Ditto with a minus sign and parentheses # Ditto with a minus sign and parentheses
self.assertEqual(-(020000000000), 2147483648L) self.assertEqual(-(020000000000), -2147483648L)
self.assertEqual(-(037777777777), 1) self.assertEqual(-(037777777777), -4294967295L)
# Ditto with a minus sign and NO parentheses # Ditto with a minus sign and NO parentheses
# This failed in Python 2.2 through 2.2.2 and in 2.3a1 # This failed in Python 2.2 through 2.2.2 and in 2.3a1
self.assertEqual(-020000000000, 2147483648L) self.assertEqual(-020000000000, -2147483648L)
self.assertEqual(-037777777777, 1) self.assertEqual(-037777777777, -4294967295L)
else: else:
# Positive-looking constants with negavive values # Positive constants
self.assertEqual(01000000000000000000000, -9223372036854775808L) self.assertEqual(01000000000000000000000, 9223372036854775808L)
self.assertEqual(01777777777777777777777, -1) self.assertEqual(01777777777777777777777, 18446744073709551615L)
# Ditto with a minus sign and parentheses # Ditto with a minus sign and parentheses
self.assertEqual(-(01000000000000000000000), 9223372036854775808L) self.assertEqual(-(01000000000000000000000), -9223372036854775808L)
self.assertEqual(-(01777777777777777777777), 1) self.assertEqual(-(01777777777777777777777), -18446744073709551615L)
# Ditto with a minus sign and NO parentheses # Ditto with a minus sign and NO parentheses
# This failed in Python 2.2 through 2.2.2 and in 2.3a1 # This failed in Python 2.2 through 2.2.2 and in 2.3a1
self.assertEqual(-01000000000000000000000, 9223372036854775808L) self.assertEqual(-01000000000000000000000, -9223372036854775808L)
self.assertEqual(-01777777777777777777777, 1) self.assertEqual(-01777777777777777777777, -18446744073709551615L)
\n"""
def test_main(): def test_main():
test_support.run_unittest(TextHexOct) test_support.run_unittest(TextHexOct)
......
...@@ -12,6 +12,15 @@ What's New in Python 2.4 alpha 1? ...@@ -12,6 +12,15 @@ What's New in Python 2.4 alpha 1?
Core and builtins Core and builtins
----------------- -----------------
- Removed FutureWarnings related to hex/oct literals and conversions
and left shifts. (Thanks to Kalle Svensson for SF patch 849227.)
This addresses most of the remaining semantic changes promised by
PEP 237, except for repr() of a long, which still shows the trailing
'L'. The PEP appears to promise warnings for operations that
changed semantics compared to Python 2.3, but this is not
implemented; we've suffered through enough warnings related to
hex/oct literals and I think it's best to be silent now.
- For str and unicode objects, the ljust(), center(), and rjust() - For str and unicode objects, the ljust(), center(), and rjust()
methods now accept an optional argument specifying a fill methods now accept an optional argument specifying a fill
character other than a space. character other than a space.
......
...@@ -278,7 +278,6 @@ PyInt_FromString(char *s, char **pend, int base) ...@@ -278,7 +278,6 @@ PyInt_FromString(char *s, char **pend, int base)
char *end; char *end;
long x; long x;
char buffer[256]; /* For errors */ char buffer[256]; /* For errors */
int warn = 0;
if ((base != 0 && base < 2) || base > 36) { if ((base != 0 && base < 2) || base > 36) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
...@@ -292,7 +291,7 @@ PyInt_FromString(char *s, char **pend, int base) ...@@ -292,7 +291,7 @@ PyInt_FromString(char *s, char **pend, int base)
if (base == 0 && s[0] == '0') { if (base == 0 && s[0] == '0') {
x = (long) PyOS_strtoul(s, &end, base); x = (long) PyOS_strtoul(s, &end, base);
if (x < 0) if (x < 0)
warn = 1; return PyLong_FromString(s, pend, base);
} }
else else
x = PyOS_strtol(s, &end, base); x = PyOS_strtol(s, &end, base);
...@@ -312,11 +311,6 @@ PyInt_FromString(char *s, char **pend, int base) ...@@ -312,11 +311,6 @@ PyInt_FromString(char *s, char **pend, int base)
return NULL; return NULL;
return PyLong_FromString(s, pend, base); return PyLong_FromString(s, pend, base);
} }
if (warn) {
if (PyErr_Warn(PyExc_FutureWarning,
"int('0...', 0): sign will change in Python 2.4") < 0)
return NULL;
}
if (pend) if (pend)
*pend = end; *pend = end;
return PyInt_FromLong(x); return PyInt_FromLong(x);
...@@ -766,18 +760,13 @@ int_lshift(PyIntObject *v, PyIntObject *w) ...@@ -766,18 +760,13 @@ int_lshift(PyIntObject *v, PyIntObject *w)
if (a == 0 || b == 0) if (a == 0 || b == 0)
return int_pos(v); return int_pos(v);
if (b >= LONG_BIT) { if (b >= LONG_BIT) {
if (PyErr_Warn(PyExc_FutureWarning, return PyNumber_Lshift(PyLong_FromLong(PyInt_AS_LONG(v)),
"x<<y losing bits or changing sign " PyLong_FromLong(PyInt_AS_LONG(w)));
"will return a long in Python 2.4 and up") < 0)
return NULL;
return PyInt_FromLong(0L);
} }
c = a << b; c = a << b;
if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) { if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
if (PyErr_Warn(PyExc_FutureWarning, return PyNumber_Lshift(PyLong_FromLong(PyInt_AS_LONG(v)),
"x<<y losing bits or changing sign " PyLong_FromLong(PyInt_AS_LONG(w)));
"will return a long in Python 2.4 and up") < 0)
return NULL;
} }
return PyInt_FromLong(c); return PyInt_FromLong(c);
} }
...@@ -868,13 +857,9 @@ int_oct(PyIntObject *v) ...@@ -868,13 +857,9 @@ int_oct(PyIntObject *v)
{ {
char buf[100]; char buf[100];
long x = v -> ob_ival; long x = v -> ob_ival;
if (x < 0) { if (x < 0)
if (PyErr_Warn(PyExc_FutureWarning, PyOS_snprintf(buf, sizeof(buf), "-0%lo", -x);
"hex()/oct() of negative int will return " else if (x == 0)
"a signed string in Python 2.4 and up") < 0)
return NULL;
}
if (x == 0)
strcpy(buf, "0"); strcpy(buf, "0");
else else
PyOS_snprintf(buf, sizeof(buf), "0%lo", x); PyOS_snprintf(buf, sizeof(buf), "0%lo", x);
...@@ -886,13 +871,10 @@ int_hex(PyIntObject *v) ...@@ -886,13 +871,10 @@ int_hex(PyIntObject *v)
{ {
char buf[100]; char buf[100];
long x = v -> ob_ival; long x = v -> ob_ival;
if (x < 0) { if (x < 0)
if (PyErr_Warn(PyExc_FutureWarning, PyOS_snprintf(buf, sizeof(buf), "-0x%lx", -x);
"hex()/oct() of negative int will return " else
"a signed string in Python 2.4 and up") < 0) PyOS_snprintf(buf, sizeof(buf), "0x%lx", x);
return NULL;
}
PyOS_snprintf(buf, sizeof(buf), "0x%lx", x);
return PyString_FromString(buf); return PyString_FromString(buf);
} }
......
...@@ -3565,6 +3565,7 @@ formatint(char *buf, size_t buflen, int flags, ...@@ -3565,6 +3565,7 @@ formatint(char *buf, size_t buflen, int flags,
worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine) worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine)
+ 1 + 1 = 24 */ + 1 + 1 = 24 */
char fmt[64]; /* plenty big enough! */ char fmt[64]; /* plenty big enough! */
char *sign;
long x; long x;
x = PyInt_AsLong(v); x = PyInt_AsLong(v);
...@@ -3572,12 +3573,13 @@ formatint(char *buf, size_t buflen, int flags, ...@@ -3572,12 +3573,13 @@ formatint(char *buf, size_t buflen, int flags,
PyErr_SetString(PyExc_TypeError, "int argument required"); PyErr_SetString(PyExc_TypeError, "int argument required");
return -1; return -1;
} }
if (x < 0 && type != 'd' && type != 'i') { if (x < 0 && type == 'u') {
if (PyErr_Warn(PyExc_FutureWarning, type = 'd';
"%u/%o/%x/%X of negative int will return "
"a signed string in Python 2.4 and up") < 0)
return -1;
} }
if (x < 0 && (type == 'x' || type == 'X' || type == 'o'))
sign = "-";
else
sign = "";
if (prec < 0) if (prec < 0)
prec = 1; prec = 1;
...@@ -3603,24 +3605,27 @@ formatint(char *buf, size_t buflen, int flags, ...@@ -3603,24 +3605,27 @@ formatint(char *buf, size_t buflen, int flags,
* Note that this is the same approach as used in * Note that this is the same approach as used in
* formatint() in unicodeobject.c * formatint() in unicodeobject.c
*/ */
PyOS_snprintf(fmt, sizeof(fmt), "0%c%%.%dl%c", PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c",
type, prec, type); sign, type, prec, type);
} }
else { else {
PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%dl%c", PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c",
(flags&F_ALT) ? "#" : "", sign, (flags&F_ALT) ? "#" : "",
prec, type); prec, type);
} }
/* buf = '+'/'-'/'0'/'0x' + '[0-9]'*max(prec, len(x in octal)) /* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal))
* worst case buf = '0x' + [0-9]*prec, where prec >= 11 * worst case buf = '-0x' + [0-9]*prec, where prec >= 11
*/ */
if (buflen <= 13 || buflen <= (size_t)2 + (size_t)prec) { if (buflen <= 14 || buflen <= (size_t)3 + (size_t)prec) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"formatted integer is too long (precision too large?)"); "formatted integer is too long (precision too large?)");
return -1; return -1;
} }
PyOS_snprintf(buf, buflen, fmt, x); if (sign[0])
PyOS_snprintf(buf, buflen, fmt, -x);
else
PyOS_snprintf(buf, buflen, fmt, x);
return strlen(buf); return strlen(buf);
} }
...@@ -3907,8 +3912,6 @@ PyString_Format(PyObject *format, PyObject *args) ...@@ -3907,8 +3912,6 @@ PyString_Format(PyObject *format, PyObject *args)
prec, c, &pbuf, &len); prec, c, &pbuf, &len);
if (!temp) if (!temp)
goto error; goto error;
/* unbounded ints can always produce
a sign character! */
sign = 1; sign = 1;
} }
else { else {
...@@ -3918,8 +3921,7 @@ PyString_Format(PyObject *format, PyObject *args) ...@@ -3918,8 +3921,7 @@ PyString_Format(PyObject *format, PyObject *args)
flags, prec, c, v); flags, prec, c, v);
if (len < 0) if (len < 0)
goto error; goto error;
/* only d conversion is signed */ sign = 1;
sign = c == 'd';
} }
if (flags & F_ZERO) if (flags & F_ZERO)
fill = '0'; fill = '0';
......
...@@ -6177,24 +6177,26 @@ formatint(Py_UNICODE *buf, ...@@ -6177,24 +6177,26 @@ formatint(Py_UNICODE *buf,
* = 24 * = 24
*/ */
char fmt[64]; /* plenty big enough! */ char fmt[64]; /* plenty big enough! */
char *sign;
long x; long x;
x = PyInt_AsLong(v); x = PyInt_AsLong(v);
if (x == -1 && PyErr_Occurred()) if (x == -1 && PyErr_Occurred())
return -1; return -1;
if (x < 0 && type != 'd' && type != 'i') { if (x < 0 && type == 'u') {
if (PyErr_Warn(PyExc_FutureWarning, type = 'd';
"%u/%o/%x/%X of negative int will return "
"a signed string in Python 2.4 and up") < 0)
return -1;
} }
if (x < 0 && (type == 'x' || type == 'X' || type == 'o'))
sign = "-";
else
sign = "";
if (prec < 0) if (prec < 0)
prec = 1; prec = 1;
/* buf = '+'/'-'/'0'/'0x' + '[0-9]'*max(prec,len(x in octal)) /* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal))
* worst case buf = '0x' + [0-9]*prec, where prec >= 11 * worst case buf = '-0x' + [0-9]*prec, where prec >= 11
*/ */
if (buflen <= 13 || buflen <= (size_t)2 + (size_t)prec) { if (buflen <= 14 || buflen <= (size_t)3 + (size_t)prec) {
PyErr_SetString(PyExc_OverflowError, PyErr_SetString(PyExc_OverflowError,
"formatted integer is too long (precision too large?)"); "formatted integer is too long (precision too large?)");
return -1; return -1;
...@@ -6222,15 +6224,18 @@ formatint(Py_UNICODE *buf, ...@@ -6222,15 +6224,18 @@ formatint(Py_UNICODE *buf,
* Note that this is the same approach as used in * Note that this is the same approach as used in
* formatint() in stringobject.c * formatint() in stringobject.c
*/ */
PyOS_snprintf(fmt, sizeof(fmt), "0%c%%.%dl%c", PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c",
type, prec, type); sign, type, prec, type);
} }
else { else {
PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%dl%c", PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c",
(flags&F_ALT) ? "#" : "", sign, (flags&F_ALT) ? "#" : "",
prec, type); prec, type);
} }
return usprintf(buf, fmt, x); if (sign[0])
return usprintf(buf, fmt, -x);
else
return usprintf(buf, fmt, x);
} }
static int static int
...@@ -6566,8 +6571,6 @@ PyObject *PyUnicode_Format(PyObject *format, ...@@ -6566,8 +6571,6 @@ PyObject *PyUnicode_Format(PyObject *format,
goto onError; goto onError;
pbuf = PyUnicode_AS_UNICODE(temp); pbuf = PyUnicode_AS_UNICODE(temp);
len = PyUnicode_GET_SIZE(temp); len = PyUnicode_GET_SIZE(temp);
/* unbounded ints can always produce
a sign character! */
sign = 1; sign = 1;
} }
else { else {
...@@ -6576,8 +6579,7 @@ PyObject *PyUnicode_Format(PyObject *format, ...@@ -6576,8 +6579,7 @@ PyObject *PyUnicode_Format(PyObject *format,
flags, prec, c, v); flags, prec, c, v);
if (len < 0) if (len < 0)
goto onError; goto onError;
/* only d conversion is signed */ sign = 1;
sign = c == 'd';
} }
if (flags & F_ZERO) if (flags & F_ZERO)
fill = '0'; fill = '0';
......
...@@ -1258,19 +1258,7 @@ parsenumber(struct compiling *c, char *s) ...@@ -1258,19 +1258,7 @@ parsenumber(struct compiling *c, char *s)
if (s[0] == '0') { if (s[0] == '0') {
x = (long) PyOS_strtoul(s, &end, 0); x = (long) PyOS_strtoul(s, &end, 0);
if (x < 0 && errno == 0) { if (x < 0 && errno == 0) {
if (PyErr_WarnExplicit( return PyLong_FromString(s, (char **)0, 0);
PyExc_FutureWarning,
"hex/oct constants > sys.maxint "
"will return positive values "
"in Python 2.4 and up",
/* XXX: Give WarnExplicit
a const char* argument. */
(char*)c->c_filename,
c->c_lineno,
NULL,
NULL) < 0)
return NULL;
errno = 0; /* Might be changed by PyErr_Warn() */
} }
} }
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment