summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wouters <thomas@python.org>2007-09-20 18:22:40 (GMT)
committerThomas Wouters <thomas@python.org>2007-09-20 18:22:40 (GMT)
commit8ce81f767a48e9e645c523137c7f83e49f79f986 (patch)
tree68e5fa3f61af5f75d43de717a0c997db77dd2910
parent7ce29ca41cd2c41ac7a5981d182f8db25c2af977 (diff)
downloadcpython-8ce81f767a48e9e645c523137c7f83e49f79f986.zip
cpython-8ce81f767a48e9e645c523137c7f83e49f79f986.tar.gz
cpython-8ce81f767a48e9e645c523137c7f83e49f79f986.tar.bz2
Merged revisions 58211-58220 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r58211 | facundo.batista | 2007-09-19 19:53:25 +0200 (Wed, 19 Sep 2007) | 4 lines Issue #1772851. Optimization of __hash__ to behave better for big big numbers. ........ r58216 | raymond.hettinger | 2007-09-20 05:03:43 +0200 (Thu, 20 Sep 2007) | 1 line Fit nits ........ r58217 | georg.brandl | 2007-09-20 10:44:59 +0200 (Thu, 20 Sep 2007) | 2 lines alternate -> alternative. ........ r58218 | georg.brandl | 2007-09-20 18:06:07 +0200 (Thu, 20 Sep 2007) | 2 lines Patch #1541463: optimize performance of cgi.FieldStorage operations. ........ r58219 | georg.brandl | 2007-09-20 18:45:27 +0200 (Thu, 20 Sep 2007) | 2 lines #1176: document that string methods don't take keyword args. ........ r58220 | thomas.wouters | 2007-09-20 19:35:10 +0200 (Thu, 20 Sep 2007) | 4 lines Try harder to stay within the 79-column limit. There's still two places that go (way) over, but those are harder to fix without suffering in readability. ........
-rw-r--r--Doc/library/collections.rst18
-rw-r--r--Doc/library/decimal.rst2
-rw-r--r--Doc/library/stdtypes.rst11
-rw-r--r--Doc/tutorial/inputoutput.rst2
-rwxr-xr-xLib/cgi.py12
-rw-r--r--Lib/decimal.py15
-rw-r--r--Lib/test/test_decimal.py32
-rw-r--r--Python/ceval.c86
8 files changed, 117 insertions, 61 deletions
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index 227f721..274ca15 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -395,8 +395,8 @@ Setting the :attr:`default_factory` to :class:`set` makes the
.. _named-tuple-factory:
-:func:`NamedTuple` factory function
------------------------------------
+:func:`NamedTuple` Factory Function for Tuples with Named Fields
+----------------------------------------------------------------
Named tuples assign meaning to each position in a tuple and allow for more readable,
self-documenting code. They can be used wherever regular tuples are used, and
@@ -411,12 +411,12 @@ they add the ability to access fields by name instead of position index.
method which lists the tuple contents in a ``name=value`` format.
The *fieldnames* are specified in a single string with each fieldname separated by
- a space and/or comma. Any valid Python identifier may be used for a field name.
+ a space and/or comma. Any valid Python identifier may be used for a fieldname.
- If *verbose* is true, the *NamedTuple* call will print the class definition.
+ If *verbose* is true, will print the class definition.
*NamedTuple* instances do not have per-instance dictionaries, so they are
- lightweight, requiring no more memory than regular tuples.
+ lightweight and require no more memory than regular tuples.
Example::
@@ -467,7 +467,9 @@ an additonal method and an informational read-only attribute.
.. method:: somenamedtuple.replace(field, value)
- Return a new instance of the named tuple replacing the named *field* with a new *value*::
+ Return a new instance of the named tuple replacing the named *field* with a new *value*:
+
+::
>>> p = Point(x=11, y=22)
>>> p.__replace__('x', 33)
@@ -480,7 +482,9 @@ an additonal method and an informational read-only attribute.
Return a tuple of strings listing the field names. This is useful for introspection,
for converting a named tuple instance to a dictionary, and for combining named tuple
- types to create new named tuple types::
+ types to create new named tuple types:
+
+::
>>> p.__fields__ # view the field names
('x', 'y')
diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst
index bbac0d4..ee4aeec 100644
--- a/Doc/library/decimal.rst
+++ b/Doc/library/decimal.rst
@@ -977,7 +977,7 @@ method. For example, ``C.exp(x)`` is equivalent to
The usual approach to working with decimals is to create :class:`Decimal`
instances and then apply arithmetic operations which take place within the
-current context for the active thread. An alternate approach is to use context
+current context for the active thread. An alternative approach is to use context
methods for calculating within a specific context. The methods are similar to
those for the :class:`Decimal` class and are only briefly recounted here.
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 75db75c..1a0bdf3 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -657,10 +657,13 @@ String Methods
.. index:: pair: string; methods
-String objects support the methods listed below. In addition, Python's strings
-support the sequence type methods described in the :ref:`typesseq` section. To
-output formatted strings, see the :ref:`string-formatting` section. Also, see
-the :mod:`re` module for string functions based on regular expressions.
+String objects support the methods listed below. Note that none of these
+methods take keyword arguments.
+
+In addition, Python's strings support the sequence type methods described in
+the :ref:`typesseq` section. To output formatted strings, see the
+:ref:`string-formatting` section. Also, see the :mod:`re` module for string
+functions based on regular expressions.
.. method:: str.capitalize()
diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst
index 54f4403..2f4cdd3 100644
--- a/Doc/tutorial/inputoutput.rst
+++ b/Doc/tutorial/inputoutput.rst
@@ -252,7 +252,7 @@ having to load the entire file in memory. Only complete lines will be returned.
>>> f.readlines()
['This is the first line of the file.\n', 'Second line of the file\n']
-An alternate approach to reading lines is to loop over the file object. This is
+An alternative approach to reading lines is to loop over the file object. This is
memory efficient, fast, and leads to simpler code::
>>> for line in f:
diff --git a/Lib/cgi.py b/Lib/cgi.py
index 7b457cc..cb92cfc 100755
--- a/Lib/cgi.py
+++ b/Lib/cgi.py
@@ -604,23 +604,21 @@ class FieldStorage:
"""Dictionary style keys() method."""
if self.list is None:
raise TypeError("not indexable")
- keys = []
- for item in self.list:
- if item.name not in keys: keys.append(item.name)
- return keys
+ return list(set(item.name for item in self.list))
def __contains__(self, key):
"""Dictionary style __contains__ method."""
if self.list is None:
raise TypeError("not indexable")
- for item in self.list:
- if item.name == key: return True
- return False
+ return any(item.name == key for item in self.list)
def __len__(self):
"""Dictionary style len(x) support."""
return len(self.keys())
+ def __nonzero__(self):
+ return bool(self.list)
+
def read_urlencoded(self):
"""Internal: read data in query string format."""
qs = self.fp.read(self.length)
diff --git a/Lib/decimal.py b/Lib/decimal.py
index d7bd127..ffe6e9e 100644
--- a/Lib/decimal.py
+++ b/Lib/decimal.py
@@ -786,10 +786,17 @@ class Decimal(object):
if self._isnan():
raise TypeError('Cannot hash a NaN value.')
return hash(str(self))
- i = int(self)
- if self == Decimal(i):
- return hash(i)
- assert self.__bool__() # '-0' handled by integer case
+ if not self:
+ return 0
+ if self._isinteger():
+ op = _WorkRep(self.to_integral_value())
+ # to make computation feasible for Decimals with large
+ # exponent, we use the fact that hash(n) == hash(m) for
+ # any two nonzero integers n and m such that (i) n and m
+ # have the same sign, and (ii) n is congruent to m modulo
+ # 2**64-1. So we can replace hash((-1)**s*c*10**e) with
+ # hash((-1)**s*c*pow(10, e, 2**64-1).
+ return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1))
return hash(str(self.normalize()))
def as_tuple(self):
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index 41d1dd5..513ba16 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -901,6 +901,38 @@ class DecimalUsabilityTest(unittest.TestCase):
def test_hash_method(self):
#just that it's hashable
hash(Decimal(23))
+
+ test_values = [Decimal(sign*(2**m + n))
+ for m in [0, 14, 15, 16, 17, 30, 31,
+ 32, 33, 62, 63, 64, 65, 66]
+ for n in range(-10, 10)
+ for sign in [-1, 1]]
+ test_values.extend([
+ Decimal("-0"), # zeros
+ Decimal("0.00"),
+ Decimal("-0.000"),
+ Decimal("0E10"),
+ Decimal("-0E12"),
+ Decimal("10.0"), # negative exponent
+ Decimal("-23.00000"),
+ Decimal("1230E100"), # positive exponent
+ Decimal("-4.5678E50"),
+ # a value for which hash(n) != hash(n % (2**64-1))
+ # in Python pre-2.6
+ Decimal(2**64 + 2**32 - 1),
+ # selection of values which fail with the old (before
+ # version 2.6) long.__hash__
+ Decimal("1.634E100"),
+ Decimal("90.697E100"),
+ Decimal("188.83E100"),
+ Decimal("1652.9E100"),
+ Decimal("56531E100"),
+ ])
+
+ # check that hash(d) == hash(int(d)) for integral values
+ for value in test_values:
+ self.assertEqual(hash(value), hash(int(value)))
+
#the same hash that to an int
self.assertEqual(hash(Decimal(23)), hash(23))
self.assertRaises(TypeError, hash, Decimal('NaN'))
diff --git a/Python/ceval.c b/Python/ceval.c
index 73a0624..dd6f6c4 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -28,8 +28,9 @@
typedef unsigned long long uint64;
#if defined(__ppc__) /* <- Don't know if this is the correct symbol; this
- section should work for GCC on any PowerPC platform,
- irrespective of OS. POWER? Who knows :-) */
+ section should work for GCC on any PowerPC
+ platform, irrespective of OS.
+ POWER? Who knows :-) */
#define READ_TIMESTAMP(var) ppc_getcounter(&var)
@@ -93,7 +94,8 @@ static PyObject * call_function(PyObject ***, int);
static PyObject * fast_function(PyObject *, PyObject ***, int, int, int);
static PyObject * do_call(PyObject *, PyObject ***, int, int);
static PyObject * ext_do_call(PyObject *, PyObject ***, int, int, int);
-static PyObject * update_keyword_args(PyObject *, int, PyObject ***,PyObject *);
+static PyObject * update_keyword_args(PyObject *, int, PyObject ***,
+ PyObject *);
static PyObject * update_star_args(int, int, PyObject *, PyObject ***);
static PyObject * load_args(PyObject ***, int);
#define CALL_FLAG_VAR 1
@@ -509,7 +511,8 @@ PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
PyObject *
PyEval_EvalFrame(PyFrameObject *f) {
/* This is for backward compatibility with extension modules that
- used this API; core interpreter code should call PyEval_EvalFrameEx() */
+ used this API; core interpreter code should call
+ PyEval_EvalFrameEx() */
return PyEval_EvalFrameEx(f, 0);
}
@@ -519,7 +522,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#ifdef DXPAIRS
int lastopcode = 0;
#endif
- register PyObject **stack_pointer; /* Next free slot in value stack */
+ register PyObject **stack_pointer; /* Next free slot in value stack */
register unsigned char *next_instr;
register int opcode; /* Current opcode */
register int oparg; /* Current opcode argument, if any */
@@ -610,10 +613,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#define JUMPBY(x) (next_instr += (x))
/* OpCode prediction macros
- Some opcodes tend to come in pairs thus making it possible to predict
- the second code when the first is run. For example, COMPARE_OP is often
- followed by JUMP_IF_FALSE or JUMP_IF_TRUE. And, those opcodes are often
- followed by a POP_TOP.
+ Some opcodes tend to come in pairs thus making it possible to
+ predict the second code when the first is run. For example,
+ COMPARE_OP is often followed by JUMP_IF_FALSE or JUMP_IF_TRUE. And,
+ those opcodes are often followed by a POP_TOP.
Verifying the prediction costs a single high-speed test of register
variable against a constant. If the pairing was good, then the
@@ -660,11 +663,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#define PUSH(v) { (void)(BASIC_PUSH(v), \
lltrace && prtrace(TOP(), "push")); \
assert(STACK_LEVEL() <= co->co_stacksize); }
-#define POP() ((void)(lltrace && prtrace(TOP(), "pop")), BASIC_POP())
+#define POP() ((void)(lltrace && prtrace(TOP(), "pop")), \
+ BASIC_POP())
#define STACKADJ(n) { (void)(BASIC_STACKADJ(n), \
lltrace && prtrace(TOP(), "stackadj")); \
assert(STACK_LEVEL() <= co->co_stacksize); }
-#define EXT_POP(STACK_POINTER) (lltrace && prtrace((STACK_POINTER)[-1], "ext_pop"), *--(STACK_POINTER))
+#define EXT_POP(STACK_POINTER) (lltrace && prtrace((STACK_POINTER)[-1], \
+ "ext_pop"), *--(STACK_POINTER))
#else
#define PUSH(v) BASIC_PUSH(v)
#define POP() BASIC_POP()
@@ -1568,7 +1573,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
if ((x = f->f_locals) != NULL) {
if ((err = PyObject_DelItem(x, w)) != 0)
format_exc_check_arg(PyExc_NameError,
- NAME_ERROR_MSG ,w);
+ NAME_ERROR_MSG,
+ w);
break;
}
PyErr_Format(PyExc_SystemError,
@@ -1579,8 +1585,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
PREDICTED_WITH_ARG(UNPACK_SEQUENCE);
case UNPACK_SEQUENCE:
v = POP();
- if (PyTuple_CheckExact(v) && PyTuple_GET_SIZE(v) == oparg) {
- PyObject **items = ((PyTupleObject *)v)->ob_item;
+ if (PyTuple_CheckExact(v) &&
+ PyTuple_GET_SIZE(v) == oparg) {
+ PyObject **items = \
+ ((PyTupleObject *)v)->ob_item;
while (oparg--) {
w = items[oparg];
Py_INCREF(w);
@@ -1588,15 +1596,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
}
Py_DECREF(v);
continue;
- } else if (PyList_CheckExact(v) && PyList_GET_SIZE(v) == oparg) {
- PyObject **items = ((PyListObject *)v)->ob_item;
+ } else if (PyList_CheckExact(v) &&
+ PyList_GET_SIZE(v) == oparg) {
+ PyObject **items = \
+ ((PyListObject *)v)->ob_item;
while (oparg--) {
w = items[oparg];
Py_INCREF(w);
PUSH(w);
}
} else if (unpack_iterable(v, oparg, -1,
- stack_pointer + oparg)) {
+ stack_pointer + oparg)) {
stack_pointer += oparg;
} else {
/* unpack_iterable() raised an exception */
@@ -1669,7 +1679,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
else {
x = PyObject_GetItem(v, w);
if (x == NULL && PyErr_Occurred()) {
- if (!PyErr_ExceptionMatches(PyExc_KeyError))
+ if (!PyErr_ExceptionMatches(
+ PyExc_KeyError))
break;
PyErr_Clear();
}
@@ -1681,7 +1692,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
if (x == NULL) {
format_exc_check_arg(
PyExc_NameError,
- NAME_ERROR_MSG ,w);
+ NAME_ERROR_MSG, w);
break;
}
}
@@ -1782,13 +1793,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
UNBOUNDLOCAL_ERROR_MSG,
v);
} else {
- v = PyTuple_GET_ITEM(
- co->co_freevars,
- oparg - PyTuple_GET_SIZE(co->co_cellvars));
- format_exc_check_arg(
- PyExc_NameError,
- UNBOUNDFREE_ERROR_MSG,
- v);
+ v = PyTuple_GET_ITEM(co->co_freevars, oparg -
+ PyTuple_GET_SIZE(co->co_cellvars));
+ format_exc_check_arg(PyExc_NameError,
+ UNBOUNDFREE_ERROR_MSG, v);
}
break;
@@ -2046,7 +2054,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
continue;
}
if (PyErr_Occurred()) {
- if (!PyErr_ExceptionMatches(PyExc_StopIteration))
+ if (!PyErr_ExceptionMatches(
+ PyExc_StopIteration))
break;
PyErr_Clear();
}
@@ -2072,9 +2081,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
case SETUP_LOOP:
case SETUP_EXCEPT:
case SETUP_FINALLY:
- /* NOTE: If you add any new block-setup opcodes that are
- not try/except/finally handlers, you may need to
- update the PyGen_NeedsFinalizing() function. */
+ /* NOTE: If you add any new block-setup opcodes that
+ are not try/except/finally handlers, you may need
+ to update the PyGen_NeedsFinalizing() function.
+ */
PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg,
STACK_LEVEL());
@@ -3968,8 +3978,9 @@ string_concatenate(PyObject *v, PyObject *w,
if (v->ob_refcnt == 2) {
/* In the common case, there are 2 references to the value
* stored in 'variable' when the += is performed: one on the
- * value stack (in 'v') and one still stored in the 'variable'.
- * We try to delete the variable now to reduce the refcnt to 1.
+ * value stack (in 'v') and one still stored in the
+ * 'variable'. We try to delete the variable now to reduce
+ * the refcnt to 1.
*/
switch (*next_instr) {
case STORE_FAST:
@@ -3982,7 +3993,8 @@ string_concatenate(PyObject *v, PyObject *w,
}
case STORE_DEREF:
{
- PyObject **freevars = f->f_localsplus + f->f_code->co_nlocals;
+ PyObject **freevars = (f->f_localsplus +
+ f->f_code->co_nlocals);
PyObject *c = freevars[PEEKARG()];
if (PyCell_GET(c) == v)
PyCell_Set(c, NULL);
@@ -4010,10 +4022,10 @@ string_concatenate(PyObject *v, PyObject *w,
*/
if (_PyString_Resize(&v, new_len) != 0) {
/* XXX if _PyString_Resize() fails, 'v' has been
- * deallocated so it cannot be put back into 'variable'.
- * The MemoryError is raised when there is no value in
- * 'variable', which might (very remotely) be a cause
- * of incompatibilities.
+ * deallocated so it cannot be put back into
+ * 'variable'. The MemoryError is raised when there
+ * is no value in 'variable', which might (very
+ * remotely) be a cause of incompatibilities.
*/
return NULL;
}