[Python-3000-checkins] r58222 - in python/branches/py3k: Doc/library/collections.rst Doc/library/decimal.rst Doc/library/stdtypes.rst Doc/tutorial/inputoutput.rst Lib/cgi.py Lib/decimal.py Lib/test/test_decimal.py Python/ceval.c

thomas.wouters python-3000-checkins at python.org
Thu Sep 20 20:22:41 CEST 2007


Author: thomas.wouters
Date: Thu Sep 20 20:22:40 2007
New Revision: 58222

Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/collections.rst
   python/branches/py3k/Doc/library/decimal.rst
   python/branches/py3k/Doc/library/stdtypes.rst
   python/branches/py3k/Doc/tutorial/inputoutput.rst
   python/branches/py3k/Lib/cgi.py
   python/branches/py3k/Lib/decimal.py
   python/branches/py3k/Lib/test/test_decimal.py
   python/branches/py3k/Python/ceval.c
Log:
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.
........


Modified: python/branches/py3k/Doc/library/collections.rst
==============================================================================
--- python/branches/py3k/Doc/library/collections.rst	(original)
+++ python/branches/py3k/Doc/library/collections.rst	Thu Sep 20 20:22:40 2007
@@ -395,8 +395,8 @@
 
 .. _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 @@
    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 @@
 
 .. 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 @@
 
    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')

Modified: python/branches/py3k/Doc/library/decimal.rst
==============================================================================
--- python/branches/py3k/Doc/library/decimal.rst	(original)
+++ python/branches/py3k/Doc/library/decimal.rst	Thu Sep 20 20:22:40 2007
@@ -977,7 +977,7 @@
 
 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.
 

Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst	(original)
+++ python/branches/py3k/Doc/library/stdtypes.rst	Thu Sep 20 20:22:40 2007
@@ -657,10 +657,13 @@
 
 .. 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()
 

Modified: python/branches/py3k/Doc/tutorial/inputoutput.rst
==============================================================================
--- python/branches/py3k/Doc/tutorial/inputoutput.rst	(original)
+++ python/branches/py3k/Doc/tutorial/inputoutput.rst	Thu Sep 20 20:22:40 2007
@@ -252,7 +252,7 @@
    >>> 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:

Modified: python/branches/py3k/Lib/cgi.py
==============================================================================
--- python/branches/py3k/Lib/cgi.py	(original)
+++ python/branches/py3k/Lib/cgi.py	Thu Sep 20 20:22:40 2007
@@ -604,23 +604,21 @@
         """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)

Modified: python/branches/py3k/Lib/decimal.py
==============================================================================
--- python/branches/py3k/Lib/decimal.py	(original)
+++ python/branches/py3k/Lib/decimal.py	Thu Sep 20 20:22:40 2007
@@ -786,10 +786,17 @@
             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):

Modified: python/branches/py3k/Lib/test/test_decimal.py
==============================================================================
--- python/branches/py3k/Lib/test/test_decimal.py	(original)
+++ python/branches/py3k/Lib/test/test_decimal.py	Thu Sep 20 20:22:40 2007
@@ -901,6 +901,38 @@
     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'))

Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c	(original)
+++ python/branches/py3k/Python/ceval.c	Thu Sep 20 20:22:40 2007
@@ -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 * 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 @@
 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 @@
 #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 @@
 #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 @@
 #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 @@
 			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 @@
 		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 @@
 				}
 				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 @@
 			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 @@
 					if (x == NULL) {
 						format_exc_check_arg(
 							    PyExc_NameError,
-							    NAME_ERROR_MSG ,w);
+							    NAME_ERROR_MSG, w);
 						break;
 					}
 				}
@@ -1782,13 +1793,10 @@
 				       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 @@
 				continue;
 			}
 			if (PyErr_Occurred()) {
-				if (!PyErr_ExceptionMatches(PyExc_StopIteration))
+				if (!PyErr_ExceptionMatches(
+						PyExc_StopIteration))
 					break;
 				PyErr_Clear();
 			}
@@ -2072,9 +2081,10 @@
 		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 @@
 	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 @@
 		}
 		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 @@
 		 */
 		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;
 		}


More information about the Python-3000-checkins mailing list