Merged revisions 60124-60142 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r60131 | georg.brandl | 2008-01-20 12:13:29 +0100 (Sun, 20 Jan 2008) | 3 lines

  #1351692: in pprint, always call format() for dict and list items to enable
  custom formatting of contents via subclassing PrettyPrinter.
........
  r60133 | georg.brandl | 2008-01-20 12:43:03 +0100 (Sun, 20 Jan 2008) | 2 lines

  #1178141: add addinfourl.code to get http status code from urllib.
........
  r60134 | georg.brandl | 2008-01-20 13:05:43 +0100 (Sun, 20 Jan 2008) | 4 lines

  #856047: respect the ``no_proxy`` env var when checking for proxies
  in urllib and using the other ``_proxy`` env vars.
  Original patch by Donovan Baarda.
........
  r60135 | georg.brandl | 2008-01-20 13:18:17 +0100 (Sun, 20 Jan 2008) | 4 lines

  #1664522: in urllib, don't read non-existing directories in ftp mode,
  returning a 0-byte file -- raise an IOError instead.
  Original patch from Phil Knirsch.
........
  r60136 | georg.brandl | 2008-01-20 13:57:47 +0100 (Sun, 20 Jan 2008) | 2 lines

  #799369: document possible sys.platform values.
........
  r60137 | georg.brandl | 2008-01-20 14:08:37 +0100 (Sun, 20 Jan 2008) | 2 lines

  #652749: document the constants added to the builtins by site.py.
........
  r60138 | georg.brandl | 2008-01-20 14:59:46 +0100 (Sun, 20 Jan 2008) | 2 lines

  #1648: add sys.gettrace() and sys.getprofile().
........
  r60139 | georg.brandl | 2008-01-20 15:17:42 +0100 (Sun, 20 Jan 2008) | 2 lines

  #1669: don't allow shutil.rmtree() to be called on a symlink.
........
  r60140 | georg.brandl | 2008-01-20 15:20:02 +0100 (Sun, 20 Jan 2008) | 2 lines

  Fix test_pyclbr after urllib change.
........
  r60141 | christian.heimes | 2008-01-20 15:28:28 +0100 (Sun, 20 Jan 2008) | 1 line

  Fixed a wrong assumption in configure.in and Include/pyport.h. The is finite function is not called isfinite() but finite(). Sorry, my fault. :)
........
  r60142 | georg.brandl | 2008-01-20 15:31:27 +0100 (Sun, 20 Jan 2008) | 2 lines

  #1876: fix typos in test_operator.
........
diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst
index 3870874..12b56f8 100644
--- a/Doc/library/constants.rst
+++ b/Doc/library/constants.rst
@@ -1,4 +1,3 @@
-
 Built-in Constants
 ==================
 
@@ -52,3 +51,28 @@
    This constant is true if Python was not started with an :option:`-O` option.
    Assignments to :const:`__debug__` are illegal and raise a :exc:`SyntaxError`.
    See also the :keyword:`assert` statement.
+
+
+Constants added by the :mod:`site` module
+-----------------------------------------
+
+The :mod:`site` module (which is imported automatically during startup, except
+if the :option:`-S` command-line option is given) adds several constants to the
+built-in namespace.  They are useful for the interactive interpreter shell and
+should not be used in programs.
+
+.. data:: quit([code=None])
+          exit([code=None])
+
+   Objects that when printed, print a message like "Use quit() or Ctrl-D
+   (i.e. EOF) to exit", and when called, raise :exc:`SystemExit` with the
+   specified exit code, and when .
+
+.. data:: copyright
+          license
+          credits
+
+   Objects that when printed, print a message like "Type license() to see the
+   full license text", and when called, display the corresponding text in a
+   pager-like fashion (one screen at a time).
+
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst
index 731afb4..08ab140 100644
--- a/Doc/library/functions.rst
+++ b/Doc/library/functions.rst
@@ -526,6 +526,8 @@
    topic, and a help page is printed on the console.  If the argument is any other
    kind of object, a help page on the object is generated.
 
+   This function is added to the built-in namespace by the :mod:`site` module.
+
 
 .. function:: hex(x)
 
diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst
index f80c893..db4a259 100644
--- a/Doc/library/shutil.rst
+++ b/Doc/library/shutil.rst
@@ -93,18 +93,24 @@
 
    .. index:: single: directory; deleting
 
-   Delete an entire directory tree (*path* must point to a directory). If
-   *ignore_errors* is true, errors resulting from failed removals will be ignored;
-   if false or omitted, such errors are handled by calling a handler specified by
-   *onerror* or, if that is omitted, they raise an exception.
+   Delete an entire directory tree; *path* must point to a directory (but not a
+   symbolic link to a directory).  If *ignore_errors* is true, errors resulting
+   from failed removals will be ignored; if false or omitted, such errors are
+   handled by calling a handler specified by *onerror* or, if that is omitted,
+   they raise an exception.
 
-   If *onerror* is provided, it must be a callable that accepts three parameters:
-   *function*, *path*, and *excinfo*. The first parameter, *function*, is the
-   function which raised the exception; it will be :func:`os.listdir`,
-   :func:`os.remove` or :func:`os.rmdir`.  The second parameter, *path*, will be
-   the path name passed to *function*.  The third parameter, *excinfo*, will be the
-   exception information return by :func:`sys.exc_info`.  Exceptions raised by
-   *onerror* will not be caught.
+   If *onerror* is provided, it must be a callable that accepts three
+   parameters: *function*, *path*, and *excinfo*. The first parameter,
+   *function*, is the function which raised the exception; it will be
+   :func:`os.path.islink`, :func:`os.listdir`, :func:`os.remove` or
+   :func:`os.rmdir`.  The second parameter, *path*, will be the path name passed
+   to *function*.  The third parameter, *excinfo*, will be the exception
+   information return by :func:`sys.exc_info`.  Exceptions raised by *onerror*
+   will not be caught.
+
+   .. versionchanged:: 2.6
+      Explicitly check for *path* being a symbolic link and raise :exc:`OSError`
+      in that case.
 
 
 .. function:: move(src, dst)
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index 6d1a09b..5718f7b 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -326,6 +326,35 @@
    This function should be used for internal and specialized purposes only.
 
 
+.. function:: getprofile()
+
+   .. index::
+      single: profile function
+      single: profiler
+
+   Get the profiler function as set by :func:`setprofile`.
+
+   .. versionadded:: 2.6
+
+
+.. function:: gettrace()
+
+   .. index::
+      single: trace function
+      single: debugger
+
+   Get the trace function as set by :func:`settrace`.
+
+   .. note::
+
+      The :func:`gettrace` function is intended only for implementing debuggers,
+      profilers, coverage tools and the like. Its behavior is part of the
+      implementation platform, rather than part of the language definition,
+      and thus may not be available in all Python implementations.
+
+   .. versionadded:: 2.6
+
+
 .. function:: getwindowsversion()
 
    Return a tuple containing five components, describing the Windows version
@@ -444,9 +473,26 @@
 
 .. data:: platform
 
-   This string contains a platform identifier, e.g. ``'sunos5'`` or ``'linux1'``.
-   This can be used to append platform-specific components to ``path``, for
-   instance.
+   This string contains a platform identifier that can be used to append
+   platform-specific components to :data:`sys.path`, for instance.
+
+   For Unix systems, this is the lowercased OS name as returned by ``uname -s``
+   with the first part of the version as returned by ``uname -r`` appended,
+   e.g. ``'sunos5'`` or ``'linux2'``, *at the time when Python was built*.
+   For other systems, the values are:
+
+   ================ ===========================
+   System           :data:`platform` value
+   ================ ===========================
+   Windows          ``'win32'``
+   Windows/Cygwin   ``'cygwin'``
+   MacOS X          ``'darwin'``
+   MacOS 9          ``'mac'``
+   OS/2             ``'os2'``
+   OS/2 EMX         ``'os2emx'``
+   RiscOS           ``'riscos'``
+   AtheOS           ``'atheos'``
+   ================ ===========================
 
 
 .. data:: prefix
diff --git a/Doc/library/urllib.rst b/Doc/library/urllib.rst
index 4b86e88..63fb53e 100644
--- a/Doc/library/urllib.rst
+++ b/Doc/library/urllib.rst
@@ -27,16 +27,17 @@
    a server somewhere on the network.  If the connection cannot be made the
    :exc:`IOError` exception is raised.  If all went well, a file-like object is
    returned.  This supports the following methods: :meth:`read`, :meth:`readline`,
-   :meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info` and
+   :meth:`readlines`, :meth:`fileno`, :meth:`close`, :meth:`info`, :meth:`getcode` and
    :meth:`geturl`.  It also has proper support for the :term:`iterator` protocol. One
    caveat: the :meth:`read` method, if the size argument is omitted or negative,
    may not read until the end of the data stream; there is no good way to determine
    that the entire stream from a socket has been read in the general case.
 
-   Except for the :meth:`info` and :meth:`geturl` methods, these methods have the
-   same interface as for file objects --- see section :ref:`bltin-file-objects` in
-   this manual.  (It is not a built-in file object, however, so it can't be used at
-   those few places where a true built-in file object is required.)
+   Except for the :meth:`info`, :meth:`getcode` and :meth:`geturl` methods,
+   these methods have the same interface as for file objects --- see section
+   :ref:`bltin-file-objects` in this manual.  (It is not a built-in file object,
+   however, so it can't be used at those few places where a true built-in file
+   object is required.)
 
    .. index:: module: mimetools
 
@@ -58,6 +59,9 @@
    the client was redirected to.  The :meth:`geturl` method can be used to get at
    this redirected URL.
 
+   The :meth:`getcode` method returns the HTTP status code that was sent with the
+   response, or ``None`` if the URL is no HTTP URL.
+
    If the *url* uses the :file:`http:` scheme identifier, the optional *data*
    argument may be given to specify a ``POST`` request (normally the request type
    is ``GET``).  The *data* argument must be in standard
@@ -75,6 +79,11 @@
       % python
       ...
 
+   The :envvar:`no_proxy` environment variable can be used to specify hosts which
+   shouldn't be reached via proxy; if set, it should be a comma-separated list
+   of hostname suffixes, optionally with ``:port`` appended, for example
+   ``cern.ch,ncsa.uiuc.edu,some.host:8080``.
+
    In a Windows environment, if no proxy environment variables are set, proxy
    settings are obtained from the registry's Internet Settings section.
 
diff --git a/Include/pyport.h b/Include/pyport.h
index e4da8f4..cfc2961 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -388,8 +388,8 @@
  * macro for this particular test is useful
  */
 #ifndef Py_IS_FINITE
-#ifdef HAVE_ISFINITE
-#define Py_IS_FINITE(X) isfinite
+#ifdef HAVE_FINITE
+#define Py_IS_FINITE(X) finite
 #else
 #define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X))
 #endif
diff --git a/Lib/shutil.py b/Lib/shutil.py
index f3d6fa9..c365ad6 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -156,6 +156,14 @@
     elif onerror is None:
         def onerror(*args):
             raise
+    try:
+        if os.path.islink(path):
+            # symlinks to directories are forbidden, see bug #1669
+            raise OSError("Cannot call rmtree on a symbolic link")
+    except OSError:
+        onerror(os.path.islink, path, sys.exc_info())
+        # can't continue even if onerror hook returns
+        return
     names = []
     try:
         names = os.listdir(path)
diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py
index 57f3846..dbb8f9e 100644
--- a/Lib/test/test_operator.py
+++ b/Lib/test/test_operator.py
@@ -364,9 +364,9 @@
         self.assertRaises(TypeError, operator.attrgetter('x', (), 'y'), record)
 
         class C(object):
-            def __getattr(self, name):
+            def __getattr__(self, name):
                 raise SyntaxError
-        self.failUnlessRaises(AttributeError, operator.attrgetter('foo'), C())
+        self.failUnlessRaises(SyntaxError, operator.attrgetter('foo'), C())
 
     def test_itemgetter(self):
         a = 'ABCDE'
@@ -376,9 +376,9 @@
         self.assertRaises(IndexError, f, a)
 
         class C(object):
-            def __getitem(self, name):
+            def __getitem__(self, name):
                 raise SyntaxError
-        self.failUnlessRaises(TypeError, operator.itemgetter(42), C())
+        self.failUnlessRaises(SyntaxError, operator.itemgetter(42), C())
 
         f = operator.itemgetter('name')
         self.assertRaises(TypeError, f, a)
diff --git a/Lib/test/test_profilehooks.py b/Lib/test/test_profilehooks.py
index 3a17dc7..6d6aa8e 100644
--- a/Lib/test/test_profilehooks.py
+++ b/Lib/test/test_profilehooks.py
@@ -4,6 +4,22 @@
 
 from test import test_support
 
+class TestGetProfile(unittest.TestCase):
+    def setUp(self):
+        sys.setprofile(None)
+
+    def tearDown(self):
+        sys.setprofile(None)
+
+    def test_empty(self):
+        assert sys.getprofile() == None
+
+    def test_setget(self):
+        def fn(*args):
+            pass
+
+        sys.setprofile(fn)
+        assert sys.getprofile() == fn
 
 class HookWatcher:
     def __init__(self):
@@ -359,6 +375,7 @@
 
 def test_main():
     test_support.run_unittest(
+        TestGetProfile,
         ProfileHookTestCase,
         ProfileSimulatorTestCase
     )
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index 5d46db1..f041823 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -158,6 +158,7 @@
         cm('cgi', ignore=('log',))      # set with = in module
         cm('mhlib')
         cm('urllib', ignore=('getproxies_registry',
+                             'proxy_bypass_registry',
                              'open_https',
                              '_https_connection',
                              'getproxies_internetconfig',)) # not on all platforms
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index ee15d0e..b63031e 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -149,6 +149,20 @@
                 except OSError:
                     pass
 
+        def test_rmtree_on_symlink(self):
+            # bug 1669.
+            os.mkdir(TESTFN)
+            try:
+                src = os.path.join(TESTFN, 'cheese')
+                dst = os.path.join(TESTFN, 'shop')
+                os.mkdir(src)
+                os.symlink(src, dst)
+                self.assertRaises(OSError, shutil.rmtree, dst)
+            finally:
+                shutil.rmtree(TESTFN, ignore_errors=True)
+
+
+
 def test_main():
     test_support.run_unittest(TestShutil)
 
diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py
index 3ec00d2..a0f76c6 100644
--- a/Lib/test/test_trace.py
+++ b/Lib/test/test_trace.py
@@ -268,6 +268,20 @@
         self.compare_events(func.__code__.co_firstlineno,
                             tracer.events, func.events)
 
+    def set_and_retrieve_none(self):
+        sys.settrace(None)
+        assert sys.gettrace() is None
+
+    def set_and_retrieve_func(self):
+        def fn(*args):
+            pass
+
+        sys.settrace(fn)
+        try:
+            assert sys.gettrace() is fn
+        finally:
+            sys.settrace(None)
+
     def test_01_basic(self):
         self.run_test(basic)
     def test_02_arigo(self):
diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
index a87ab71..c233e35 100644
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -47,7 +47,7 @@
     def test_interface(self):
         # Make sure object returned by urlopen() has the specified methods
         for attr in ("read", "readline", "readlines", "fileno",
-                     "close", "info", "geturl", "__iter__"):
+                     "close", "info", "geturl", "getcode", "__iter__"):
             self.assert_(hasattr(self.returned_obj, attr),
                          "object returned by urlopen() lacks %s attribute" %
                          attr)
@@ -87,6 +87,9 @@
     def test_geturl(self):
         self.assertEqual(self.returned_obj.geturl(), self.pathname)
 
+    def test_getcode(self):
+        self.assertEqual(self.returned_obj.getcode(), None)
+
     def test_iter(self):
         # Test iterator
         # Don't need to count number of iterations since test would fail the
@@ -123,6 +126,8 @@
             fp = urllib.urlopen("http://python.org/")
             self.assertEqual(fp.readline(), b"Hello!")
             self.assertEqual(fp.readline(), b"")
+            self.assertEqual(fp.geturl(), 'http://python.org/')
+            self.assertEqual(fp.getcode(), 200)
         finally:
             self.unfakehttp()
 
diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py
index ebd9d2d..a7d3805 100644
--- a/Lib/test/test_urllibnet.py
+++ b/Lib/test/test_urllibnet.py
@@ -83,6 +83,16 @@
             open_url.close()
         self.assertEqual(gotten_url, URL)
 
+    def test_getcode(self):
+        # test getcode() with the fancy opener to get 404 error codes
+        URL = "http://www.python.org/XXXinvalidXXX"
+        open_url = urllib.FancyURLopener().open(URL)
+        try:
+            code = open_url.getcode()
+        finally:
+            open_url.close()
+        self.assertEqual(code, 404)
+
     def test_fileno(self):
         if (sys.platform in ('win32',) or
                 not hasattr(os, 'fdopen')):
diff --git a/Lib/urllib.py b/Lib/urllib.py
index 1b1fc40..f9c8ec0 100644
--- a/Lib/urllib.py
+++ b/Lib/urllib.py
@@ -557,7 +557,7 @@
 
     def http_error_default(self, url, fp, errcode, errmsg, headers):
         """Default error handling -- don't raise an exception."""
-        return addinfourl(fp, headers, "http:" + url)
+        return addinfourl(fp, headers, "http:" + url, errcode)
 
     def http_error_302(self, url, fp, errcode, errmsg, headers, data=None):
         """Error 302 -- relocated (temporarily)."""
@@ -815,9 +815,19 @@
         if not conn:
             # Set transfer mode to ASCII!
             self.ftp.voidcmd('TYPE A')
-            # Try a directory listing
-            if file: cmd = 'LIST ' + file
-            else: cmd = 'LIST'
+            # Try a directory listing. Verify that directory exists.
+            if file:
+                pwd = self.ftp.pwd()
+                try:
+                    try:
+                        self.ftp.cwd(file)
+                    except ftplib.error_perm as reason:
+                        raise IOError('ftp error', reason) from reason
+                finally:
+                    self.ftp.cwd(pwd)
+                cmd = 'LIST ' + file
+            else:
+                cmd = 'LIST'
             conn = self.ftp.ntransfercmd(cmd)
         self.busy = 1
         # Pass back both a suitably decorated object and a retrieval length
@@ -898,14 +908,18 @@
 class addinfourl(addbase):
     """class to add info() and geturl() methods to an open file."""
 
-    def __init__(self, fp, headers, url):
+    def __init__(self, fp, headers, url, code=None):
         addbase.__init__(self, fp)
         self.headers = headers
         self.url = url
+        self.code = code
 
     def info(self):
         return self.headers
 
+    def getcode(self):
+        return self.code
+
     def geturl(self):
         return self.url
 
@@ -1228,10 +1242,33 @@
     proxies = {}
     for name, value in os.environ.items():
         name = name.lower()
+        if name == 'no_proxy':
+            # handled in proxy_bypass_environment
+            continue
         if value and name[-6:] == '_proxy':
             proxies[name[:-6]] = value
     return proxies
 
+def proxy_bypass_environment(host):
+    """Test if proxies should not be used for a particular host.
+
+    Checks the environment for a variable named no_proxy, which should
+    be a list of DNS suffixes separated by commas, or '*' for all hosts.
+    """
+    no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '')
+    # '*' is special case for always bypass
+    if no_proxy == '*':
+        return 1
+    # strip port off host
+    hostonly, port = splitport(host)
+    # check if the host ends with any of the DNS suffixes
+    for name in no_proxy.split(','):
+        if name and (hostonly.endswith(name) or host.endswith(name)):
+            return 1
+    # otherwise, don't bypass
+    return 0
+
+
 if sys.platform == 'darwin':
     def getproxies_internetconfig():
         """Return a dictionary of scheme -> proxy server URL mappings.
@@ -1259,12 +1296,15 @@
                 pass
             else:
                 proxies['http'] = 'http://%s' % value
-        # FTP: XXXX To be done.
-        # Gopher: XXXX To be done.
+        # FTP: XXX To be done.
+        # Gopher: XXX To be done.
         return proxies
 
-    def proxy_bypass(x):
-        return 0
+    def proxy_bypass(host):
+        if getproxies_environment():
+            return proxy_bypass_environment(host)
+        else:
+            return 0
 
     def getproxies():
         return getproxies_environment() or getproxies_internetconfig()
@@ -1324,7 +1364,7 @@
         """
         return getproxies_environment() or getproxies_registry()
 
-    def proxy_bypass(host):
+    def proxy_bypass_registry(host):
         try:
             import _winreg
             import re
@@ -1383,12 +1423,22 @@
                     return 1
         return 0
 
+    def proxy_bypass(host):
+        """Return a dictionary of scheme -> proxy server URL mappings.
+
+        Returns settings gathered from the environment, if specified,
+        or the registry.
+
+        """
+        if getproxies_environment():
+            return proxy_bypass_environment(host)
+        else:
+            return proxy_bypass_registry(host)
+
 else:
     # By default use environment variables
     getproxies = getproxies_environment
-
-    def proxy_bypass(host):
-        return 0
+    proxy_bypass = proxy_bypass_environment
 
 # Test and time quote() and unquote()
 def test1():
diff --git a/Python/hypot.c b/Python/hypot.c
index 9d3c0d0..a18ce16 100644
--- a/Python/hypot.c
+++ b/Python/hypot.c
@@ -2,6 +2,7 @@
 
 #include "Python.h"
 
+#ifndef HAVE_HYPOT
 double hypot(double x, double y)
 {
 	double yx;
@@ -20,3 +21,5 @@
 		return x*sqrt(1.+yx*yx);
 	}
 }
+#endif /* HAVE_HYPOT */
+
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index ae06c30..499f328 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -374,6 +374,25 @@
 );
 
 static PyObject *
+sys_gettrace(PyObject *self, PyObject *args)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *temp = tstate->c_traceobj;
+
+	if (temp == NULL)
+		temp = Py_None;
+	Py_INCREF(temp);
+	return temp;
+}
+
+PyDoc_STRVAR(gettrace_doc,
+"gettrace()\n\
+\n\
+Return the global debug tracing function set with sys.settrace.\n\
+See the debugger chapter in the library manual."
+);
+
+static PyObject *
 sys_setprofile(PyObject *self, PyObject *args)
 {
 	if (trace_init() == -1)
@@ -394,6 +413,25 @@
 );
 
 static PyObject *
+sys_getprofile(PyObject *self, PyObject *args)
+{
+	PyThreadState *tstate = PyThreadState_GET();
+	PyObject *temp = tstate->c_profileobj;
+
+	if (temp == NULL)
+		temp = Py_None;
+	Py_INCREF(temp);
+	return temp;
+}
+
+PyDoc_STRVAR(getprofile_doc,
+"getprofile()\n\
+\n\
+Return the profiling function set with sys.setprofile.\n\
+See the profiler chapter in the library manual."
+);
+
+static PyObject *
 sys_setcheckinterval(PyObject *self, PyObject *args)
 {
 	if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval))
@@ -763,12 +801,14 @@
 	 setdlopenflags_doc},
 #endif
 	{"setprofile",	sys_setprofile, METH_O, setprofile_doc},
+	{"getprofile",	sys_getprofile, METH_NOARGS, getprofile_doc},
 	{"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS,
 	 setrecursionlimit_doc},
 #ifdef WITH_TSC
 	{"settscdump", sys_settscdump, METH_VARARGS, settscdump_doc},
 #endif
 	{"settrace",	sys_settrace, METH_O, settrace_doc},
+	{"gettrace",	sys_gettrace, METH_NOARGS, gettrace_doc},
 	{"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc},
 	{NULL,		NULL}		/* sentinel */
 };
@@ -903,8 +943,10 @@
 exc_info() -- return thread-safe information about the current exception\n\
 exit() -- exit the interpreter by raising SystemExit\n\
 getdlopenflags() -- returns flags to be used for dlopen() calls\n\
+getprofile() -- get the global profiling function\n\
 getrefcount() -- return the reference count for an object (plus one :-)\n\
 getrecursionlimit() -- return the max recursion depth for the interpreter\n\
+gettrace() -- get the global debug tracing function\n\
 setcheckinterval() -- control how often the interpreter checks for events\n\
 setdlopenflags() -- set the flags to be used for dlopen() calls\n\
 setprofile() -- set the global profiling function\n\
diff --git a/configure b/configure
index 02f5f73..e530f5c 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 59826 .
+# From configure.in Revision: 59829 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.61 for python 3.0.
 #
@@ -20584,7 +20584,6 @@
 # ************************************
 # * Check for mathematical functions *
 # ************************************
-# check for hypot() in math library
 LIBS_SAVE=$LIBS
 LIBS="$LIBS $LIBM"
 
@@ -20694,7 +20693,12 @@
 
 
 
-for ac_func in copysign isfinite isnan isinf
+
+
+
+
+
+for ac_func in acosh asinh atanh copysign expm1 finite isinf isnan log1p
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { echo "$as_me:$LINENO: checking for $ac_func" >&5
diff --git a/configure.in b/configure.in
index fe52c4b..41e27a7 100644
--- a/configure.in
+++ b/configure.in
@@ -2948,12 +2948,11 @@
 # ************************************
 # * Check for mathematical functions *
 # ************************************
-# check for hypot() in math library
 LIBS_SAVE=$LIBS
 LIBS="$LIBS $LIBM"
 AC_REPLACE_FUNCS(hypot)
 
-AC_CHECK_FUNCS(copysign isfinite isnan isinf)
+AC_CHECK_FUNCS(acosh asinh atanh copysign expm1 finite isinf isnan log1p)
 
 LIBS=$LIBS_SAVE
 
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 41dd943..4eff113 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -25,6 +25,9 @@
    the case on Motorola V4 (R40V4.2) */
 #undef GETTIMEOFDAY_NO_TZ
 
+/* Define to 1 if you have the `acosh' function. */
+#undef HAVE_ACOSH
+
 /* struct addrinfo (netdb.h) */
 #undef HAVE_ADDRINFO
 
@@ -34,9 +37,15 @@
 /* Define this if your time.h defines altzone. */
 #undef HAVE_ALTZONE
 
+/* Define to 1 if you have the `asinh' function. */
+#undef HAVE_ASINH
+
 /* Define to 1 if you have the <asm/types.h> header file. */
 #undef HAVE_ASM_TYPES_H
 
+/* Define to 1 if you have the `atanh' function. */
+#undef HAVE_ATANH
+
 /* Define if GCC supports __attribute__((format(PyArg_ParseTuple, 2, 3))) */
 #undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE
 
@@ -141,6 +150,9 @@
 /* Define to 1 if you have the `execv' function. */
 #undef HAVE_EXECV
 
+/* Define to 1 if you have the `expm1' function. */
+#undef HAVE_EXPM1
+
 /* Define if you have the 'fchdir' function. */
 #undef HAVE_FCHDIR
 
@@ -156,6 +168,9 @@
 /* Define if you have the 'fdatasync' function. */
 #undef HAVE_FDATASYNC
 
+/* Define to 1 if you have the `finite' function. */
+#undef HAVE_FINITE
+
 /* Define if you have the 'flock' function. */
 #undef HAVE_FLOCK
 
@@ -288,9 +303,6 @@
 /* Define to 1 if you have the <io.h> header file. */
 #undef HAVE_IO_H
 
-/* Define to 1 if you have the `isfinite' function. */
-#undef HAVE_ISFINITE
-
 /* Define to 1 if you have the `isinf' function. */
 #undef HAVE_ISINF
 
@@ -354,6 +366,9 @@
 /* Define to 1 if you have the <linux/tipc.h> header file. */
 #undef HAVE_LINUX_TIPC_H
 
+/* Define to 1 if you have the `log1p' function. */
+#undef HAVE_LOG1P
+
 /* Define this if you have the type long double. */
 #undef HAVE_LONG_DOUBLE