diff options
-rw-r--r-- | Doc/ref/ref2.tex | 24 | ||||
-rw-r--r-- | Lib/test/test_builtin.py | 5 | ||||
-rw-r--r-- | Lib/test/test_compile.py | 19 | ||||
-rw-r--r-- | Lib/test/test_format.py | 7 | ||||
-rw-r--r-- | Lib/test/test_grammar.py | 12 | ||||
-rw-r--r-- | Lib/test/test_hexoct.py | 64 | ||||
-rw-r--r-- | Misc/NEWS | 9 | ||||
-rw-r--r-- | Objects/intobject.c | 42 | ||||
-rw-r--r-- | Objects/stringobject.c | 36 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 36 | ||||
-rw-r--r-- | Python/compile.c | 14 |
11 files changed, 120 insertions, 148 deletions
diff --git a/Doc/ref/ref2.tex b/Doc/ref/ref2.tex index 76c5cc5..33bf053 100644 --- a/Doc/ref/ref2.tex +++ b/Doc/ref/ref2.tex @@ -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 digit \character{1}. -Plain integer decimal literals that are above the largest representable -plain integer (e.g., 2147483647 when using 32-bit arithmetic) are accepted -as if they were long integers instead. Octal and hexadecimal literals -behave similarly, but when in the range just above the largest representable -plain integer but below the largest unsigned 32-bit number (on a machine -using 32-bit arithmetic), 4294967296, they are taken as the negative plain -integer obtained by subtracting 4294967296 from their unsigned value. There -is no limit for long integer literals apart from what can be stored in -available memory. For example, 0xdeadbeef is taken, on a 32-bit machine, -as the value -559038737, while 0xdeadbeeffeed is taken as the value -244837814107885L. +Plain integer literals that are above the largest representable plain +integer (e.g., 2147483647 when using 32-bit arithmetic) are accepted +as if they were long integers instead.\footnote{In versions of Python +prior to 2.4, octal and hexadecimal literals in the range just above +the largest representable plain integer but below the largest unsigned +32-bit number (on a machine using 32-bit arithmetic), 4294967296, were +taken as the negative plain integer obtained by subtracting 4294967296 +from their unsigned value.} There is no limit for long integer +literals apart from what can be stored in available memory. Some examples of plain integer literals (first row) and long integer literals (second and third rows): \begin{verbatim} -7 2147483647 0177 0x80000000 +7 2147483647 0177 3L 79228162514264337593543950336L 0377L 0x100000000L - 79228162514264337593543950336 0xdeadbeeffeed + 79228162514264337593543950336 0xdeadbeef \end{verbatim} diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index d47a9da..1953f29 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -437,8 +437,7 @@ class BuiltinTest(unittest.TestCase): def test_hex(self): self.assertEqual(hex(16), '0x10') self.assertEqual(hex(16L), '0x10L') - self.assertEqual(len(hex(-1)), len(hex(sys.maxint))) - self.assert_(hex(-16) in ('0xfffffff0', '0xfffffffffffffff0')) + self.assertEqual(hex(-16), '-0x10') self.assertEqual(hex(-16L), '-0x10L') self.assertRaises(TypeError, hex, {}) @@ -757,7 +756,7 @@ class BuiltinTest(unittest.TestCase): def test_oct(self): self.assertEqual(oct(100), '0144') self.assertEqual(oct(100L), '0144L') - self.assert_(oct(-100) in ('037777777634', '01777777777777777777634')) + self.assertEqual(oct(-100), '-0144') self.assertEqual(oct(-100L), '-0144L') self.assertRaises(TypeError, oct, ()) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 4d4ba4f..e2b1c95 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -119,15 +119,18 @@ if 1: def test_unary_minus(self): # Verify treatment of unary minus on negative numbers SF bug #660455 - warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning) - warnings.filterwarnings("ignore", "hex.* of negative int", FutureWarning) - # XXX Of course the following test will have to be changed in Python 2.4 - # This test is in a <string> so the filterwarnings() can affect it - all_one_bits = '0xffffffff' - if sys.maxint != 2147483647: + if sys.maxint == 2147483647: + # 32-bit machine + all_one_bits = '0xffffffff' + self.assertEqual(eval(all_one_bits), 4294967295L) + self.assertEqual(eval("-" + all_one_bits), -4294967295L) + elif sys.maxint == 9223372036854775807: + # 64-bit machine all_one_bits = '0xffffffffffffffff' - self.assertEqual(eval(all_one_bits), -1) - self.assertEqual(eval("-" + all_one_bits), 1) + self.assertEqual(eval(all_one_bits), 18446744073709551615L) + self.assertEqual(eval("-" + all_one_bits), -18446744073709551615L) + else: + self.fail("How many bits *does* this machine have???") def test_sequence_unpacking_error(self): # Verify sequence packing/unpacking with "or". SF bug #757818 diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index f791874..0a51231 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -183,12 +183,12 @@ testboth("%#X", 0, "0X0") testboth("%#X", 0L, "0X0") 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("%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") @@ -238,6 +238,3 @@ if sys.maxint == 2**32-1: pass else: 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") diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index c57bbed..6666c13 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -39,20 +39,20 @@ except ImportError: if maxint == 2147483647: # The following test will start to fail in Python 2.4; # 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 - if 037777777777 != -1: raise TestFailed, 'oct -1' - if 0xffffffff != -1: raise TestFailed, 'hex -1' + if 037777777777 < 0: raise TestFailed, 'large oct' + if 0xffffffff < 0: raise TestFailed, 'large hex' for s in '2147483648', '040000000000', '0x100000000': try: x = eval(s) except OverflowError: print "OverflowError on huge integer literal " + `s` elif eval('maxint == 9223372036854775807'): - if eval('-9223372036854775807-1 != 01000000000000000000000'): + if eval('-9223372036854775807-1 != -01000000000000000000000'): raise TestFailed, 'max negative int' - if eval('01777777777777777777777') != -1: raise TestFailed, 'oct -1' - if eval('0xffffffffffffffff') != -1: raise TestFailed, 'hex -1' + if eval('01777777777777777777777') < 0: raise TestFailed, 'large oct' + if eval('0xffffffffffffffff') < 0: raise TestFailed, 'large hex' for s in '9223372036854775808', '02000000000000000000000', \ '0x10000000000000000': try: diff --git a/Lib/test/test_hexoct.py b/Lib/test/test_hexoct.py index 8a57906..f71dbe0 100644 --- a/Lib/test/test_hexoct.py +++ b/Lib/test/test_hexoct.py @@ -1,8 +1,6 @@ """Test correct treatment of hex/oct constants. This is complex because of changes due to PEP 237. - -Some of these tests will have to change in Python 2.4! """ import sys @@ -41,31 +39,28 @@ class TextHexOct(unittest.TestCase): self.assertEqual(-0x7fffffffffffffff, -9223372036854775807) 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: - # Positive-looking constants with negavive values - self.assertEqual(0x80000000, -2147483648L) - self.assertEqual(0xffffffff, -1) + # Positive constants + self.assertEqual(0x80000000, 2147483648L) + self.assertEqual(0xffffffff, 4294967295L) # Ditto with a minus sign and parentheses - self.assertEqual(-(0x80000000), 2147483648L) - self.assertEqual(-(0xffffffff), 1) + self.assertEqual(-(0x80000000), -2147483648L) + self.assertEqual(-(0xffffffff), -4294967295L) # Ditto with a minus sign and NO parentheses # This failed in Python 2.2 through 2.2.2 and in 2.3a1 - self.assertEqual(-0x80000000, 2147483648L) - self.assertEqual(-0xffffffff, 1) + self.assertEqual(-0x80000000, -2147483648L) + self.assertEqual(-0xffffffff, -4294967295L) else: - # Positive-looking constants with negavive values - self.assertEqual(0x8000000000000000, -9223372036854775808L) - self.assertEqual(0xffffffffffffffff, -1) + # Positive constants + self.assertEqual(0x8000000000000000, 9223372036854775808L) + self.assertEqual(0xffffffffffffffff, 18446744073709551615L) # Ditto with a minus sign and parentheses - self.assertEqual(-(0x8000000000000000), 9223372036854775808L) - self.assertEqual(-(0xffffffffffffffff), 1) + self.assertEqual(-(0x8000000000000000), -9223372036854775808L) + self.assertEqual(-(0xffffffffffffffff), -18446744073709551615L) # Ditto with a minus sign and NO parentheses # This failed in Python 2.2 through 2.2.2 and in 2.3a1 - self.assertEqual(-0x8000000000000000, 9223372036854775808L) - self.assertEqual(-0xffffffffffffffff, 1) - \n""" + self.assertEqual(-0x8000000000000000, -9223372036854775808L) + self.assertEqual(-0xffffffffffffffff, -18446744073709551615L) def test_oct_baseline(self): # Baseline tests @@ -91,31 +86,28 @@ class TextHexOct(unittest.TestCase): self.assertEqual(-0777777777777777777777, -9223372036854775807) 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: - # Positive-looking constants with negavive values - self.assertEqual(020000000000, -2147483648L) - self.assertEqual(037777777777, -1) + # Positive constants + self.assertEqual(020000000000, 2147483648L) + self.assertEqual(037777777777, 4294967295L) # Ditto with a minus sign and parentheses - self.assertEqual(-(020000000000), 2147483648L) - self.assertEqual(-(037777777777), 1) + self.assertEqual(-(020000000000), -2147483648L) + self.assertEqual(-(037777777777), -4294967295L) # Ditto with a minus sign and NO parentheses # This failed in Python 2.2 through 2.2.2 and in 2.3a1 - self.assertEqual(-020000000000, 2147483648L) - self.assertEqual(-037777777777, 1) + self.assertEqual(-020000000000, -2147483648L) + self.assertEqual(-037777777777, -4294967295L) else: - # Positive-looking constants with negavive values - self.assertEqual(01000000000000000000000, -9223372036854775808L) - self.assertEqual(01777777777777777777777, -1) + # Positive constants + self.assertEqual(01000000000000000000000, 9223372036854775808L) + self.assertEqual(01777777777777777777777, 18446744073709551615L) # Ditto with a minus sign and parentheses - self.assertEqual(-(01000000000000000000000), 9223372036854775808L) - self.assertEqual(-(01777777777777777777777), 1) + self.assertEqual(-(01000000000000000000000), -9223372036854775808L) + self.assertEqual(-(01777777777777777777777), -18446744073709551615L) # Ditto with a minus sign and NO parentheses # This failed in Python 2.2 through 2.2.2 and in 2.3a1 - self.assertEqual(-01000000000000000000000, 9223372036854775808L) - self.assertEqual(-01777777777777777777777, 1) - \n""" + self.assertEqual(-01000000000000000000000, -9223372036854775808L) + self.assertEqual(-01777777777777777777777, -18446744073709551615L) def test_main(): test_support.run_unittest(TextHexOct) @@ -12,6 +12,15 @@ What's New in Python 2.4 alpha 1? 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() methods now accept an optional argument specifying a fill character other than a space. diff --git a/Objects/intobject.c b/Objects/intobject.c index b97e2bc..47acbff 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -278,7 +278,6 @@ PyInt_FromString(char *s, char **pend, int base) char *end; long x; char buffer[256]; /* For errors */ - int warn = 0; if ((base != 0 && base < 2) || base > 36) { PyErr_SetString(PyExc_ValueError, @@ -292,7 +291,7 @@ PyInt_FromString(char *s, char **pend, int base) if (base == 0 && s[0] == '0') { x = (long) PyOS_strtoul(s, &end, base); if (x < 0) - warn = 1; + return PyLong_FromString(s, pend, base); } else x = PyOS_strtol(s, &end, base); @@ -312,11 +311,6 @@ PyInt_FromString(char *s, char **pend, int base) return NULL; 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) *pend = end; return PyInt_FromLong(x); @@ -766,18 +760,13 @@ int_lshift(PyIntObject *v, PyIntObject *w) if (a == 0 || b == 0) return int_pos(v); if (b >= LONG_BIT) { - if (PyErr_Warn(PyExc_FutureWarning, - "x<<y losing bits or changing sign " - "will return a long in Python 2.4 and up") < 0) - return NULL; - return PyInt_FromLong(0L); + return PyNumber_Lshift(PyLong_FromLong(PyInt_AS_LONG(v)), + PyLong_FromLong(PyInt_AS_LONG(w))); } c = a << b; if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) { - if (PyErr_Warn(PyExc_FutureWarning, - "x<<y losing bits or changing sign " - "will return a long in Python 2.4 and up") < 0) - return NULL; + return PyNumber_Lshift(PyLong_FromLong(PyInt_AS_LONG(v)), + PyLong_FromLong(PyInt_AS_LONG(w))); } return PyInt_FromLong(c); } @@ -868,13 +857,9 @@ int_oct(PyIntObject *v) { char buf[100]; long x = v -> ob_ival; - if (x < 0) { - if (PyErr_Warn(PyExc_FutureWarning, - "hex()/oct() of negative int will return " - "a signed string in Python 2.4 and up") < 0) - return NULL; - } - if (x == 0) + if (x < 0) + PyOS_snprintf(buf, sizeof(buf), "-0%lo", -x); + else if (x == 0) strcpy(buf, "0"); else PyOS_snprintf(buf, sizeof(buf), "0%lo", x); @@ -886,13 +871,10 @@ int_hex(PyIntObject *v) { char buf[100]; long x = v -> ob_ival; - if (x < 0) { - if (PyErr_Warn(PyExc_FutureWarning, - "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); + if (x < 0) + PyOS_snprintf(buf, sizeof(buf), "-0x%lx", -x); + else + PyOS_snprintf(buf, sizeof(buf), "0x%lx", x); return PyString_FromString(buf); } diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 739cc3e..d3351df 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -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) + 1 + 1 = 24 */ char fmt[64]; /* plenty big enough! */ + char *sign; long x; x = PyInt_AsLong(v); @@ -3572,12 +3573,13 @@ 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_FutureWarning, - "%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 == 'u') { + type = 'd'; } + if (x < 0 && (type == 'x' || type == 'X' || type == 'o')) + sign = "-"; + else + sign = ""; if (prec < 0) prec = 1; @@ -3603,24 +3605,27 @@ formatint(char *buf, size_t buflen, int flags, * Note that this is the same approach as used in * formatint() in unicodeobject.c */ - PyOS_snprintf(fmt, sizeof(fmt), "0%c%%.%dl%c", - type, prec, type); + PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c", + sign, type, prec, type); } else { - PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%dl%c", - (flags&F_ALT) ? "#" : "", + PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c", + sign, (flags&F_ALT) ? "#" : "", prec, type); } - /* buf = '+'/'-'/'0'/'0x' + '[0-9]'*max(prec, len(x in octal)) - * worst case buf = '0x' + [0-9]*prec, where prec >= 11 + /* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal)) + * 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, "formatted integer is too long (precision too large?)"); 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); } @@ -3907,8 +3912,6 @@ PyString_Format(PyObject *format, PyObject *args) prec, c, &pbuf, &len); if (!temp) goto error; - /* unbounded ints can always produce - a sign character! */ sign = 1; } else { @@ -3918,8 +3921,7 @@ PyString_Format(PyObject *format, PyObject *args) flags, prec, c, v); if (len < 0) goto error; - /* only d conversion is signed */ - sign = c == 'd'; + sign = 1; } if (flags & F_ZERO) fill = '0'; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index c950f8b..f87d749 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -6177,24 +6177,26 @@ formatint(Py_UNICODE *buf, * = 24 */ char fmt[64]; /* plenty big enough! */ + char *sign; long x; x = PyInt_AsLong(v); if (x == -1 && PyErr_Occurred()) return -1; - if (x < 0 && type != 'd' && type != 'i') { - if (PyErr_Warn(PyExc_FutureWarning, - "%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 == 'u') { + type = 'd'; } + if (x < 0 && (type == 'x' || type == 'X' || type == 'o')) + sign = "-"; + else + sign = ""; if (prec < 0) prec = 1; - /* buf = '+'/'-'/'0'/'0x' + '[0-9]'*max(prec,len(x in octal)) - * worst case buf = '0x' + [0-9]*prec, where prec >= 11 + /* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal)) + * 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, "formatted integer is too long (precision too large?)"); return -1; @@ -6222,15 +6224,18 @@ formatint(Py_UNICODE *buf, * Note that this is the same approach as used in * formatint() in stringobject.c */ - PyOS_snprintf(fmt, sizeof(fmt), "0%c%%.%dl%c", - type, prec, type); + PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c", + sign, type, prec, type); } else { - PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%dl%c", - (flags&F_ALT) ? "#" : "", + PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c", + sign, (flags&F_ALT) ? "#" : "", prec, type); } - return usprintf(buf, fmt, x); + if (sign[0]) + return usprintf(buf, fmt, -x); + else + return usprintf(buf, fmt, x); } static int @@ -6566,8 +6571,6 @@ PyObject *PyUnicode_Format(PyObject *format, goto onError; pbuf = PyUnicode_AS_UNICODE(temp); len = PyUnicode_GET_SIZE(temp); - /* unbounded ints can always produce - a sign character! */ sign = 1; } else { @@ -6576,8 +6579,7 @@ PyObject *PyUnicode_Format(PyObject *format, flags, prec, c, v); if (len < 0) goto onError; - /* only d conversion is signed */ - sign = c == 'd'; + sign = 1; } if (flags & F_ZERO) fill = '0'; diff --git a/Python/compile.c b/Python/compile.c index 4fb47ae..04d8b65 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1258,19 +1258,7 @@ parsenumber(struct compiling *c, char *s) if (s[0] == '0') { x = (long) PyOS_strtoul(s, &end, 0); if (x < 0 && errno == 0) { - if (PyErr_WarnExplicit( - 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() */ + return PyLong_FromString(s, (char **)0, 0); } } else |