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:
parent
7ce29ca41c
commit
8ce81f767a
|
@ -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')
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
12
Lib/cgi.py
12
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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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'))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue