Merge 3.2.1 release clone changes into main 3.2 branch after 3.2.1rc2 release.
diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst
index 7367674..32ae724 100644
--- a/Doc/library/sqlite3.rst
+++ b/Doc/library/sqlite3.rst
@@ -599,43 +599,43 @@
 
 Let's assume we initialize a table as in the example given above::
 
-    conn = sqlite3.connect(":memory:")
-    c = conn.cursor()
-    c.execute('''create table stocks
-    (date text, trans text, symbol text,
-     qty real, price real)''')
-    c.execute("""insert into stocks
-              values ('2006-01-05','BUY','RHAT',100,35.14)""")
-    conn.commit()
-    c.close()
+   conn = sqlite3.connect(":memory:")
+   c = conn.cursor()
+   c.execute('''create table stocks
+   (date text, trans text, symbol text,
+    qty real, price real)''')
+   c.execute("""insert into stocks
+             values ('2006-01-05','BUY','RHAT',100,35.14)""")
+   conn.commit()
+   c.close()
 
 Now we plug :class:`Row` in::
 
-    >>> conn.row_factory = sqlite3.Row
-    >>> c = conn.cursor()
-    >>> c.execute('select * from stocks')
-    <sqlite3.Cursor object at 0x7f4e7dd8fa80>
-    >>> r = c.fetchone()
-    >>> type(r)
-    <class 'sqlite3.Row'>
-    >>> tuple(r)
-    ('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14)
-    >>> len(r)
-    5
-    >>> r[2]
-    'RHAT'
-    >>> r.keys()
-    ['date', 'trans', 'symbol', 'qty', 'price']
-    >>> r['qty']
-    100.0
-    >>> for member in r:
-    ...     print(member)
-    ...
-    2006-01-05
-    BUY
-    RHAT
-    100.0
-    35.14
+   >>> conn.row_factory = sqlite3.Row
+   >>> c = conn.cursor()
+   >>> c.execute('select * from stocks')
+   <sqlite3.Cursor object at 0x7f4e7dd8fa80>
+   >>> r = c.fetchone()
+   >>> type(r)
+   <class 'sqlite3.Row'>
+   >>> tuple(r)
+   ('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14)
+   >>> len(r)
+   5
+   >>> r[2]
+   'RHAT'
+   >>> r.keys()
+   ['date', 'trans', 'symbol', 'qty', 'price']
+   >>> r['qty']
+   100.0
+   >>> for member in r:
+   ...     print(member)
+   ...
+   2006-01-05
+   BUY
+   RHAT
+   100.0
+   35.14
 
 
 .. _sqlite3-types:
@@ -886,6 +886,7 @@
 .. rubric:: Footnotes
 
 .. [#f1] The sqlite3 module is not built with loadable extension support by
-  default, because some platforms (notably Mac OS X) have SQLite libraries which
-  are compiled without this feature. To get loadable extension support, you must
-  pass --enable-loadable-sqlite-extensions to configure.
+   default, because some platforms (notably Mac OS X) have SQLite
+   libraries which are compiled without this feature. To get loadable
+   extension support, you must pass --enable-loadable-sqlite-extensions to
+   configure.
diff --git a/Lib/glob.py b/Lib/glob.py
index c5f5f69..36d493d 100644
--- a/Lib/glob.py
+++ b/Lib/glob.py
@@ -1,6 +1,5 @@
 """Filename globbing utility."""
 
-import sys
 import os
 import re
 import fnmatch
diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py
index 06c8bba..834805e 100644
--- a/Lib/idlelib/PyShell.py
+++ b/Lib/idlelib/PyShell.py
@@ -59,7 +59,7 @@
             file = warning_stream
         try:
             file.write(warnings.formatwarning(message, category, filename,
-                                              lineno, file=file, line=line))
+                                              lineno, line=line))
         except IOError:
             pass  ## file (probably __stderr__) is invalid, warning dropped.
     warnings.showwarning = idle_showwarning
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 1619446..2533226 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -256,20 +256,18 @@
 def importfile(path):
     """Import a Python source file or compiled file given its path."""
     magic = imp.get_magic()
-    file = open(path, 'r')
-    if file.read(len(magic)) == magic:
-        kind = imp.PY_COMPILED
-    else:
-        kind = imp.PY_SOURCE
-    file.close()
-    filename = os.path.basename(path)
-    name, ext = os.path.splitext(filename)
-    file = open(path, 'r')
-    try:
-        module = imp.load_module(name, file, path, (ext, 'r', kind))
-    except:
-        raise ErrorDuringImport(path, sys.exc_info())
-    file.close()
+    with open(path, 'rb') as file:
+        if file.read(len(magic)) == magic:
+            kind = imp.PY_COMPILED
+        else:
+            kind = imp.PY_SOURCE
+        file.seek(0)
+        filename = os.path.basename(path)
+        name, ext = os.path.splitext(filename)
+        try:
+            module = imp.load_module(name, file, path, (ext, 'r', kind))
+        except:
+            raise ErrorDuringImport(path, sys.exc_info())
     return module
 
 def safeimport(path, forceload=0, cache={}):
diff --git a/Lib/runpy.py b/Lib/runpy.py
index 4738df3..31e5e55 100644
--- a/Lib/runpy.py
+++ b/Lib/runpy.py
@@ -226,7 +226,7 @@
         code = read_code(f)
     if code is None:
         # That didn't work, so try it as normal source code
-        with open(fname, "rU") as f:
+        with open(fname, "rb") as f:
             code = compile(f.read(), fname, 'exec')
     return code
 
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 76f4249..46ddc82 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -566,6 +566,33 @@
             del g
             self.assertEqual(sys.exc_info()[0], TypeError)
 
+    def test_generator_leaking2(self):
+        # See issue 12475.
+        def g():
+            yield
+        try:
+            raise RuntimeError
+        except RuntimeError:
+            it = g()
+            next(it)
+        try:
+            next(it)
+        except StopIteration:
+            pass
+        self.assertEqual(sys.exc_info(), (None, None, None))
+
+    def test_generator_doesnt_retain_old_exc(self):
+        def g():
+            self.assertIsInstance(sys.exc_info()[1], RuntimeError)
+            yield
+            self.assertEqual(sys.exc_info(), (None, None, None))
+        it = g()
+        try:
+            raise RuntimeError
+        except RuntimeError:
+            next(it)
+        self.assertRaises(StopIteration, next, it)
+
     def test_generator_finalizing_and_exc_info(self):
         # See #7173
         def simple_gen():
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 707b7cb..cfd4583 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -2651,6 +2651,8 @@
         1/0
 
     @unittest.skipUnless(threading, 'Threading required for this test.')
+    @unittest.skipIf(sys.platform in ('freebsd5', 'freebsd6', 'freebsd7'),
+                     'issue #12429: skip test on FreeBSD <= 7')
     def check_interrupted_write(self, item, bytes, **fdopen_kwargs):
         """Check that a partial write, when it gets interrupted, properly
         invokes the signal handler, and bubbles up the exception raised
diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py
index ad3ab39..7ffb6af 100644
--- a/Lib/test/test_runpy.py
+++ b/Lib/test/test_runpy.py
@@ -405,6 +405,16 @@
             msg = "recursion depth exceeded"
             self.assertRaisesRegex(RuntimeError, msg, run_path, zip_name)
 
+    def test_encoding(self):
+        with temp_dir() as script_dir:
+            filename = os.path.join(script_dir, 'script.py')
+            with open(filename, 'w', encoding='latin1') as f:
+                f.write("""
+#coding:latin1
+"non-ASCII: h\xe9"
+""")
+            result = run_path(filename)
+            self.assertEqual(result['__doc__'], "non-ASCII: h\xe9")
 
 
 def test_main():
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index 475a26b..e2310e2 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -427,7 +427,7 @@
         self.assertEqual(os.stat(file1).st_mode, os.stat(file2).st_mode)
 
     @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod')
-    @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.utime')
+    @unittest.skipUnless(hasattr(os, 'utime'), 'requires os.utime')
     def test_copy2(self):
         # Ensure that the copied file exists and has the same mode and
         # modification time bits.
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index ede6545..8df1bf0 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -11,7 +11,7 @@
 import unittest
 from test import support
 from contextlib import closing
-from test.script_helper import spawn_python
+from test.script_helper import assert_python_ok, spawn_python
 
 if sys.platform in ('os2', 'riscos'):
     raise unittest.SkipTest("Can't test signal on %s" % sys.platform)
@@ -233,49 +233,80 @@
 
 @unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
 class WakeupSignalTests(unittest.TestCase):
-    TIMEOUT_FULL = 10
-    TIMEOUT_HALF = 5
+    def check_wakeup(self, test_body):
+        # use a subprocess to have only one thread and to not change signal
+        # handling of the parent process
+        code = """if 1:
+        import fcntl
+        import os
+        import signal
+
+        def handler(signum, frame):
+            pass
+
+        {}
+
+        signal.signal(signal.SIGALRM, handler)
+        read, write = os.pipe()
+        flags = fcntl.fcntl(write, fcntl.F_GETFL, 0)
+        flags = flags | os.O_NONBLOCK
+        fcntl.fcntl(write, fcntl.F_SETFL, flags)
+        signal.set_wakeup_fd(write)
+
+        test()
+
+        os.close(read)
+        os.close(write)
+        """.format(test_body)
+
+        assert_python_ok('-c', code)
 
     def test_wakeup_fd_early(self):
-        import select
+        self.check_wakeup("""def test():
+            import select
+            import time
 
-        signal.alarm(1)
-        before_time = time.time()
-        # We attempt to get a signal during the sleep,
-        # before select is called
-        time.sleep(self.TIMEOUT_FULL)
-        mid_time = time.time()
-        self.assertTrue(mid_time - before_time < self.TIMEOUT_HALF)
-        select.select([self.read], [], [], self.TIMEOUT_FULL)
-        after_time = time.time()
-        self.assertTrue(after_time - mid_time < self.TIMEOUT_HALF)
+            TIMEOUT_FULL = 10
+            TIMEOUT_HALF = 5
+
+            signal.alarm(1)
+            before_time = time.time()
+            # We attempt to get a signal during the sleep,
+            # before select is called
+            time.sleep(TIMEOUT_FULL)
+            mid_time = time.time()
+            dt = mid_time - before_time
+            if dt >= TIMEOUT_HALF:
+                raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
+            select.select([read], [], [], TIMEOUT_FULL)
+            after_time = time.time()
+            dt = after_time - mid_time
+            if dt >= TIMEOUT_HALF:
+                raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
+        """)
 
     def test_wakeup_fd_during(self):
-        import select
+        self.check_wakeup("""def test():
+            import select
+            import time
 
-        signal.alarm(1)
-        before_time = time.time()
-        # We attempt to get a signal during the select call
-        self.assertRaises(select.error, select.select,
-            [self.read], [], [], self.TIMEOUT_FULL)
-        after_time = time.time()
-        self.assertTrue(after_time - before_time < self.TIMEOUT_HALF)
+            TIMEOUT_FULL = 10
+            TIMEOUT_HALF = 5
 
-    def setUp(self):
-        import fcntl
-
-        self.alrm = signal.signal(signal.SIGALRM, lambda x,y:None)
-        self.read, self.write = os.pipe()
-        flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0)
-        flags = flags | os.O_NONBLOCK
-        fcntl.fcntl(self.write, fcntl.F_SETFL, flags)
-        self.old_wakeup = signal.set_wakeup_fd(self.write)
-
-    def tearDown(self):
-        signal.set_wakeup_fd(self.old_wakeup)
-        os.close(self.read)
-        os.close(self.write)
-        signal.signal(signal.SIGALRM, self.alrm)
+            signal.alarm(1)
+            before_time = time.time()
+            # We attempt to get a signal during the select call
+            try:
+                select.select([read], [], [], TIMEOUT_FULL)
+            except select.error:
+                pass
+            else:
+                raise Exception("select.error not raised")
+            after_time = time.time()
+            dt = after_time - before_time
+            if dt >= TIMEOUT_HALF:
+                raise Exception("%s >= %s" % (dt, TIMEOUT_HALF))
+        """)
 
 @unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
 class SiginterruptTest(unittest.TestCase):
diff --git a/Lib/test/test_tk.py b/Lib/test/test_tk.py
index ab979fa..f993c53 100644
--- a/Lib/test/test_tk.py
+++ b/Lib/test/test_tk.py
@@ -2,15 +2,11 @@
 # Skip test if _tkinter wasn't built.
 support.import_module('_tkinter')
 
-import tkinter
-from tkinter.test import runtktests
-import unittest
+# Skip test if tk cannot be initialized.
+from tkinter.test.support import check_tk_availability
+check_tk_availability()
 
-try:
-    tkinter.Button()
-except tkinter.TclError as msg:
-    # assuming tk is not available
-    raise unittest.SkipTest("tk not available: %s" % msg)
+from tkinter.test import runtktests
 
 def test_main(enable_gui=False):
     if enable_gui:
diff --git a/Lib/test/test_ttk_guionly.py b/Lib/test/test_ttk_guionly.py
index bff4fc1..b8c1a4c 100644
--- a/Lib/test/test_ttk_guionly.py
+++ b/Lib/test/test_ttk_guionly.py
@@ -5,6 +5,10 @@
 # Skip this test if _tkinter wasn't built.
 support.import_module('_tkinter')
 
+# Skip test if tk cannot be initialized.
+from tkinter.test.support import check_tk_availability
+check_tk_availability()
+
 from _tkinter import TclError
 from tkinter import ttk
 from tkinter.test import runtktests
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 97be587..885e740 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -788,6 +788,7 @@
         self.assertEqual('%c' % '\U00021483', '\U00021483')
         self.assertRaises(TypeError, "%c".__mod__, "aa")
         self.assertRaises(ValueError, "%.1\u1032f".__mod__, (1.0/3))
+        self.assertRaises(TypeError, "%i".__mod__, "aa")
 
         # formatting jobs delegated from the string implementation:
         self.assertEqual('...%(foo)s...' % {'foo':"abc"}, '...abc...')
diff --git a/Lib/tkinter/test/support.py b/Lib/tkinter/test/support.py
index 97212fb..20bd412 100644
--- a/Lib/tkinter/test/support.py
+++ b/Lib/tkinter/test/support.py
@@ -1,6 +1,42 @@
+import subprocess
+import sys
+from test import support
 import tkinter
+import unittest
+
+_tk_available = None
+
+def check_tk_availability():
+    """Check that Tk is installed and available."""
+    global _tk_available
+
+    if _tk_available is not None:
+        return
+
+    if sys.platform == 'darwin':
+        # The Aqua Tk implementations on OS X can abort the process if
+        # being called in an environment where a window server connection
+        # cannot be made, for instance when invoked by a buildbot or ssh
+        # process not running under the same user id as the current console
+        # user.  Instead, try to initialize Tk under a subprocess.
+        p = subprocess.Popen(
+                [sys.executable, '-c', 'import tkinter; tkinter.Button()'],
+                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        stderr = support.strip_python_stderr(p.communicate()[1])
+        if stderr or p.returncode:
+            raise unittest.SkipTest("tk cannot be initialized: %s" % stderr)
+    else:
+        try:
+            tkinter.Button()
+        except tkinter.TclError as msg:
+            # assuming tk is not available
+            raise unittest.SkipTest("tk not available: %s" % msg)
+
+    _tk_available = True
+    return
 
 def get_tk_root():
+    check_tk_availability()     # raise exception if tk unavailable
     try:
         root = tkinter._default_root
     except AttributeError:
diff --git a/Lib/xml/dom/pulldom.py b/Lib/xml/dom/pulldom.py
index 81a36b0..d5ac8b2 100644
--- a/Lib/xml/dom/pulldom.py
+++ b/Lib/xml/dom/pulldom.py
@@ -326,7 +326,7 @@
     if bufsize is None:
         bufsize = default_bufsize
     if isinstance(stream_or_string, str):
-        stream = open(stream_or_string)
+        stream = open(stream_or_string, 'rb')
     else:
         stream = stream_or_string
     if not parser:
diff --git a/Misc/NEWS b/Misc/NEWS
index 1518bd1..67485b3 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,51 @@
 Python News
 +++++++++++
 
+What's New in Python 3.2.2?
+===========================
+
+*Release date: XX-XX-2011*
+
+Core and Builtins
+-----------------
+
+- When a generator yields, do not retain the caller's exception state on the
+  generator.
+
+- Issue #12475: Prevent generators from leaking their exception state into the
+  caller's frame as they return for the last time.
+
+Library
+-------
+
+- Issue #12467: warnings: fix a race condition if a warning is emitted at
+  shutdown, if globals()['__file__'] is None.
+
+- Issue #12451: pydoc: importfile() now opens the Python script in binary mode,
+  instead of text mode using the locale encoding, to avoid encoding issues.
+
+- Issue #12451: runpy: run_path() now opens the Python script in binary mode,
+  instead of text mode using the locale encoding, to support other encodings
+  than UTF-8 (scripts using the coding cookie).
+
+- Issue #12451: xml.dom.pulldom: parse() now opens files in binary mode instead
+  of the text mode (using the locale encoding) to avoid encoding issues.
+
+C-API
+-----
+
+Tests
+-----
+
+- Issue #12469: Run "wakeup" signal tests in subprocess to run the test in a
+  fresh process with only one thread and to not change signal handling of the
+  parent process.
+
+- Issue #8716: Avoid crashes caused by Aqua Tk on OSX when attempting to run
+  test_tk or test_ttk_guionly under a username that is not currently logged
+  in to the console windowserver (as may be the case under buildbot or ssh).
+
+
 What's New in Python 3.2.1?
 ===========================
 
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 7a70a5e..03807a4 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -9689,8 +9689,6 @@
             case 'o':
             case 'x':
             case 'X':
-                if (c == 'i')
-                    c = 'd';
                 isnumok = 0;
                 if (PyNumber_Check(v)) {
                     PyObject *iobj=NULL;
@@ -9705,7 +9703,7 @@
                     if (iobj!=NULL) {
                         if (PyLong_Check(iobj)) {
                             isnumok = 1;
-                            temp = formatlong(iobj, flags, prec, c);
+                            temp = formatlong(iobj, flags, prec, (c == 'i'? 'd': c));
                             Py_DECREF(iobj);
                             if (!temp)
                                 goto onError;
diff --git a/Python/_warnings.c b/Python/_warnings.c
index 07fd683..99f6071 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -517,6 +517,7 @@
     }
     else {
         const char *module_str = _PyUnicode_AsString(*module);
+        Py_XDECREF(*filename);
         if (module_str == NULL)
                 goto handle_error;
         if (strcmp(module_str, "__main__") == 0) {
diff --git a/Python/ceval.c b/Python/ceval.c
index 705ed41..5c3bb83 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1145,6 +1145,23 @@
         f->f_exc_traceback = tmp; \
     }
 
+#define RESTORE_AND_CLEAR_EXC_STATE() \
+    { \
+        PyObject *type, *value, *tb; \
+        type = tstate->exc_type; \
+        value = tstate->exc_value; \
+        tb = tstate->exc_traceback; \
+        tstate->exc_type = f->f_exc_type; \
+        tstate->exc_value = f->f_exc_value; \
+        tstate->exc_traceback = f->f_exc_traceback; \
+        f->f_exc_type = NULL; \
+        f->f_exc_value = NULL; \
+        f->f_exc_traceback = NULL; \
+        Py_XDECREF(type); \
+        Py_XDECREF(value); \
+        Py_XDECREF(tb); \
+    }
+
 /* Start of code */
 
     if (f == NULL)
@@ -1881,10 +1898,6 @@
             retval = POP();
             f->f_stacktop = stack_pointer;
             why = WHY_YIELD;
-            /* Put aside the current exception state and restore
-               that of the calling frame. This only serves when
-               "yield" is used inside an except handler. */
-            SWAP_EXC_STATE();
             goto fast_yield;
 
         TARGET(POP_EXCEPT)
@@ -3021,6 +3034,26 @@
         retval = NULL;
 
 fast_yield:
+    if (co->co_flags & CO_GENERATOR && (why == WHY_YIELD || why == WHY_RETURN)) {
+        /* The purpose of this block is to put aside the generator's exception
+           state and restore that of the calling frame. If the current
+           exception state is from the caller, we clear the exception values
+           on the generator frame, so they are not swapped back in latter. The
+           origin of the current exception state is determined by checking for
+           except handler blocks, which we must be in iff a new exception
+           state came into existence in this frame. (An uncaught exception
+           would have why == WHY_EXCEPTION, and we wouldn't be here). */
+        int i;
+        for (i = 0; i < f->f_iblock; i++)
+            if (f->f_blockstack[i].b_type == EXCEPT_HANDLER)
+                break;
+        if (i == f->f_iblock)
+            /* We did not create this exception. */
+            RESTORE_AND_CLEAR_EXC_STATE()
+        else
+            SWAP_EXC_STATE()
+    }
+
     if (tstate->use_tracing) {
         if (tstate->c_tracefunc) {
             if (why == WHY_RETURN || why == WHY_YIELD) {