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.
........
This commit is contained in:
Thomas Wouters 2007-09-20 18:22:40 +00:00
parent 7ce29ca41c
commit 8ce81f767a
8 changed files with 117 additions and 61 deletions

View File

@ -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')

View File

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

View File

@ -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()

View File

@ -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:

View File

@ -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)

View File

@ -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):

View File

@ -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'))

View File

@ -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;
}