[Python-checkins] r60446 - in python/branches/trunk-math: Doc/c-api/set.rst Doc/c-api/type.rst Doc/conf.py Doc/library/sys.rst Doc/tools/sphinxext Doc/tutorial/errors.rst Include/object.h Include/setobject.h Include/unicodeobject.h Lib/_abcoll.py Lib/ctypes/test/test_funcptr.py Lib/optparse.py Lib/pydoc.py Lib/rational.py Lib/test/regrtest.py Lib/test/test_builtin.py Lib/test/test_resource.py Lib/test/test_xmlrpc.py Makefile.pre.in Misc/NEWS Misc/Vim/python.vim Misc/Vim/syntax_test.py Misc/Vim/vim_syntax.py Modules/_ctypes/_ctypes.c Modules/_ctypes/callbacks.c Objects/abstract.c Objects/complexobject.c Objects/fileobject.c Objects/floatobject.c Objects/setobject.c Objects/typeobject.c Objects/unicodeobject.c Python/bltinmodule.c Python/compile.c Python/marshal.c Python/pythonrun.c Python/sysmodule.c setup.py

christian.heimes python-checkins at python.org
Wed Jan 30 14:42:24 CET 2008


Author: christian.heimes
Date: Wed Jan 30 14:42:22 2008
New Revision: 60446

Modified:
   python/branches/trunk-math/   (props changed)
   python/branches/trunk-math/Doc/c-api/set.rst
   python/branches/trunk-math/Doc/c-api/type.rst
   python/branches/trunk-math/Doc/conf.py
   python/branches/trunk-math/Doc/library/sys.rst
   python/branches/trunk-math/Doc/tools/sphinxext/   (props changed)
   python/branches/trunk-math/Doc/tutorial/errors.rst
   python/branches/trunk-math/Include/object.h
   python/branches/trunk-math/Include/setobject.h
   python/branches/trunk-math/Include/unicodeobject.h
   python/branches/trunk-math/Lib/_abcoll.py
   python/branches/trunk-math/Lib/ctypes/test/test_funcptr.py
   python/branches/trunk-math/Lib/optparse.py
   python/branches/trunk-math/Lib/pydoc.py
   python/branches/trunk-math/Lib/rational.py
   python/branches/trunk-math/Lib/test/regrtest.py
   python/branches/trunk-math/Lib/test/test_builtin.py
   python/branches/trunk-math/Lib/test/test_resource.py
   python/branches/trunk-math/Lib/test/test_xmlrpc.py
   python/branches/trunk-math/Makefile.pre.in
   python/branches/trunk-math/Misc/NEWS
   python/branches/trunk-math/Misc/Vim/python.vim
   python/branches/trunk-math/Misc/Vim/syntax_test.py
   python/branches/trunk-math/Misc/Vim/vim_syntax.py
   python/branches/trunk-math/Modules/_ctypes/_ctypes.c
   python/branches/trunk-math/Modules/_ctypes/callbacks.c
   python/branches/trunk-math/Objects/abstract.c
   python/branches/trunk-math/Objects/complexobject.c
   python/branches/trunk-math/Objects/fileobject.c
   python/branches/trunk-math/Objects/floatobject.c
   python/branches/trunk-math/Objects/setobject.c
   python/branches/trunk-math/Objects/typeobject.c
   python/branches/trunk-math/Objects/unicodeobject.c
   python/branches/trunk-math/Python/bltinmodule.c
   python/branches/trunk-math/Python/compile.c
   python/branches/trunk-math/Python/marshal.c
   python/branches/trunk-math/Python/pythonrun.c
   python/branches/trunk-math/Python/sysmodule.c
   python/branches/trunk-math/setup.py
Log:
Merged revisions 60364-60444 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r60364 | neal.norwitz | 2008-01-27 19:09:48 +0100 (Sun, 27 Jan 2008) | 4 lines
  
  Update the comment and remove the close.  If we close we can't flush anymore.
  We might still need to close after the for loop if flushing 6! times still
  doesn't cause the signal/exception.
........
  r60365 | georg.brandl | 2008-01-27 19:14:43 +0100 (Sun, 27 Jan 2008) | 2 lines
  
  Remove effectless expression statement.
........
  r60367 | neal.norwitz | 2008-01-27 19:19:04 +0100 (Sun, 27 Jan 2008) | 1 line
  
  Try to handle socket.errors properly in is_unavailable
........
  r60370 | christian.heimes | 2008-01-27 20:01:45 +0100 (Sun, 27 Jan 2008) | 1 line
  
  Change isbasestring function as discussed on the cvs list a while ago
........
  r60372 | neal.norwitz | 2008-01-27 21:03:13 +0100 (Sun, 27 Jan 2008) | 3 lines
  
  socket.error doesn't have a headers attribute like ProtocolError.
  Handle that situation where we catch socket.errors.
........
  r60375 | georg.brandl | 2008-01-27 21:25:12 +0100 (Sun, 27 Jan 2008) | 2 lines
  
  Add refcounting extension to build config.
........
  r60377 | jeffrey.yasskin | 2008-01-28 00:08:46 +0100 (Mon, 28 Jan 2008) | 6 lines
  
  Moved Rational._binary_float_to_ratio() to float.as_integer_ratio() because
  it's useful outside of rational numbers.
  
  This is my first C code that had to do anything significant. Please be more
  careful when looking over it.
........
  r60378 | christian.heimes | 2008-01-28 00:34:59 +0100 (Mon, 28 Jan 2008) | 1 line
  
  Added clear cache methods to clear the internal type lookup cache for ref leak test runs.
........
  r60381 | christian.heimes | 2008-01-28 03:07:53 +0100 (Mon, 28 Jan 2008) | 1 line
  
  static PyObject* variables should use PyString_InternFromString() instead of PyObject_FromString() to store a python string in a function level static var.
........
  r60388 | thomas.heller | 2008-01-28 09:44:13 +0100 (Mon, 28 Jan 2008) | 1 line
  
  Revert rev. 59925, it breaks comtypes (I need to further examine this).
........
  r60397 | raymond.hettinger | 2008-01-28 21:34:33 +0100 (Mon, 28 Jan 2008) | 5 lines
  
  Make PySet_Add() work with frozensets.
  Works like PyTuple_SetItem() to build-up values in a brand new frozenset.
  Also, PyFrozenSet_New() is now guaranteed to produce a distinct new frozenset.
........
  r60398 | raymond.hettinger | 2008-01-28 22:34:30 +0100 (Mon, 28 Jan 2008) | 1 line
  
  Let marshal built-up sets and frozensets one element at a time (without creating an intermediate tuple).
........
  r60399 | raymond.hettinger | 2008-01-28 22:47:42 +0100 (Mon, 28 Jan 2008) | 1 line
  
  Factor-out common code with a new macro
........
  r60400 | raymond.hettinger | 2008-01-28 22:48:07 +0100 (Mon, 28 Jan 2008) | 1 line
  
  Factor-out common code with a new macro
........
  r60401 | raymond.hettinger | 2008-01-28 22:51:25 +0100 (Mon, 28 Jan 2008) | 1 line
  
  Removed unnecessary conditional (spotted by Neal Norwitz).
........
  r60403 | gregory.p.smith | 2008-01-29 00:21:00 +0100 (Tue, 29 Jan 2008) | 4 lines
  
  Disable use of BerkeleyDB 4.6.x to see what the odd platform buildbots
  think.  In particular, neal norwitz has traced an Ubuntu sparc64 crash
  to the Lib/test/bsddb/test_basics.py test when opening a db with DB_THREAD.
........
  r60405 | brett.cannon | 2008-01-29 05:13:07 +0100 (Tue, 29 Jan 2008) | 2 lines
  
  Fix the reindent rule to use $(BUILDPYTHON).
........
  r60406 | brett.cannon | 2008-01-29 05:18:04 +0100 (Tue, 29 Jan 2008) | 3 lines
  
  Update Vim syntax highlighting to specify what revision was used to generate
  the file.
........
  r60407 | brett.cannon | 2008-01-29 05:20:56 +0100 (Tue, 29 Jan 2008) | 2 lines
  
  Ignore .pyc and .pyo files.
........
  r60425 | raymond.hettinger | 2008-01-29 20:52:09 +0100 (Tue, 29 Jan 2008) | 1 line
  
  CallMethod is faster with a NULL third-argument than with an empty format string.
........
  r60431 | raymond.hettinger | 2008-01-30 01:01:07 +0100 (Wed, 30 Jan 2008) | 1 line
  
  Add isdisjoint() to the Set/MutableSet ABCs.
........
  r60432 | raymond.hettinger | 2008-01-30 01:08:31 +0100 (Wed, 30 Jan 2008) | 1 line
  
  MutableSets support a remove() method.
........
  r60433 | raymond.hettinger | 2008-01-30 01:51:58 +0100 (Wed, 30 Jan 2008) | 1 line
  
  Demonstrate new except/as syntax.
........
  r60440 | christian.heimes | 2008-01-30 12:32:37 +0100 (Wed, 30 Jan 2008) | 1 line
  
  Patch #1970 by Antoine Pitrou: Speedup unicode whitespace and linebreak detection. The speedup is about 25% for split() (571 / 457 usec) and 35% (175 / 127 usec )for splitlines()
........
  r60441 | christian.heimes | 2008-01-30 12:46:00 +0100 (Wed, 30 Jan 2008) | 1 line
  
  Removed unused var
........


Modified: python/branches/trunk-math/Doc/c-api/set.rst
==============================================================================
--- python/branches/trunk-math/Doc/c-api/set.rst	(original)
+++ python/branches/trunk-math/Doc/c-api/set.rst	Wed Jan 30 14:42:22 2008
@@ -52,6 +52,12 @@
 the constructor functions work with any iterable Python object.
 
 
+.. cfunction:: int PySet_Check(PyObject *p)
+
+   Return true if *p* is a :class:`set` object or an instance of a subtype.
+
+   .. versionadded:: 2.6
+
 .. cfunction:: int PyAnySet_Check(PyObject *p)
 
    Return true if *p* is a :class:`set` object, a :class:`frozenset` object, or an
@@ -86,6 +92,11 @@
    set on success or *NULL* on failure.  Raise :exc:`TypeError` if *iterable* is
    not actually iterable.
 
+   .. versionchanged:: 2.6
+      Now guaranteed to return a brand-new :class:`frozenset`.  Formerly,
+      frozensets of zero-length were a singleton.  This got in the way of 
+      building-up new frozensets with :meth:`PySet_Add`.
+
 The following functions and macros are available for instances of :class:`set`
 or :class:`frozenset` or instances of their subtypes.
 
@@ -112,9 +123,6 @@
    the *key* is unhashable. Raise :exc:`PyExc_SystemError` if *anyset* is not a
    :class:`set`, :class:`frozenset`, or an instance of a subtype.
 
-The following functions are available for instances of :class:`set` or its
-subtypes but not for instances of :class:`frozenset` or its subtypes.
-
 
 .. cfunction:: int PySet_Add(PyObject *set, PyObject *key)
 
@@ -124,6 +132,14 @@
    Raise a :exc:`SystemError` if *set* is an not an instance of :class:`set` or its
    subtype.
 
+   .. versionchanged:: 2.6
+      Now works with instances of :class:`frozenset` or its subtypes.
+      Like :cfunc:`PyTuple_SetItem` in that it can be used to fill-in the
+      values of brand new frozensets before they are exposed to other code.
+
+The following functions are available for instances of :class:`set` or its
+subtypes but not for instances of :class:`frozenset` or its subtypes.
+
 
 .. cfunction:: int PySet_Discard(PyObject *set, PyObject *key)
 

Modified: python/branches/trunk-math/Doc/c-api/type.rst
==============================================================================
--- python/branches/trunk-math/Doc/c-api/type.rst	(original)
+++ python/branches/trunk-math/Doc/c-api/type.rst	Wed Jan 30 14:42:22 2008
@@ -35,6 +35,13 @@
    .. versionadded:: 2.2
 
 
+.. cfunction:: unsigned int PyType_ClearCache(void)
+
+   Clears the internal lookup cache. Return the current version tag.
+
+   .. versionadded:: 2.6
+
+
 .. cfunction:: int PyType_HasFeature(PyObject *o, int feature)
 
    Return true if the type object *o* sets the feature *feature*.  Type features

Modified: python/branches/trunk-math/Doc/conf.py
==============================================================================
--- python/branches/trunk-math/Doc/conf.py	(original)
+++ python/branches/trunk-math/Doc/conf.py	Wed Jan 30 14:42:22 2008
@@ -13,6 +13,8 @@
 # General configuration
 # ---------------------
 
+extensions = ['sphinx.addons.refcounting']
+
 # General substitutions.
 project = 'Python'
 copyright = '1990-%s, Python Software Foundation' % time.strftime('%Y')

Modified: python/branches/trunk-math/Doc/library/sys.rst
==============================================================================
--- python/branches/trunk-math/Doc/library/sys.rst	(original)
+++ python/branches/trunk-math/Doc/library/sys.rst	Wed Jan 30 14:42:22 2008
@@ -58,6 +58,13 @@
    A string containing the copyright pertaining to the Python interpreter.
 
 
+.. function:: _cleartypecache()
+
+   Clear the internal type lookup cache.
+
+   .. versionadded:: 2.6
+
+
 .. function:: _current_frames()
 
    Return a dictionary mapping each thread's identifier to the topmost stack frame

Modified: python/branches/trunk-math/Doc/tutorial/errors.rst
==============================================================================
--- python/branches/trunk-math/Doc/tutorial/errors.rst	(original)
+++ python/branches/trunk-math/Doc/tutorial/errors.rst	Wed Jan 30 14:42:22 2008
@@ -131,7 +131,7 @@
        f = open('myfile.txt')
        s = f.readline()
        i = int(s.strip())
-   except IOError, (errno, strerror):
+   except IOError as (errno, strerror):
        print "I/O error(%s): %s" % (errno, strerror)
    except ValueError:
        print "Could not convert data to an integer."
@@ -176,7 +176,7 @@
 
    >>> try:
    ...    raise Exception('spam', 'eggs')
-   ... except Exception, inst:
+   ... except Exception as inst:
    ...    print type(inst)     # the exception instance
    ...    print inst.args      # arguments stored in .args
    ...    print inst           # __str__ allows args to printed directly
@@ -202,7 +202,7 @@
    ... 
    >>> try:
    ...     this_fails()
-   ... except ZeroDivisionError, detail:
+   ... except ZeroDivisionError as detail:
    ...     print 'Handling run-time error:', detail
    ... 
    Handling run-time error: integer division or modulo by zero
@@ -259,7 +259,7 @@
    ... 
    >>> try:
    ...     raise MyError(2*2)
-   ... except MyError, e:
+   ... except MyError as e:
    ...     print 'My exception occurred, value:', e.value
    ... 
    My exception occurred, value: 4

Modified: python/branches/trunk-math/Include/object.h
==============================================================================
--- python/branches/trunk-math/Include/object.h	(original)
+++ python/branches/trunk-math/Include/object.h	Wed Jan 30 14:42:22 2008
@@ -399,6 +399,7 @@
 PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *,
 					       PyObject *, PyObject *);
 PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
+PyAPI_FUNC(unsigned int) PyType_ClearCache(void);
 
 /* Generic operations on objects */
 PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);

Modified: python/branches/trunk-math/Include/setobject.h
==============================================================================
--- python/branches/trunk-math/Include/setobject.h	(original)
+++ python/branches/trunk-math/Include/setobject.h	Wed Jan 30 14:42:22 2008
@@ -73,6 +73,8 @@
 	(Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type || \
 	  PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \
 	  PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type))
+#define PySet_Check(ob) \
+	(Py_TYPE(ob) == &PySet_Type || PyType_IsSubtype(Py_TYPE(ob), &PySet_Type))
 
 PyAPI_FUNC(PyObject *) PySet_New(PyObject *);
 PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *);

Modified: python/branches/trunk-math/Include/unicodeobject.h
==============================================================================
--- python/branches/trunk-math/Include/unicodeobject.h	(original)
+++ python/branches/trunk-math/Include/unicodeobject.h	Wed Jan 30 14:42:22 2008
@@ -348,7 +348,14 @@
 
 #else
 
-#define Py_UNICODE_ISSPACE(ch) _PyUnicode_IsWhitespace(ch)
+/* Since splitting on whitespace is an important use case, and whitespace
+   in most situations is solely ASCII whitespace, we optimize for the common
+   case by using a quick look-up table with an inlined check.
+ */
+extern const unsigned char _Py_ascii_whitespace[];
+
+#define Py_UNICODE_ISSPACE(ch) \
+	((ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch))
 
 #define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch)
 #define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch)

Modified: python/branches/trunk-math/Lib/_abcoll.py
==============================================================================
--- python/branches/trunk-math/Lib/_abcoll.py	(original)
+++ python/branches/trunk-math/Lib/_abcoll.py	Wed Jan 30 14:42:22 2008
@@ -177,6 +177,12 @@
             return NotImplemented
         return self._from_iterable(value for value in other if value in self)
 
+    def isdisjoint(self, other):
+        for value in other:
+            if value in self:
+                return False
+        return True
+
     def __or__(self, other):
         if not isinstance(other, Iterable):
             return NotImplemented
@@ -244,6 +250,12 @@
         """Return True if it was deleted, False if not there."""
         raise NotImplementedError
 
+    def remove(self, value):
+        """Remove an element. If not a member, raise a KeyError."""
+        if value not in self:
+            raise KeyError(value)
+        self.discard(value)
+
     def pop(self):
         """Return the popped value.  Raise KeyError if empty."""
         it = iter(self)

Modified: python/branches/trunk-math/Lib/ctypes/test/test_funcptr.py
==============================================================================
--- python/branches/trunk-math/Lib/ctypes/test/test_funcptr.py	(original)
+++ python/branches/trunk-math/Lib/ctypes/test/test_funcptr.py	Wed Jan 30 14:42:22 2008
@@ -123,11 +123,5 @@
         self.failUnlessEqual(strtok(None, "\n"), "c")
         self.failUnlessEqual(strtok(None, "\n"), None)
 
-    def test_NULL_funcptr(self):
-        tp = CFUNCTYPE(c_int)
-        func = tp() # NULL function pointer
-        # raise a ValueError when we try to call it
-        self.assertRaises(ValueError, func)
-
 if __name__ == '__main__':
     unittest.main()

Modified: python/branches/trunk-math/Lib/optparse.py
==============================================================================
--- python/branches/trunk-math/Lib/optparse.py	(original)
+++ python/branches/trunk-math/Lib/optparse.py	Wed Jan 30 14:42:22 2008
@@ -823,12 +823,14 @@
 except NameError:
     (True, False) = (1, 0)
 
-def isbasestring(x):
-    try:
+try:
+    basestring
+except NameError:
+    def isbasestring(x):
+        return isinstance(x, (types.StringType, types.UnicodeType))
+else:
+    def isbasestring(x):
         return isinstance(x, basestring)
-    except:
-        return isinstance(x, types.StringType) or isinstance(x, types.UnicodeType)
-
 
 class Values:
 

Modified: python/branches/trunk-math/Lib/pydoc.py
==============================================================================
--- python/branches/trunk-math/Lib/pydoc.py	(original)
+++ python/branches/trunk-math/Lib/pydoc.py	Wed Jan 30 14:42:22 2008
@@ -1197,7 +1197,6 @@
             else:
                 tag = "inherited from %s" % classname(thisclass,
                                                       object.__module__)
-            filter(lambda t: not t[0].startswith('_'), attrs)
 
             # Sort attrs by name.
             attrs.sort()

Modified: python/branches/trunk-math/Lib/rational.py
==============================================================================
--- python/branches/trunk-math/Lib/rational.py	(original)
+++ python/branches/trunk-math/Lib/rational.py	Wed Jan 30 14:42:22 2008
@@ -25,60 +25,6 @@
     return a
 
 
-def _binary_float_to_ratio(x):
-    """x -> (top, bot), a pair of ints s.t. x = top/bot.
-
-    The conversion is done exactly, without rounding.
-    bot > 0 guaranteed.
-    Some form of binary fp is assumed.
-    Pass NaNs or infinities at your own risk.
-
-    >>> _binary_float_to_ratio(10.0)
-    (10, 1)
-    >>> _binary_float_to_ratio(0.0)
-    (0, 1)
-    >>> _binary_float_to_ratio(-.25)
-    (-1, 4)
-    """
-    # XXX Move this to floatobject.c with a name like
-    # float.as_integer_ratio()
-
-    if x == 0:
-        return 0, 1
-    f, e = math.frexp(x)
-    signbit = 1
-    if f < 0:
-        f = -f
-        signbit = -1
-    assert 0.5 <= f < 1.0
-    # x = signbit * f * 2**e exactly
-
-    # Suck up CHUNK bits at a time; 28 is enough so that we suck
-    # up all bits in 2 iterations for all known binary double-
-    # precision formats, and small enough to fit in an int.
-    CHUNK = 28
-    top = 0
-    # invariant: x = signbit * (top + f) * 2**e exactly
-    while f:
-        f = math.ldexp(f, CHUNK)
-        digit = trunc(f)
-        assert digit >> CHUNK == 0
-        top = (top << CHUNK) | digit
-        f = f - digit
-        assert 0.0 <= f < 1.0
-        e = e - CHUNK
-    assert top
-
-    # Add in the sign bit.
-    top = signbit * top
-
-    # now x = top * 2**e exactly; fold in 2**e
-    if e>0:
-        return (top * 2**e, 1)
-    else:
-        return (top, 2 ** -e)
-
-
 _RATIONAL_FORMAT = re.compile(
     r'^\s*(?P<sign>[-+]?)(?P<num>\d+)'
     r'(?:/(?P<denom>\d+)|\.(?P<decimal>\d+))?\s*$')
@@ -163,7 +109,7 @@
                             (cls.__name__, f, type(f).__name__))
         if math.isnan(f) or math.isinf(f):
             raise TypeError("Cannot convert %r to %s." % (f, cls.__name__))
-        return cls(*_binary_float_to_ratio(f))
+        return cls(*f.as_integer_ratio())
 
     @classmethod
     def from_decimal(cls, dec):

Modified: python/branches/trunk-math/Lib/test/regrtest.py
==============================================================================
--- python/branches/trunk-math/Lib/test/regrtest.py	(original)
+++ python/branches/trunk-math/Lib/test/regrtest.py	Wed Jan 30 14:42:22 2008
@@ -709,6 +709,9 @@
     sys.path_importer_cache.clear()
     sys.path_importer_cache.update(pic)
 
+    # clear type cache
+    sys._cleartypecache()
+
     # Clear ABC registries, restoring previously saved ABC registries.
     for abc in [getattr(_abcoll, a) for a in _abcoll.__all__]:
         if not issubclass(abc, _Abstract):

Modified: python/branches/trunk-math/Lib/test/test_builtin.py
==============================================================================
--- python/branches/trunk-math/Lib/test/test_builtin.py	(original)
+++ python/branches/trunk-math/Lib/test/test_builtin.py	Wed Jan 30 14:42:22 2008
@@ -5,7 +5,7 @@
                               run_unittest, run_with_locale
 from operator import neg
 
-import sys, warnings, cStringIO, random, UserDict
+import sys, warnings, cStringIO, random, rational, UserDict
 warnings.filterwarnings("ignore", "hex../oct.. of negative int",
                         FutureWarning, __name__)
 warnings.filterwarnings("ignore", "integer argument expected",
@@ -688,6 +688,25 @@
         self.assertAlmostEqual(float(Foo3(21)), 42.)
         self.assertRaises(TypeError, float, Foo4(42))
 
+    def test_floatasratio(self):
+        R = rational.Rational
+        self.assertEqual(R(0, 1),
+                         R(*float(0.0).as_integer_ratio()))
+        self.assertEqual(R(5, 2),
+                         R(*float(2.5).as_integer_ratio()))
+        self.assertEqual(R(1, 2),
+                         R(*float(0.5).as_integer_ratio()))
+        self.assertEqual(R(4728779608739021, 2251799813685248),
+                         R(*float(2.1).as_integer_ratio()))
+        self.assertEqual(R(-4728779608739021, 2251799813685248),
+                         R(*float(-2.1).as_integer_ratio()))
+        self.assertEqual(R(-2100, 1),
+                         R(*float(-2100.0).as_integer_ratio()))
+
+        self.assertRaises(OverflowError, float('inf').as_integer_ratio)
+        self.assertRaises(OverflowError, float('-inf').as_integer_ratio)
+        self.assertRaises(ValueError, float('nan').as_integer_ratio)
+
     def test_getattr(self):
         import sys
         self.assert_(getattr(sys, 'stdout') is sys.stdout)

Modified: python/branches/trunk-math/Lib/test/test_resource.py
==============================================================================
--- python/branches/trunk-math/Lib/test/test_resource.py	(original)
+++ python/branches/trunk-math/Lib/test/test_resource.py	Wed Jan 30 14:42:22 2008
@@ -56,13 +56,12 @@
                         f.flush()
                         # On some systems (e.g., Ubuntu on hppa) the flush()
                         # doesn't always cause the exception, but the close()
-                        # does eventually.  Try closing several times in
+                        # does eventually.  Try flushing several times in
                         # an attempt to ensure the file is really synced and
                         # the exception raised.
                         for i in range(5):
                             time.sleep(.1)
                             f.flush()
-                            f.close()
                     except IOError:
                         if not limit_set:
                             raise

Modified: python/branches/trunk-math/Lib/test/test_xmlrpc.py
==============================================================================
--- python/branches/trunk-math/Lib/test/test_xmlrpc.py	(original)
+++ python/branches/trunk-math/Lib/test/test_xmlrpc.py	Wed Jan 30 14:42:22 2008
@@ -348,10 +348,14 @@
        given by operations on non-blocking sockets.'''
 
     # sometimes we get a -1 error code and/or empty headers
-    if e.errcode == -1 or e.headers is None:
-        return True
+    try:
+        if e.errcode == -1 or e.headers is None:
+            return True
+        exc_mess = e.headers.get('X-exception')
+    except AttributeError:
+        # Ignore socket.errors here.
+        exc_mess = str(e)
 
-    exc_mess = e.headers.get('X-exception')
     if exc_mess and 'temporarily unavailable' in exc_mess.lower():
         return True
 
@@ -393,7 +397,7 @@
             # ignore failures due to non-blocking socket 'unavailable' errors
             if not is_unavailable_exception(e):
                 # protocol error; provide additional information in test output
-                self.fail("%s\n%s" % (e, e.headers))
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
     # [ch] The test 404 is causing lots of false alarms.
     def XXXtest_404(self):
@@ -419,7 +423,7 @@
             # ignore failures due to non-blocking socket 'unavailable' errors
             if not is_unavailable_exception(e):
                 # protocol error; provide additional information in test output
-                self.fail("%s\n%s" % (e, e.headers))
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
     def test_introspection2(self):
         try:
@@ -431,7 +435,7 @@
             # ignore failures due to non-blocking socket 'unavailable' errors
             if not is_unavailable_exception(e):
                 # protocol error; provide additional information in test output
-                self.fail("%s\n%s" % (e, e.headers))
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
     def test_introspection3(self):
         try:
@@ -443,7 +447,7 @@
             # ignore failures due to non-blocking socket 'unavailable' errors
             if not is_unavailable_exception(e):
                 # protocol error; provide additional information in test output
-                self.fail("%s\n%s" % (e, e.headers))
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
     def test_introspection4(self):
         # the SimpleXMLRPCServer doesn't support signatures, but
@@ -456,7 +460,7 @@
             # ignore failures due to non-blocking socket 'unavailable' errors
             if not is_unavailable_exception(e):
                 # protocol error; provide additional information in test output
-                self.fail("%s\n%s" % (e, e.headers))
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
     def test_multicall(self):
         try:
@@ -473,7 +477,7 @@
             # ignore failures due to non-blocking socket 'unavailable' errors
             if not is_unavailable_exception(e):
                 # protocol error; provide additional information in test output
-                self.fail("%s\n%s" % (e, e.headers))
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
     def test_non_existing_multicall(self):
         try:
@@ -494,7 +498,7 @@
             # ignore failures due to non-blocking socket 'unavailable' errors
             if not is_unavailable_exception(e):
                 # protocol error; provide additional information in test output
-                self.fail("%s\n%s" % (e, e.headers))
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
     def test_dotted_attribute(self):
         # this will raise AttirebuteError because code don't want us to use
@@ -549,7 +553,7 @@
             # ignore failures due to non-blocking socket 'unavailable' errors
             if not is_unavailable_exception(e):
                 # protocol error; provide additional information in test output
-                self.fail("%s\n%s" % (e, e.headers))
+                self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
 
     def test_fail_no_info(self):
         # use the broken message class
@@ -560,7 +564,7 @@
             p.pow(6,8)
         except (xmlrpclib.ProtocolError, socket.error), e:
             # ignore failures due to non-blocking socket 'unavailable' errors
-            if not is_unavailable_exception(e):
+            if not is_unavailable_exception(e) and hasattr(e, "headers"):
                 # The two server-side error headers shouldn't be sent back in this case
                 self.assertTrue(e.headers.get("X-exception") is None)
                 self.assertTrue(e.headers.get("X-traceback") is None)
@@ -580,7 +584,7 @@
             p.pow(6,8)
         except (xmlrpclib.ProtocolError, socket.error), e:
             # ignore failures due to non-blocking socket 'unavailable' errors
-            if not is_unavailable_exception(e):
+            if not is_unavailable_exception(e) and hasattr(e, "headers"):
                 # We should get error info in the response
                 expected_err = "invalid literal for int() with base 10: 'I am broken'"
                 self.assertEqual(e.headers.get("x-exception"), expected_err)

Modified: python/branches/trunk-math/Makefile.pre.in
==============================================================================
--- python/branches/trunk-math/Makefile.pre.in	(original)
+++ python/branches/trunk-math/Makefile.pre.in	Wed Jan 30 14:42:22 2008
@@ -1027,7 +1027,7 @@
 
 # Run reindent on the library
 reindent:
-	./python$(EXEEXT) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib
+	./$(BUILDPYTHON) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib
 
 # Rerun configure with the same options as it was run last time,
 # provided the config.status script exists

Modified: python/branches/trunk-math/Misc/NEWS
==============================================================================
--- python/branches/trunk-math/Misc/NEWS	(original)
+++ python/branches/trunk-math/Misc/NEWS	Wed Jan 30 14:42:22 2008
@@ -20,6 +20,12 @@
   without the four functions and copysign in libm were added to a new file
   Python/pymath.c.
 
+- Patch #1970 by Antoine Pitrou: Speedup unicode whitespace and linebreak
+  detection
+
+- Added ``PyType_ClearCache()`` and ``sys._cleartypecache`` to clear the
+  internal lookup cache for ref leak tests.
+
 - Patch #1473257: generator objects gain a gi_code attribute. This is the
   same object as the func_code attribute of the function that produced the
   generator.

Modified: python/branches/trunk-math/Misc/Vim/python.vim
==============================================================================
--- python/branches/trunk-math/Misc/Vim/python.vim	(original)
+++ python/branches/trunk-math/Misc/Vim/python.vim	Wed Jan 30 14:42:22 2008
@@ -1,4 +1,4 @@
-" Auto-generated Vim syntax file for Python
+" Auto-generated Vim syntax file for Python (trunk: r60376M).
 "
 " To use: copy or symlink to ~/.vim/syntax/python.vim
 
@@ -64,7 +64,7 @@
 if exists("python_highlight_builtins")
   syn keyword pythonBuiltin    Ellipsis False None NotImplemented True __debug__
   syn keyword pythonBuiltin    __import__ abs all any apply basestring bool
-  syn keyword pythonBuiltin    buffer callable chr classmethod cmp coerce
+  syn keyword pythonBuiltin    buffer bytes callable chr classmethod cmp coerce
   syn keyword pythonBuiltin    compile complex copyright credits delattr dict
   syn keyword pythonBuiltin    dir divmod enumerate eval execfile exit file
   syn keyword pythonBuiltin    filter float frozenset getattr globals hasattr
@@ -73,7 +73,8 @@
   syn keyword pythonBuiltin    max min object oct open ord pow property quit
   syn keyword pythonBuiltin    range raw_input reduce reload repr reversed round
   syn keyword pythonBuiltin    set setattr slice sorted staticmethod str sum
-  syn keyword pythonBuiltin    super tuple type unichr unicode vars xrange zip
+  syn keyword pythonBuiltin    super trunc tuple type unichr unicode vars xrange
+  syn keyword pythonBuiltin    zip
 
 endif
 

Modified: python/branches/trunk-math/Misc/Vim/syntax_test.py
==============================================================================
--- python/branches/trunk-math/Misc/Vim/syntax_test.py	(original)
+++ python/branches/trunk-math/Misc/Vim/syntax_test.py	Wed Jan 30 14:42:22 2008
@@ -4,9 +4,8 @@
 Not necessarily sensical or comprehensive (assume that if one exception is
 highlighted that all are, for instance).
 
-Highlighting extraneous whitespace at the end of the line is not represented
-here as all trailing whitespace is automatically removed from .py files in the
-repository.
+Extraneous trailing whitespace can't be tested because of svn pre-commit hook
+checks for such things.
 
 """
 # Comment

Modified: python/branches/trunk-math/Misc/Vim/vim_syntax.py
==============================================================================
--- python/branches/trunk-math/Misc/Vim/vim_syntax.py	(original)
+++ python/branches/trunk-math/Misc/Vim/vim_syntax.py	Wed Jan 30 14:42:22 2008
@@ -4,8 +4,9 @@
 import exceptions
 import __builtin__
 from string import Template
+from sys import subversion
 
-comment_header = '''" Auto-generated Vim syntax file for Python.
+comment_header = '''" Auto-generated Vim syntax file for Python (%s: r%s).
 "
 " To use: copy or symlink to ~/.vim/syntax/python.vim'''
 
@@ -160,7 +161,7 @@
 def main(file_path):
     with open(file_path, 'w') as FILE:
         # Comment for file
-        print>>FILE, comment_header
+        print>>FILE, comment_header % subversion[1:]
         print>>FILE, ''
         # Statements at start of file
         print>>FILE, statement_header

Modified: python/branches/trunk-math/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/branches/trunk-math/Modules/_ctypes/_ctypes.c	(original)
+++ python/branches/trunk-math/Modules/_ctypes/_ctypes.c	Wed Jan 30 14:42:22 2008
@@ -1529,9 +1529,9 @@
 
 	if (suffix == NULL)
 #ifdef WORDS_BIGENDIAN
-		suffix = PyString_FromString("_le");
+		suffix = PyString_InternFromString("_le");
 #else
-		suffix = PyString_FromString("_be");
+		suffix = PyString_InternFromString("_be");
 #endif
 
 	Py_INCREF(name);
@@ -3435,11 +3435,6 @@
 
 
 	pProc = *(void **)self->b_ptr;
-	if (pProc == NULL) {
-		PyErr_SetString(PyExc_ValueError,
-				"attempt to call NULL function pointer");
-		return NULL;
-	}
 #ifdef MS_WIN32
 	if (self->index) {
 		/* It's a COM method */
@@ -4416,7 +4411,7 @@
 	}
 
 	if (format == NULL) {
-		format = PyString_FromString("%s(%r)");
+		format = PyString_InternFromString("%s(%r)");
 		if (format == NULL)
 			return NULL;
 	}

Modified: python/branches/trunk-math/Modules/_ctypes/callbacks.c
==============================================================================
--- python/branches/trunk-math/Modules/_ctypes/callbacks.c	(original)
+++ python/branches/trunk-math/Modules/_ctypes/callbacks.c	Wed Jan 30 14:42:22 2008
@@ -368,7 +368,7 @@
 	static PyObject *context;
 
 	if (context == NULL)
-		context = PyString_FromString("_ctypes.DllGetClassObject");
+		context = PyString_InternFromString("_ctypes.DllGetClassObject");
 
 	mod = PyImport_ImportModuleNoBlock("ctypes");
 	if (!mod) {
@@ -447,7 +447,7 @@
 	static PyObject *context;
 
 	if (context == NULL)
-		context = PyString_FromString("_ctypes.DllCanUnloadNow");
+		context = PyString_InternFromString("_ctypes.DllCanUnloadNow");
 
 	mod = PyImport_ImportModuleNoBlock("ctypes");
 	if (!mod) {

Modified: python/branches/trunk-math/Objects/abstract.c
==============================================================================
--- python/branches/trunk-math/Objects/abstract.c	(original)
+++ python/branches/trunk-math/Objects/abstract.c	Wed Jan 30 14:42:22 2008
@@ -2142,7 +2142,7 @@
 	PyObject *bases;
 
 	if (__bases__ == NULL) {
-		__bases__ = PyString_FromString("__bases__");
+		__bases__ = PyString_InternFromString("__bases__");
 		if (__bases__ == NULL)
 			return NULL;
 	}
@@ -2220,7 +2220,7 @@
 	int retval = 0;
 
 	if (__class__ == NULL) {
-		__class__ = PyString_FromString("__class__");
+		__class__ = PyString_InternFromString("__class__");
 		if (__class__ == NULL)
 			return -1;
 	}

Modified: python/branches/trunk-math/Objects/complexobject.c
==============================================================================
--- python/branches/trunk-math/Objects/complexobject.c	(original)
+++ python/branches/trunk-math/Objects/complexobject.c	Wed Jan 30 14:42:22 2008
@@ -261,14 +261,19 @@
 		return ((PyComplexObject *)op)->cval;
 	}
 	/* If not, use op's __complex__  method, if it exists */
-	
+
 	/* return -1 on failure */
 	cv.real = -1.;
 	cv.imag = 0.;
+
+	if (complex_str == NULL) {
+		if (!(complex_str = PyString_InternFromString("__complex__")))
+			return cv;
+	}
 	
 	if (PyInstance_Check(op)) {
 		/* this can go away in python 3000 */
-		if (PyObject_HasAttrString(op, "__complex__")) {
+		if (PyObject_HasAttr(op, complex_str)) {
 			newop = PyObject_CallMethod(op, "__complex__", NULL);
 			if (!newop)
 				return cv;
@@ -276,10 +281,6 @@
 		/* else try __float__ */
 	} else {
 		PyObject *complexfunc;
-		if (!complex_str) {
-			if (!(complex_str = PyString_FromString("__complex__")))
-				return cv;
-		}
 		complexfunc = _PyType_Lookup(op->ob_type, complex_str);
 		/* complexfunc is a borrowed reference */
 		if (complexfunc) {

Modified: python/branches/trunk-math/Objects/fileobject.c
==============================================================================
--- python/branches/trunk-math/Objects/fileobject.c	(original)
+++ python/branches/trunk-math/Objects/fileobject.c	Wed Jan 30 14:42:22 2008
@@ -1965,7 +1965,7 @@
 	assert(type != NULL && type->tp_alloc != NULL);
 
 	if (not_yet_string == NULL) {
-		not_yet_string = PyString_FromString("<uninitialized file>");
+		not_yet_string = PyString_InternFromString("<uninitialized file>");
 		if (not_yet_string == NULL)
 			return NULL;
 	}

Modified: python/branches/trunk-math/Objects/floatobject.c
==============================================================================
--- python/branches/trunk-math/Objects/floatobject.c	(original)
+++ python/branches/trunk-math/Objects/floatobject.c	Wed Jan 30 14:42:22 2008
@@ -1153,6 +1153,163 @@
 	return v;
 }
 
+static PyObject *
+float_as_integer_ratio(PyObject *v)
+{
+	double self;
+	double float_part;
+	int exponent;
+	int is_negative;
+	const int chunk_size = 28;
+	PyObject *prev;
+	PyObject *py_chunk = NULL;
+	PyObject *py_exponent = NULL;
+	PyObject *numerator = NULL;
+	PyObject *denominator = NULL;
+	PyObject *result_pair = NULL;
+	PyNumberMethods *long_methods;
+
+#define INPLACE_UPDATE(obj, call) \
+	prev = obj; \
+	obj = call; \
+	Py_DECREF(prev); \
+
+	CONVERT_TO_DOUBLE(v, self);
+
+	if (Py_IS_INFINITY(self)) {
+	  PyErr_SetString(PyExc_OverflowError,
+			  "Cannot pass infinity to float.as_integer_ratio.");
+	  return NULL;
+	}
+#ifdef Py_NAN
+	if (Py_IS_NAN(self)) {
+	  PyErr_SetString(PyExc_ValueError,
+			  "Cannot pass nan to float.as_integer_ratio.");
+	  return NULL;
+	}
+#endif
+
+	if (self == 0) {
+		numerator = PyInt_FromLong(0);
+		if (numerator == NULL) goto error;
+		denominator = PyInt_FromLong(1);
+		if (denominator == NULL) goto error;
+		result_pair = PyTuple_Pack(2, numerator, denominator);
+		/* Hand ownership over to the tuple. If the tuple
+		   wasn't created successfully, we want to delete the
+		   ints anyway. */
+		Py_DECREF(numerator);
+		Py_DECREF(denominator);
+		return result_pair;
+	}
+
+	/* XXX: Could perhaps handle FLT_RADIX!=2 by using ilogb and
+	   scalbn, but those may not be in C89. */
+	PyFPE_START_PROTECT("as_integer_ratio", goto error);
+	float_part = frexp(self, &exponent);
+	is_negative = 0;
+	if (float_part < 0) {
+		float_part = -float_part;
+		is_negative = 1;
+		/* 0.5 <= float_part < 1.0 */
+	}
+	PyFPE_END_PROTECT(float_part);
+	/* abs(self) == float_part * 2**exponent exactly */
+
+	/* Suck up chunk_size bits at a time; 28 is enough so that we
+	   suck up all bits in 2 iterations for all known binary
+	   double-precision formats, and small enough to fit in a
+	   long. */
+	numerator = PyLong_FromLong(0);
+	if (numerator == NULL) goto error;
+
+	long_methods = PyLong_Type.tp_as_number;
+
+	py_chunk = PyLong_FromLong(chunk_size);
+	if (py_chunk == NULL) goto error;
+
+	while (float_part != 0) {
+		/* invariant: abs(self) ==
+		   (numerator + float_part) * 2**exponent exactly */
+		long digit;
+		PyObject *py_digit;
+
+		PyFPE_START_PROTECT("as_integer_ratio", goto error);
+		/* Pull chunk_size bits out of float_part, into digits. */
+		float_part = ldexp(float_part, chunk_size);
+		digit = (long)float_part;
+		float_part -= digit;
+                /* 0 <= float_part < 1 */
+		exponent -= chunk_size;
+		PyFPE_END_PROTECT(float_part);
+
+		/* Shift digits into numerator. */
+		// numerator <<= chunk_size
+		INPLACE_UPDATE(numerator,
+			       long_methods->nb_lshift(numerator, py_chunk));
+		if (numerator == NULL) goto error;
+
+		// numerator |= digit
+		py_digit = PyLong_FromLong(digit);
+		if (py_digit == NULL) goto error;
+		INPLACE_UPDATE(numerator,
+			       long_methods->nb_or(numerator, py_digit));
+		Py_DECREF(py_digit);
+		if (numerator == NULL) goto error;
+	}
+
+	/* Add in the sign bit. */
+	if (is_negative) {
+		INPLACE_UPDATE(numerator,
+			       long_methods->nb_negative(numerator));
+		if (numerator == NULL) goto error;
+	}
+
+	/* now self = numerator * 2**exponent exactly; fold in 2**exponent */
+	denominator = PyLong_FromLong(1);
+	py_exponent = PyLong_FromLong(labs(exponent));
+	if (py_exponent == NULL) goto error;
+	INPLACE_UPDATE(py_exponent,
+		       long_methods->nb_lshift(denominator, py_exponent));
+	if (py_exponent == NULL) goto error;
+	if (exponent > 0) {
+		INPLACE_UPDATE(numerator,
+			       long_methods->nb_multiply(numerator,
+							 py_exponent));
+		if (numerator == NULL) goto error;
+	}
+	else {
+		Py_DECREF(denominator);
+		denominator = py_exponent;
+		py_exponent = NULL;
+	}
+
+	result_pair = PyTuple_Pack(2, numerator, denominator);
+
+#undef INPLACE_UPDATE
+error:
+	Py_XDECREF(py_exponent);
+	Py_XDECREF(py_chunk);
+	Py_XDECREF(denominator);
+	Py_XDECREF(numerator);
+	return result_pair;
+}
+
+PyDoc_STRVAR(float_as_integer_ratio_doc,
+"float.as_integer_ratio() -> (int, int)\n"
+"\n"
+"Returns a pair of integers, not necessarily in lowest terms, whose\n"
+"ratio is exactly equal to the original float. This method raises an\n"
+"OverflowError on infinities and a ValueError on nans. The resulting\n"
+"denominator will be positive.\n"
+"\n"
+">>> (10.0).as_integer_ratio()\n"
+"(167772160L, 16777216L)\n"
+">>> (0.0).as_integer_ratio()\n"
+"(0, 1)\n"
+">>> (-.25).as_integer_ratio()\n"
+"(-134217728L, 536870912L)");
+
 
 static PyObject *
 float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
@@ -1341,6 +1498,8 @@
 	 "Returns self, the complex conjugate of any float."},
 	{"__trunc__",	(PyCFunction)float_trunc, METH_NOARGS,
          "Returns the Integral closest to x between 0 and x."},
+	{"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS,
+	 float_as_integer_ratio_doc},
 	{"__getnewargs__",	(PyCFunction)float_getnewargs,	METH_NOARGS},
 	{"__getformat__",	(PyCFunction)float_getformat,	
 	 METH_O|METH_CLASS,		float_getformat_doc},

Modified: python/branches/trunk-math/Objects/setobject.c
==============================================================================
--- python/branches/trunk-math/Objects/setobject.c	(original)
+++ python/branches/trunk-math/Objects/setobject.c	Wed Jan 30 14:42:22 2008
@@ -2142,17 +2142,7 @@
 PyObject *
 PyFrozenSet_New(PyObject *iterable)
 {
-	PyObject *args, *result;
-
-	if (iterable == NULL)
-		args = PyTuple_New(0);
-	else
-		args = PyTuple_Pack(1, iterable);
-	if (args == NULL)
-		return NULL;
-	result = frozenset_new(&PyFrozenSet_Type, args, NULL);
-	Py_DECREF(args);
-	return result;
+	return make_new_set(&PyFrozenSet_Type, iterable);
 }
 
 Py_ssize_t
@@ -2168,7 +2158,7 @@
 int
 PySet_Clear(PyObject *set)
 {
-	if (!PyType_IsSubtype(Py_TYPE(set), &PySet_Type)) {
+	if (!PySet_Check(set)) {
 		PyErr_BadInternalCall();
 		return -1;
 	}
@@ -2188,7 +2178,7 @@
 int
 PySet_Discard(PyObject *set, PyObject *key)
 {
-	if (!PyType_IsSubtype(Py_TYPE(set), &PySet_Type)) {
+	if (!PySet_Check(set)) {
 		PyErr_BadInternalCall();
 		return -1;
 	}
@@ -2196,13 +2186,13 @@
 }
 
 int
-PySet_Add(PyObject *set, PyObject *key)
+PySet_Add(PyObject *anyset, PyObject *key)
 {
-	if (!PyType_IsSubtype(Py_TYPE(set), &PySet_Type)) {
+	if (!PyAnySet_Check(anyset)) {
 		PyErr_BadInternalCall();
 		return -1;
 	}
-	return set_add_key((PySetObject *)set, key);
+	return set_add_key((PySetObject *)anyset, key);
 }
 
 int
@@ -2239,7 +2229,7 @@
 PyObject *
 PySet_Pop(PyObject *set)
 {
-	if (!PyType_IsSubtype(Py_TYPE(set), &PySet_Type)) {
+	if (!PySet_Check(set)) {
 		PyErr_BadInternalCall();
 		return NULL;
 	}
@@ -2249,7 +2239,7 @@
 int
 _PySet_Update(PyObject *set, PyObject *iterable)
 {
-	if (!PyType_IsSubtype(Py_TYPE(set), &PySet_Type)) {
+	if (!PySet_Check(set)) {
 		PyErr_BadInternalCall();
 		return -1;
 	}
@@ -2345,7 +2335,6 @@
 	f = PyFrozenSet_New(dup);
 	assert(PySet_Size(f) == 3);
 	assert(PyFrozenSet_CheckExact(f));
-	assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
 	assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
 	assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
 	Py_DECREF(f);

Modified: python/branches/trunk-math/Objects/typeobject.c
==============================================================================
--- python/branches/trunk-math/Objects/typeobject.c	(original)
+++ python/branches/trunk-math/Objects/typeobject.c	Wed Jan 30 14:42:22 2008
@@ -32,6 +32,24 @@
 
 static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP];
 static unsigned int next_version_tag = 0;
+static void type_modified(PyTypeObject *);
+
+unsigned int
+PyType_ClearCache(void)
+{
+	Py_ssize_t i;
+	unsigned int cur_version_tag = next_version_tag - 1;
+	
+	for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) {
+		method_cache[i].version = 0;
+		Py_CLEAR(method_cache[i].name);
+		method_cache[i].value = NULL;
+	}
+	next_version_tag = 0;
+	/* mark all version tags as invalid */
+	type_modified(&PyBaseObject_Type);
+	return cur_version_tag;
+}
 
 static void
 type_modified(PyTypeObject *type)

Modified: python/branches/trunk-math/Objects/unicodeobject.c
==============================================================================
--- python/branches/trunk-math/Objects/unicodeobject.c	(original)
+++ python/branches/trunk-math/Objects/unicodeobject.c	Wed Jan 30 14:42:22 2008
@@ -112,6 +112,64 @@
 */
 static char unicode_default_encoding[100];
 
+/* Fast detection of the most frequent whitespace characters */
+const unsigned char _Py_ascii_whitespace[] = {
+	0, 0, 0, 0, 0, 0, 0, 0,
+//     case 0x0009: /* HORIZONTAL TABULATION */
+//     case 0x000A: /* LINE FEED */
+//     case 0x000B: /* VERTICAL TABULATION */
+//     case 0x000C: /* FORM FEED */
+//     case 0x000D: /* CARRIAGE RETURN */
+	0, 1, 1, 1, 1, 1, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+//     case 0x001C: /* FILE SEPARATOR */
+//     case 0x001D: /* GROUP SEPARATOR */
+//     case 0x001E: /* RECORD SEPARATOR */
+//     case 0x001F: /* UNIT SEPARATOR */
+	0, 0, 0, 0, 1, 1, 1, 1,
+//     case 0x0020: /* SPACE */
+	1, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* Same for linebreaks */
+static unsigned char ascii_linebreak[] = {
+	0, 0, 0, 0, 0, 0, 0, 0,
+//         0x000A, /* LINE FEED */
+//         0x000D, /* CARRIAGE RETURN */
+	0, 0, 1, 0, 0, 1, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+//         0x001C, /* FILE SEPARATOR */
+//         0x001D, /* GROUP SEPARATOR */
+//         0x001E, /* RECORD SEPARATOR */
+	0, 0, 0, 0, 1, 1, 1, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0
+};
+
+
 Py_UNICODE
 PyUnicode_GetMax(void)
 {
@@ -138,8 +196,9 @@
 
 #define BLOOM(mask, ch) ((mask & (1 << ((ch) & 0x1F))))
 
-#define BLOOM_LINEBREAK(ch)\
-    (BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK((ch)))
+#define BLOOM_LINEBREAK(ch) \
+    ((ch) < 128U ? ascii_linebreak[(ch)] : \
+    (BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK(ch)))
 
 Py_LOCAL_INLINE(BLOOM_MASK) make_bloom_mask(Py_UNICODE* ptr, Py_ssize_t len)
 {
@@ -5505,25 +5564,26 @@
     register Py_ssize_t j;
     Py_ssize_t len = self->length;
     PyObject *str;
+    register const Py_UNICODE *buf = self->str;
 
     for (i = j = 0; i < len; ) {
 	/* find a token */
-	while (i < len && Py_UNICODE_ISSPACE(self->str[i]))
+	while (i < len && Py_UNICODE_ISSPACE(buf[i]))
 	    i++;
 	j = i;
-	while (i < len && !Py_UNICODE_ISSPACE(self->str[i]))
+	while (i < len && !Py_UNICODE_ISSPACE(buf[i]))
 	    i++;
 	if (j < i) {
 	    if (maxcount-- <= 0)
 		break;
-	    SPLIT_APPEND(self->str, j, i);
-	    while (i < len && Py_UNICODE_ISSPACE(self->str[i]))
+	    SPLIT_APPEND(buf, j, i);
+	    while (i < len && Py_UNICODE_ISSPACE(buf[i]))
 		i++;
 	    j = i;
 	}
     }
     if (j < len) {
-	SPLIT_APPEND(self->str, j, len);
+	SPLIT_APPEND(buf, j, len);
     }
     return list;
 
@@ -5596,18 +5656,19 @@
     register Py_ssize_t j;
     Py_ssize_t len = self->length;
     PyObject *str;
+    register const Py_UNICODE *buf = self->str;
 
     for (i = j = 0; i < len; ) {
-	if (self->str[i] == ch) {
+	if (buf[i] == ch) {
 	    if (maxcount-- <= 0)
 		break;
-	    SPLIT_APPEND(self->str, j, i);
+	    SPLIT_APPEND(buf, j, i);
 	    i = j = i + 1;
 	} else
 	    i++;
     }
     if (j <= len) {
-	SPLIT_APPEND(self->str, j, len);
+	SPLIT_APPEND(buf, j, len);
     }
     return list;
 
@@ -5656,25 +5717,26 @@
     register Py_ssize_t j;
     Py_ssize_t len = self->length;
     PyObject *str;
+    register const Py_UNICODE *buf = self->str;
 
     for (i = j = len - 1; i >= 0; ) {
 	/* find a token */
-	while (i >= 0 && Py_UNICODE_ISSPACE(self->str[i]))
+	while (i >= 0 && Py_UNICODE_ISSPACE(buf[i]))
 	    i--;
 	j = i;
-	while (i >= 0 && !Py_UNICODE_ISSPACE(self->str[i]))
+	while (i >= 0 && !Py_UNICODE_ISSPACE(buf[i]))
 	    i--;
 	if (j > i) {
 	    if (maxcount-- <= 0)
 		break;
-	    SPLIT_APPEND(self->str, i + 1, j + 1);
-	    while (i >= 0 && Py_UNICODE_ISSPACE(self->str[i]))
+	    SPLIT_APPEND(buf, i + 1, j + 1);
+	    while (i >= 0 && Py_UNICODE_ISSPACE(buf[i]))
 		i--;
 	    j = i;
 	}
     }
     if (j >= 0) {
-	SPLIT_APPEND(self->str, 0, j + 1);
+	SPLIT_APPEND(buf, 0, j + 1);
     }
     if (PyList_Reverse(list) < 0)
         goto onError;
@@ -5695,18 +5757,19 @@
     register Py_ssize_t j;
     Py_ssize_t len = self->length;
     PyObject *str;
+    register const Py_UNICODE *buf = self->str;
 
     for (i = j = len - 1; i >= 0; ) {
-	if (self->str[i] == ch) {
+	if (buf[i] == ch) {
 	    if (maxcount-- <= 0)
 		break;
-	    SPLIT_APPEND(self->str, i + 1, j + 1);
+	    SPLIT_APPEND(buf, i + 1, j + 1);
 	    j = i = i - 1;
 	} else
 	    i--;
     }
     if (j >= -1) {
-	SPLIT_APPEND(self->str, 0, j + 1);
+	SPLIT_APPEND(buf, 0, j + 1);
     }
     if (PyList_Reverse(list) < 0)
         goto onError;

Modified: python/branches/trunk-math/Python/bltinmodule.c
==============================================================================
--- python/branches/trunk-math/Python/bltinmodule.c	(original)
+++ python/branches/trunk-math/Python/bltinmodule.c	Wed Jan 30 14:42:22 2008
@@ -2050,7 +2050,7 @@
         /* XXX: The py3k branch gets better errors for this by using
            _PyType_Lookup(), but since float's mro isn't set in py2.6,
            we just use PyObject_CallMethod here. */
-	return PyObject_CallMethod(number, "__trunc__", "");
+	return PyObject_CallMethod(number, "__trunc__", NULL);
 }
 
 PyDoc_STRVAR(trunc_doc,

Modified: python/branches/trunk-math/Python/compile.c
==============================================================================
--- python/branches/trunk-math/Python/compile.c	(original)
+++ python/branches/trunk-math/Python/compile.c	Wed Jan 30 14:42:22 2008
@@ -1153,7 +1153,7 @@
 	int addNone = 1;
 	static PyObject *module;
 	if (!module) {
-		module = PyString_FromString("<module>");
+		module = PyString_InternFromString("<module>");
 		if (!module)
 			return NULL;
 	}
@@ -2001,7 +2001,7 @@
 	if (Py_OptimizeFlag)
 		return 1;
 	if (assertion_error == NULL) {
-		assertion_error = PyString_FromString("AssertionError");
+		assertion_error = PyString_InternFromString("AssertionError");
 		if (assertion_error == NULL)
 			return 0;
 	}

Modified: python/branches/trunk-math/Python/marshal.c
==============================================================================
--- python/branches/trunk-math/Python/marshal.c	(original)
+++ python/branches/trunk-math/Python/marshal.c	Wed Jan 30 14:42:22 2008
@@ -508,7 +508,7 @@
 {
 	/* NULL is a valid return value, it does not necessarily means that
 	   an exception is set. */
-	PyObject *v, *v2, *v3;
+	PyObject *v, *v2;
 	long i, n;
 	int type = r_byte(p);
 	PyObject *retval;
@@ -860,7 +860,7 @@
 			retval = NULL;
 			break;
 		}
-		v = PyTuple_New((int)n);
+                v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
 		if (v == NULL) {
 			retval = NULL;
 			break;
@@ -875,18 +875,14 @@
 				v = NULL;
 				break;
 			}
-			PyTuple_SET_ITEM(v, (int)i, v2);
+			if (PySet_Add(v, v2) == -1) {
+                                Py_DECREF(v);
+                                Py_DECREF(v2);
+                                v = NULL;
+                                break;
+                        }
 		}
-		if (v == NULL) {
-			retval = NULL;
-			break;
-		}
-		if (type == TYPE_SET)
-			v3 = PySet_New(v);
-		else
-			v3 = PyFrozenSet_New(v);
-		Py_DECREF(v);
-		retval = v3;
+		retval = v;
 		break;
 
 	case TYPE_CODE:

Modified: python/branches/trunk-math/Python/pythonrun.c
==============================================================================
--- python/branches/trunk-math/Python/pythonrun.c	(original)
+++ python/branches/trunk-math/Python/pythonrun.c	Wed Jan 30 14:42:22 2008
@@ -377,6 +377,9 @@
 	Py_XDECREF(warnings_module);
 	warnings_module = NULL;
 
+	/* Clear type lookup cache */
+	PyType_ClearCache();
+
 	/* Collect garbage.  This may call finalizers; it's nice to call these
 	 * before all modules are destroyed.
 	 * XXX If a __del__ or weakref callback is triggered here, and tries to

Modified: python/branches/trunk-math/Python/sysmodule.c
==============================================================================
--- python/branches/trunk-math/Python/sysmodule.c	(original)
+++ python/branches/trunk-math/Python/sysmodule.c	Wed Jan 30 14:42:22 2008
@@ -754,6 +754,17 @@
 10. Number of stack pops performed by call_function()"
 );
 
+static PyObject *
+sys_cleartypecache(PyObject* self, PyObject* args)
+{
+	PyType_ClearCache();
+	Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(cleartypecache_doc,
+"_cleartypecache() -> None\n\
+Clear the internal type lookup cache.");
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -776,6 +787,8 @@
 	/* Might as well keep this in alphabetic order */
 	{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
 	 callstats_doc},
+	{"_cleartypecache", sys_cleartypecache, METH_NOARGS,
+	 cleartypecache_doc},
 	{"_current_frames", sys_current_frames, METH_NOARGS,
 	 current_frames_doc},
 	{"displayhook",	sys_displayhook, METH_O, displayhook_doc},

Modified: python/branches/trunk-math/setup.py
==============================================================================
--- python/branches/trunk-math/setup.py	(original)
+++ python/branches/trunk-math/setup.py	Wed Jan 30 14:42:22 2008
@@ -681,7 +681,10 @@
         # a release.  Most open source OSes come with one or more
         # versions of BerkeleyDB already installed.
 
-        max_db_ver = (4, 6)
+        max_db_ver = (4, 5)  # XXX(gregory.p.smith): 4.6 "works" but seems to
+                             # have issues on many platforms.  I've temporarily
+                             # disabled 4.6 to see what the odd platform
+                             # buildbots say.
         min_db_ver = (3, 3)
         db_setup_debug = False   # verbose debug prints from this script?
 


More information about the Python-checkins mailing list