[Python-3000-checkins] r59005 - in python/branches/py3k: Doc/library/collections.rst Doc/library/random.rst Lib/collections.py Lib/test/seq_tests.py Lib/test/test_collections.py Modules/readline.c Modules/socketmodule.c

guido.van.rossum python-3000-checkins at python.org
Fri Nov 16 01:35:22 CET 2007


Author: guido.van.rossum
Date: Fri Nov 16 01:35:22 2007
New Revision: 59005

Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Doc/library/collections.rst
   python/branches/py3k/Doc/library/random.rst
   python/branches/py3k/Lib/collections.py
   python/branches/py3k/Lib/test/seq_tests.py
   python/branches/py3k/Lib/test/test_collections.py
   python/branches/py3k/Modules/readline.c
   python/branches/py3k/Modules/socketmodule.c
Log:
Merged revisions 58947-59004 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r58952 | christian.heimes | 2007-11-12 10:58:08 -0800 (Mon, 12 Nov 2007) | 6 lines
  
  readline module cleanup
  fixed indention to tabs
  use Py_RETURN_NONE macro
  added more error checks to on_completion_display_matches_hook
  
  open question: Does PyList_SetItem(l, i, o) steal a reference to o in the case of an error?
........
  r58956 | guido.van.rossum | 2007-11-12 12:06:40 -0800 (Mon, 12 Nov 2007) | 2 lines
  
  Add the test from issue 1704621 (the issue itself is already fixed here).
........
  r58963 | amaury.forgeotdarc | 2007-11-13 13:54:28 -0800 (Tue, 13 Nov 2007) | 23 lines
  
  Merge from py3k branch:
  Correction for issue1265 (pdb bug with "with" statement). 
  
  When an unfinished generator-iterator is garbage collected, PyEval_EvalFrameEx 
  is called with a GeneratorExit exception set.  This leads to funny results 
  if the sys.settrace function itself makes use of generators.
  A visible effect is that the settrace function is reset to None. 
  Another is that the eventual "finally" block of the generator is not called.
  
  It is necessary to save/restore the exception around the call to the trace
  function.
  
  This happens a lot with py3k: isinstance() of an ABCMeta instance runs
      def __instancecheck__(cls, instance):
          """Override for isinstance(instance, cls)."""
          return any(cls.__subclasscheck__(c)
                     for c in {instance.__class__, type(instance)})
  which lets an opened generator expression each time it returns True.
  
  Backport candidate, even if the case is less frequent in 2.5.
........
  r58968 | georg.brandl | 2007-11-14 05:59:09 -0800 (Wed, 14 Nov 2007) | 2 lines
  
  Remove dead link from random docs.
........
  r58971 | raymond.hettinger | 2007-11-14 14:56:16 -0800 (Wed, 14 Nov 2007) | 1 line
  
  Make __fields__ read-only.  Suggested by Issac Morland
........
  r58972 | raymond.hettinger | 2007-11-14 15:02:30 -0800 (Wed, 14 Nov 2007) | 1 line
  
  Add test for __fields__ being read-only
........
  r58975 | raymond.hettinger | 2007-11-14 18:44:53 -0800 (Wed, 14 Nov 2007) | 6 lines
  
  Accept Issac Morland's suggestion for __replace__ to allow multiple replacements
  (suprisingly, this simplifies the signature, improves clarity, and is comparably fast).
  Update the docs to reflect a previous change to the function name.
  Add an example to the docs showing how to override the default __repr__ method.
........
  r58976 | raymond.hettinger | 2007-11-14 18:55:42 -0800 (Wed, 14 Nov 2007) | 1 line
  
  Small improvement to the implementation of __replace__().
........
  r58977 | raymond.hettinger | 2007-11-14 18:58:20 -0800 (Wed, 14 Nov 2007) | 1 line
  
  Fixup example in docs.
........
  r58978 | raymond.hettinger | 2007-11-14 19:16:09 -0800 (Wed, 14 Nov 2007) | 1 line
  
  Example of multiple replacements.
........
  r58998 | raymond.hettinger | 2007-11-15 14:39:34 -0800 (Thu, 15 Nov 2007) | 1 line
  
  Add example for use cases requiring default values.
........
  r59000 | bill.janssen | 2007-11-15 15:03:03 -0800 (Thu, 15 Nov 2007) | 1 line
  
  add the certificate for the Python SVN repository for testing SSL
........
  r59004 | guido.van.rossum | 2007-11-15 16:24:44 -0800 (Thu, 15 Nov 2007) | 8 lines
  
  A patch from issue 1378 by roudkerk:
  
  Currently on Windows set_error() make use of a large array which maps
  socket error numbers to error messages.
  
  This patch removes that array and just lets PyErr_SetExcFromWindowsErr()
  generate the message by using the Win32 function FormatMessage().
........


Modified: python/branches/py3k/Doc/library/collections.rst
==============================================================================
--- python/branches/py3k/Doc/library/collections.rst	(original)
+++ python/branches/py3k/Doc/library/collections.rst	Fri Nov 16 01:35:22 2007
@@ -10,7 +10,7 @@
 
 This module implements high-performance container datatypes.  Currently,
 there are two datatypes, :class:`deque` and :class:`defaultdict`, and
-one datatype factory function, :func:`named_tuple`. Python already
+one datatype factory function, :func:`namedtuple`. Python already
 includes built-in containers, :class:`dict`, :class:`list`,
 :class:`set`, and :class:`tuple`. In addition, the optional :mod:`bsddb`
 module has a :meth:`bsddb.btopen` method that can be used to create in-memory
@@ -383,14 +383,14 @@
 
 .. _named-tuple-factory:
 
-:func:`named_tuple` Factory Function for Tuples with Named Fields
+: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
 they add the ability to access fields by name instead of position index.
 
-.. function:: named_tuple(typename, fieldnames, [verbose])
+.. function:: namedtuple(typename, fieldnames, [verbose])
 
    Returns a new tuple subclass named *typename*.  The new subclass is used to
    create tuple-like objects that have fields accessable by attribute lookup as
@@ -415,7 +415,7 @@
 
 Example::
 
-   >>> Point = named_tuple('Point', 'x y', verbose=True)
+   >>> Point = namedtuple('Point', 'x y', verbose=True)
    class Point(tuple):
            'Point(x, y)'
            __slots__ = ()
@@ -428,8 +428,8 @@
                'Return a new dict mapping field names to their values'
                return dict(zip(('x', 'y'), self))
            def __replace__(self, field, value):
-               'Return a new Point object replacing one field with a new value'
-               return Point(**dict(zip(('x', 'y'), self) + [(field, value)]))
+               'Return a new Point object replacing specified fields with new values'
+               return Point(**dict(zip(('x', 'y'), self) + kwds.items()))
            x = property(itemgetter(0))
            y = property(itemgetter(1))
 
@@ -447,7 +447,7 @@
 Named tuples are especially useful for assigning field names to result tuples returned
 by the :mod:`csv` or :mod:`sqlite3` modules::
 
-   EmployeeRecord = named_tuple('EmployeeRecord', 'name, age, title, department, paygrade')
+   EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')
 
    from itertools import starmap
    import csv
@@ -486,18 +486,18 @@
       >>> p.__asdict__()
       {'x': 11, 'y': 22}
       
-.. method:: somenamedtuple.__replace__(field, value)
+.. method:: somenamedtuple.__replace__(kwargs)
 
-   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 specified fields with new values:
 
 ::
 
       >>> p = Point(x=11, y=22)
-      >>> p.__replace__('x', 33)
+      >>> p.__replace__(x=33)
       Point(x=33, y=22)
 
-      >>> for recordnum, record in inventory:
-      ...     inventory[recordnum] = record.replace('total', record.price * record.quantity)
+      >>> for partnum, record in inventory.items():
+      ...     inventory[partnum] = record.__replace__(price=newprices[partnum], updated=time.now())
 
 .. attribute:: somenamedtuple.__fields__
 
@@ -509,11 +509,31 @@
       >>> p.__fields__                                  # view the field names
       ('x', 'y')
 
-      >>> Color = named_tuple('Color', 'red green blue')
-      >>> Pixel = named_tuple('Pixel', Point.__fields__ + Color.__fields__)
+      >>> Color = namedtuple('Color', 'red green blue')
+      >>> Pixel = namedtuple('Pixel', Point.__fields__ + Color.__fields__)
       >>> Pixel(11, 22, 128, 255, 0)
       Pixel(x=11, y=22, red=128, green=255, blue=0)'
 
+Since a named tuple is a regular Python class, it is easy to add or change
+functionality.  For example, the display format can be changed by overriding
+the :meth:`__repr__` method:
+
+::
+
+    >>> Point = namedtuple('Point', 'x y')
+    >>> Point.__repr__ = lambda self: 'Point(%.3f, %.3f)' % self
+    >>> Point(x=10, y=20)
+    Point(10.000, 20.000)
+
+Default values can be implemented by starting with a prototype instance
+and customizing it with :meth:`__replace__`:
+
+::
+
+    >>> Account = namedtuple('Account', 'owner balance transaction_count')
+    >>> model_account = Account('<owner name>', 0.0, 0)
+    >>> johns_account = model_account.__replace__(owner='John')
+
 .. rubric:: Footnotes
 
 .. [#] For information on the star-operator see

Modified: python/branches/py3k/Doc/library/random.rst
==============================================================================
--- python/branches/py3k/Doc/library/random.rst	(original)
+++ python/branches/py3k/Doc/library/random.rst	Fri Nov 16 01:35:22 2007
@@ -282,8 +282,3 @@
    Wichmann, B. A. & Hill, I. D., "Algorithm AS 183: An efficient and portable
    pseudo-random number generator", Applied Statistics 31 (1982) 188-190.
 
-   http://www.npl.co.uk/ssfm/download/abstracts.html#196
-      A modern variation of the Wichmann-Hill generator that greatly increases the
-      period, and passes now-standard statistical tests that the original generator
-      failed.
-

Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py	(original)
+++ python/branches/py3k/Lib/collections.py	Fri Nov 16 01:35:22 2007
@@ -30,7 +30,7 @@
     11
     >>> Point(**d)                      # convert from a dictionary
     Point(x=11, y=22)
-    >>> p.__replace__('x', 100)         # __replace__() is like str.replace() but targets a named field
+    >>> p.__replace__(x=100)            # __replace__() is like str.replace() but targets named fields
     Point(x=100, y=22)
 
     """
@@ -60,7 +60,7 @@
     template = '''class %(typename)s(tuple):
         '%(typename)s(%(argtxt)s)'
         __slots__ = ()
-        __fields__ = %(field_names)r
+        __fields__ = property(lambda self: %(field_names)r)
         def __new__(cls, %(argtxt)s):
             return tuple.__new__(cls, (%(argtxt)s))
         def __repr__(self):
@@ -68,9 +68,9 @@
         def __asdict__(self, dict=dict, zip=zip):
             'Return a new dict mapping field names to their values'
             return dict(zip(%(field_names)r, self))
-        def __replace__(self, field, value, dict=dict, zip=zip):
-            'Return a new %(typename)s object replacing one field with a new value'
-            return %(typename)s(**dict(list(zip(%(field_names)r, self)) + [(field, value)]))  \n''' % locals()
+        def __replace__(self, **kwds):
+            'Return a new %(typename)s object replacing specified fields with new values'
+            return %(typename)s(**dict(zip(%(field_names)r, self) + kwds.items()))  \n''' % locals()
     for i, name in enumerate(field_names):
         template += '        %s = property(itemgetter(%d))\n' % (name, i)
     if verbose:
@@ -103,6 +103,10 @@
     p = Point(x=10, y=20)
     assert p == loads(dumps(p))
 
+    # test and demonstrate ability to override methods
+    Point.__repr__ = lambda self:  'Point(%.3f, %.3f)' % self
+    print p
+
     import doctest
     TestResults = namedtuple('TestResults', 'failed attempted')
     print(TestResults(*doctest.testmod()))

Modified: python/branches/py3k/Lib/test/seq_tests.py
==============================================================================
--- python/branches/py3k/Lib/test/seq_tests.py	(original)
+++ python/branches/py3k/Lib/test/seq_tests.py	Fri Nov 16 01:35:22 2007
@@ -304,6 +304,13 @@
             self.assertEqual(self.type2test(s)*(-4), self.type2test([]))
             self.assertEqual(id(s), id(s*1))
 
+    def test_bigrepeat(self):
+        x = self.type2test([0])
+        x *= 2**16
+        self.assertRaises(MemoryError, x.__mul__, 2**16)
+        if hasattr(x, '__imul__'):
+            self.assertRaises(MemoryError, x.__imul__, 2**16)
+
     def test_subscript(self):
         a = self.type2test([10, 11])
         self.assertEqual(a.__getitem__(0), 10)

Modified: python/branches/py3k/Lib/test/test_collections.py
==============================================================================
--- python/branches/py3k/Lib/test/test_collections.py	(original)
+++ python/branches/py3k/Lib/test/test_collections.py	Fri Nov 16 01:35:22 2007
@@ -48,9 +48,17 @@
         self.assert_('__dict__' not in dir(p))                              # verify instance has no dict
         self.assert_('__weakref__' not in dir(p))
         self.assertEqual(p.__fields__, ('x', 'y'))                          # test __fields__ attribute
-        self.assertEqual(p.__replace__('x', 1), (1, 22))                    # test __replace__ method
+        self.assertEqual(p.__replace__(x=1), (1, 22))                       # test __replace__ method
         self.assertEqual(p.__asdict__(), dict(x=11, y=22))                  # test __dict__ method
 
+        # Verify that __fields__ is read-only
+        try:
+            p.__fields__ = ('F1' ,'F2')
+        except AttributeError:
+            pass
+        else:
+            self.fail('The __fields__ attribute needs to be read-only')
+
         # verify that field string can have commas
         Point = namedtuple('Point', 'x, y')
         p = Point(x=11, y=22)

Modified: python/branches/py3k/Modules/readline.c
==============================================================================
--- python/branches/py3k/Modules/readline.c	(original)
+++ python/branches/py3k/Modules/readline.c	Fri Nov 16 01:35:22 2007
@@ -59,8 +59,7 @@
 	strcpy(copy, s);
 	rl_parse_and_bind(copy);
 	free(copy); /* Free the copy */
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(doc_parse_and_bind,
@@ -79,8 +78,7 @@
 	errno = rl_read_init_file(s);
 	if (errno)
 		return PyErr_SetFromErrno(PyExc_IOError);
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(doc_read_init_file,
@@ -100,8 +98,7 @@
 	errno = read_history(s);
 	if (errno)
 		return PyErr_SetFromErrno(PyExc_IOError);
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 static int _history_length = -1; /* do not truncate history by default */
@@ -124,8 +121,7 @@
 		history_truncate_file(s, _history_length);
 	if (errno)
 		return PyErr_SetFromErrno(PyExc_IOError);
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(doc_write_history_file,
@@ -143,8 +139,7 @@
 	if (!PyArg_ParseTuple(args, "i:set_history_length", &length))
 		return NULL;
 	_history_length = length;
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(set_history_length_doc,
@@ -195,8 +190,7 @@
 		PyErr_SetString(PyExc_TypeError, buf);
 		return NULL;
 	}
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 
@@ -218,7 +212,7 @@
 	/* We cannot set this hook globally, since it replaces the
 	   default completion display. */
 	rl_completion_display_matches_hook =
-	  completion_display_matches_hook ? 
+		completion_display_matches_hook ?
 		(rl_compdisp_func_t *)on_completion_display_matches_hook : 0;
 #endif
 	return result;
@@ -325,8 +319,7 @@
 	}
 	free((void*)rl_completer_word_break_characters);
 	rl_completer_word_break_characters = strdup(break_chars);
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(doc_set_completer_delims,
@@ -336,32 +329,31 @@
 static PyObject *
 py_remove_history(PyObject *self, PyObject *args)
 {
-        int entry_number;
-        HIST_ENTRY *entry;
+	int entry_number;
+	HIST_ENTRY *entry;
 
-        if (!PyArg_ParseTuple(args, "i:remove_history", &entry_number))
-                return NULL;
-        if (entry_number < 0) {
-                PyErr_SetString(PyExc_ValueError,
-                                "History index cannot be negative");
-                return NULL;
-        }
-        entry = remove_history(entry_number);
-        if (!entry) {
-                PyErr_Format(PyExc_ValueError,
-                             "No history item at position %d",
-                             entry_number);
-                return NULL;
-        }
-        /* free memory allocated for the history entry */
-        if (entry->line)
-                free(entry->line);
-        if (entry->data)
-                free(entry->data);
-        free(entry);
+	if (!PyArg_ParseTuple(args, "i:remove_history", &entry_number))
+		return NULL;
+	if (entry_number < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"History index cannot be negative");
+		return NULL;
+	}
+	entry = remove_history(entry_number);
+	if (!entry) {
+		PyErr_Format(PyExc_ValueError,
+			     "No history item at position %d",
+			      entry_number);
+		return NULL;
+	}
+	/* free memory allocated for the history entry */
+	if (entry->line)
+		free(entry->line);
+	if (entry->data)
+		free(entry->data);
+	free(entry);
 
-        Py_INCREF(Py_None);
-        return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(doc_remove_history,
@@ -371,34 +363,34 @@
 static PyObject *
 py_replace_history(PyObject *self, PyObject *args)
 {
-        int entry_number;
-        char *line;
-        HIST_ENTRY *old_entry;
-
-        if (!PyArg_ParseTuple(args, "is:replace_history", &entry_number, &line)) {
-                return NULL;
-        }
-        if (entry_number < 0) {
-                PyErr_SetString(PyExc_ValueError,
-                                "History index cannot be negative");
-                return NULL;
-        }
-        old_entry = replace_history_entry(entry_number, line, (void *)NULL);
-        if (!old_entry) {
-                PyErr_Format(PyExc_ValueError,
-                             "No history item at position %d",
-                             entry_number);
-                return NULL;
-        }
-        /* free memory allocated for the old history entry */
-        if (old_entry->line)
-            free(old_entry->line);
-        if (old_entry->data)
-            free(old_entry->data);
-        free(old_entry);
+	int entry_number;
+	char *line;
+	HIST_ENTRY *old_entry;
+
+	if (!PyArg_ParseTuple(args, "is:replace_history", &entry_number,
+	      		      &line)) {
+		return NULL;
+	}
+	if (entry_number < 0) {
+		PyErr_SetString(PyExc_ValueError,
+				"History index cannot be negative");
+		return NULL;
+	}
+	old_entry = replace_history_entry(entry_number, line, (void *)NULL);
+	if (!old_entry) {
+		PyErr_Format(PyExc_ValueError,
+			     "No history item at position %d",
+			     entry_number);
+		return NULL;
+	}
+	/* free memory allocated for the old history entry */
+	if (old_entry->line)
+	    free(old_entry->line);
+	if (old_entry->data)
+	    free(old_entry->data);
+	free(old_entry);
 
-        Py_INCREF(Py_None);
-        return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(doc_replace_history,
@@ -416,8 +408,7 @@
 		return NULL;
 	}
 	add_history(line);
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(doc_add_history,
@@ -458,8 +449,7 @@
 get_completer(PyObject *self, PyObject *noargs)
 {
 	if (completer == NULL) {
-		Py_INCREF(Py_None);
-		return Py_None;
+		Py_RETURN_NONE;
 	}
 	Py_INCREF(completer);
 	return completer;
@@ -483,8 +473,7 @@
 	if ((hist_ent = history_get(idx)))
 		return PyUnicode_FromString(hist_ent->line);
 	else {
-		Py_INCREF(Py_None);
-		return Py_None;
+		Py_RETURN_NONE;
 	}
 }
 
@@ -530,8 +519,7 @@
 py_clear_history(PyObject *self, PyObject *noarg)
 {
 	clear_history();
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(doc_clear_history,
@@ -549,8 +537,7 @@
 	if (!PyArg_ParseTuple(args, "s:insert_text", &s))
 		return NULL;
 	rl_insert_text(s);
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(doc_insert_text,
@@ -564,8 +551,7 @@
 redisplay(PyObject *self, PyObject *noarg)
 {
 	rl_redisplay();
-	Py_INCREF(Py_None);
-	return Py_None;
+	Py_RETURN_NONE;
 }
 
 PyDoc_STRVAR(doc_redisplay,
@@ -591,9 +577,9 @@
 	 METH_VARARGS, doc_get_history_item},
 	{"get_current_history_length", (PyCFunction)get_current_history_length,
 	 METH_NOARGS, doc_get_current_history_length},
- 	{"set_history_length", set_history_length,
+	{"set_history_length", set_history_length,
 	 METH_VARARGS, set_history_length_doc},
- 	{"get_history_length", get_history_length,
+	{"get_history_length", get_history_length,
 	 METH_NOARGS, get_history_length_doc},
 	{"set_completer", set_completer, METH_VARARGS, doc_set_completer},
 	{"get_completer", get_completer, METH_NOARGS, doc_get_completer},
@@ -605,8 +591,8 @@
 	{"set_completer_delims", set_completer_delims,
 	 METH_VARARGS, doc_set_completer_delims},
 	{"add_history", py_add_history, METH_VARARGS, doc_add_history},
-        {"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
-        {"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
+	{"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
+	{"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
 	{"get_completer_delims", get_completer_delims,
 	 METH_NOARGS, doc_get_completer_delims},
 
@@ -633,7 +619,7 @@
 	int result = 0;
 	if (func != NULL) {
 		PyObject *r;
-#ifdef WITH_THREAD 
+#ifdef WITH_THREAD
 		PyGILState_STATE gilstate = PyGILState_Ensure();
 #endif
 		r = PyObject_CallFunction(func, NULL);
@@ -652,7 +638,7 @@
 		PyErr_Clear();
 		Py_XDECREF(r);
 	  done:
-#ifdef WITH_THREAD	      
+#ifdef WITH_THREAD
 		PyGILState_Release(gilstate);
 #endif
 		return result;
@@ -682,37 +668,37 @@
 				   int num_matches, int max_length)
 {
 	int i;
-	PyObject *m, *s;
-	PyObject *r;
+	PyObject *m=NULL, *s=NULL, *r=NULL;
 #ifdef WITH_THREAD
 	PyGILState_STATE gilstate = PyGILState_Ensure();
 #endif
 	m = PyList_New(num_matches);
+	if (m == NULL)
+		goto error;
 	for (i = 0; i < num_matches; i++) {
 		s = PyUnicode_FromString(matches[i+1]);
-		if (s) {
-			PyList_SetItem(m, i, s);
-		}
-		else {
+		if (s == NULL)
+			goto error;
+		if (PyList_SetItem(m, i, s) == -1)
 			goto error;
-		}
 	}
 	r = PyObject_CallFunction(completion_display_matches_hook,
 				  "sOi", matches[0], m, max_length);
 
 	Py_DECREF(m), m=NULL;
-
+	
 	if (r == NULL ||
 		(r != Py_None && PyInt_AsLong(r) == -1 && PyErr_Occurred())) {
 		goto error;
 	}
+	Py_XDECREF(r), r=NULL;
 
-	Py_DECREF(r);
-	goto done;
-  error:
-	PyErr_Clear();
-	Py_XDECREF(r);
-  done:
+	if (0) {
+	error:
+		PyErr_Clear();
+		Py_XDECREF(m);
+		Py_XDECREF(r);
+	}
 #ifdef WITH_THREAD
 	PyGILState_Release(gilstate);
 #endif

Modified: python/branches/py3k/Modules/socketmodule.c
==============================================================================
--- python/branches/py3k/Modules/socketmodule.c	(original)
+++ python/branches/py3k/Modules/socketmodule.c	Fri Nov 16 01:35:22 2007
@@ -450,87 +450,11 @@
 {
 #ifdef MS_WINDOWS
 	int err_no = WSAGetLastError();
-	static struct {
-		int no;
-		const char *msg;
-	} *msgp, msgs[] = {
-		{WSAEINTR, "Interrupted system call"},
-		{WSAEBADF, "Bad file descriptor"},
-		{WSAEACCES, "Permission denied"},
-		{WSAEFAULT, "Bad address"},
-		{WSAEINVAL, "Invalid argument"},
-		{WSAEMFILE, "Too many open files"},
-		{WSAEWOULDBLOCK,
-		  "The socket operation could not complete "
-		  "without blocking"},
-		{WSAEINPROGRESS, "Operation now in progress"},
-		{WSAEALREADY, "Operation already in progress"},
-		{WSAENOTSOCK, "Socket operation on non-socket"},
-		{WSAEDESTADDRREQ, "Destination address required"},
-		{WSAEMSGSIZE, "Message too long"},
-		{WSAEPROTOTYPE, "Protocol wrong type for socket"},
-		{WSAENOPROTOOPT, "Protocol not available"},
-		{WSAEPROTONOSUPPORT, "Protocol not supported"},
-		{WSAESOCKTNOSUPPORT, "Socket type not supported"},
-		{WSAEOPNOTSUPP, "Operation not supported"},
-		{WSAEPFNOSUPPORT, "Protocol family not supported"},
-		{WSAEAFNOSUPPORT, "Address family not supported"},
-		{WSAEADDRINUSE, "Address already in use"},
-		{WSAEADDRNOTAVAIL, "Can't assign requested address"},
-		{WSAENETDOWN, "Network is down"},
-		{WSAENETUNREACH, "Network is unreachable"},
-		{WSAENETRESET, "Network dropped connection on reset"},
-		{WSAECONNABORTED, "Software caused connection abort"},
-		{WSAECONNRESET, "Connection reset by peer"},
-		{WSAENOBUFS, "No buffer space available"},
-		{WSAEISCONN, "Socket is already connected"},
-		{WSAENOTCONN, "Socket is not connected"},
-		{WSAESHUTDOWN, "Can't send after socket shutdown"},
-		{WSAETOOMANYREFS, "Too many references: can't splice"},
-		{WSAETIMEDOUT, "Operation timed out"},
-		{WSAECONNREFUSED, "Connection refused"},
-		{WSAELOOP, "Too many levels of symbolic links"},
-		{WSAENAMETOOLONG, "File name too long"},
-		{WSAEHOSTDOWN, "Host is down"},
-		{WSAEHOSTUNREACH, "No route to host"},
-		{WSAENOTEMPTY, "Directory not empty"},
-		{WSAEPROCLIM, "Too many processes"},
-		{WSAEUSERS, "Too many users"},
-		{WSAEDQUOT, "Disc quota exceeded"},
-		{WSAESTALE, "Stale NFS file handle"},
-		{WSAEREMOTE, "Too many levels of remote in path"},
-		{WSASYSNOTREADY, "Network subsystem is unvailable"},
-		{WSAVERNOTSUPPORTED, "WinSock version is not supported"},
-		{WSANOTINITIALISED,
-		  "Successful WSAStartup() not yet performed"},
-		{WSAEDISCON, "Graceful shutdown in progress"},
-		/* Resolver errors */
-		{WSAHOST_NOT_FOUND, "No such host is known"},
-		{WSATRY_AGAIN, "Host not found, or server failed"},
-		{WSANO_RECOVERY, "Unexpected server error encountered"},
-		{WSANO_DATA, "Valid name without requested data"},
-		{WSANO_ADDRESS, "No address, look for MX record"},
-		{0, NULL}
-	};
-	if (err_no) {
-		PyObject *v;
-		const char *msg = "winsock error";
-
-		for (msgp = msgs; msgp->msg; msgp++) {
-			if (err_no == msgp->no) {
-				msg = msgp->msg;
-				break;
-			}
-		}
-
-		v = Py_BuildValue("(is)", err_no, msg);
-		if (v != NULL) {
-			PyErr_SetObject(socket_error, v);
-			Py_DECREF(v);
-		}
-		return NULL;
-	}
-	else
+	/* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which
+	   recognizes the error codes used by both GetLastError() and
+	   WSAGetLastError */
+	if (err_no)
+		return PyErr_SetExcFromWindowsErr(socket_error, err_no);
 #endif
 
 #if defined(PYOS_OS2) && !defined(PYCC_GCC)


More information about the Python-3000-checkins mailing list