merge 2.7.6 release branch
diff --git a/.hgtags b/.hgtags
index 1a8dd47..8925a8c 100644
--- a/.hgtags
+++ b/.hgtags
@@ -160,4 +160,5 @@
 026ee0057e2d3305f90a9da41daf7c3f9eb1e814 v2.7.4
 ab05e7dd27889b93f20d97bae86170aabfe45ace v2.7.5
 a0025037f11a73df5a7dd03e5a4027adad4cb94e v2.6.9rc1
+fcb3ec2842f99454322492dd0ec2cf01322df093 v2.6.9
 4913d0e9be30666218cc4d713937e81c0e7f346a v2.7.6rc1
diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst
index 829be68..f0e179b 100644
--- a/Doc/library/codecs.rst
+++ b/Doc/library/codecs.rst
@@ -23,6 +23,29 @@
 
 It defines the following functions:
 
+.. function:: encode(obj, encoding='ascii', errors='strict')
+
+   Encodes *obj* using the codec registered for *encoding*.
+
+   *Errors* may be given to set the desired error handling scheme. The
+   default error handler is ``strict`` meaning that encoding errors raise
+   :exc:`ValueError` (or a more codec specific subclass, such as
+   :exc:`UnicodeEncodeError`). Refer to :ref:`codec-base-classes` for more
+   information on codec error handling.
+
+   .. versionadded:: 2.4
+
+.. function:: decode(obj, encoding='ascii', errors='strict')
+
+   Decodes *obj* using the codec registered for *encoding*.
+
+   *Errors* may be given to set the desired error handling scheme. The
+   default error handler is ``strict`` meaning that decoding errors raise
+   :exc:`ValueError` (or a more codec specific subclass, such as
+   :exc:`UnicodeDecodeError`). Refer to :ref:`codec-base-classes` for more
+   information on codec error handling.
+
+   .. versionadded:: 2.4
 
 .. function:: register(search_function)
 
diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst
index 72711e1..642d25b 100644
--- a/Doc/library/curses.rst
+++ b/Doc/library/curses.rst
@@ -380,7 +380,7 @@
    is to be displayed.
 
 
-.. function:: newwin(begin_y, begin_x)
+.. function:: newwin(nlines, ncols)
               newwin(nlines, ncols, begin_y, begin_x)
 
    Return a new window, whose left-upper corner is at  ``(begin_y, begin_x)``, and
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index 0de7391..db95269 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -1720,7 +1720,7 @@
    making assumptions about the output value. Field orderings will vary (for
    example, "month/day/year" versus "day/month/year"), and the output may
    contain Unicode characters encoded using the locale's default encoding (for
-   example, if the current locale is ``js_JP``, the default encoding could be
+   example, if the current locale is ``ja_JP``, the default encoding could be
    any one of ``eucJP``, ``SJIS``, or ``utf-8``; use :meth:`locale.getlocale`
    to determine the current locale's encoding).
 
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
index d3984c7..9045acf 100644
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -679,16 +679,15 @@
       (possibly modified) versions of the arguments passed in.
 
 In addition to the above, :class:`LoggerAdapter` supports the following
-methods of :class:`Logger`, i.e. :meth:`debug`, :meth:`info`, :meth:`warning`,
-:meth:`error`, :meth:`exception`, :meth:`critical`, :meth:`log`,
-:meth:`isEnabledFor`, :meth:`getEffectiveLevel`, :meth:`setLevel`,
-:meth:`hasHandlers`. These methods have the same signatures as their
-counterparts in :class:`Logger`, so you can use the two types of instances
-interchangeably.
+methods of :class:`Logger`: :meth:`~Logger.debug`, :meth:`~Logger.info`,
+:meth:`~Logger.warning`, :meth:`~Logger.error`, :meth:`~Logger.exception`,
+:meth:`~Logger.critical`, :meth:`~Logger.log` and :meth:`~Logger.isEnabledFor`.
+These methods have the same signatures as their counterparts in :class:`Logger`,
+so you can use the two types of instances interchangeably for these calls.
 
 .. versionchanged:: 2.7
-   The :meth:`isEnabledFor` method was added to :class:`LoggerAdapter`.  This
-   method delegates to the underlying logger.
+   The :meth:`~Logger.isEnabledFor` method was added to :class:`LoggerAdapter`.
+   This method delegates to the underlying logger.
 
 
 Thread Safety
diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst
index f87c2eb..92180d6 100644
--- a/Doc/library/nntplib.rst
+++ b/Doc/library/nntplib.rst
@@ -234,25 +234,25 @@
 
 .. method:: NNTP.next()
 
-   Send a ``NEXT`` command.  Return as for :meth:`stat`.
+   Send a ``NEXT`` command.  Return as for :meth:`.stat`.
 
 
 .. method:: NNTP.last()
 
-   Send a ``LAST`` command.  Return as for :meth:`stat`.
+   Send a ``LAST`` command.  Return as for :meth:`.stat`.
 
 
 .. method:: NNTP.head(id)
 
-   Send a ``HEAD`` command, where *id* has the same meaning as for :meth:`stat`.
+   Send a ``HEAD`` command, where *id* has the same meaning as for :meth:`.stat`.
    Return a tuple ``(response, number, id, list)`` where the first three are the
-   same as for :meth:`stat`, and *list* is a list of the article's headers (an
+   same as for :meth:`.stat`, and *list* is a list of the article's headers (an
    uninterpreted list of lines, without trailing newlines).
 
 
 .. method:: NNTP.body(id,[file])
 
-   Send a ``BODY`` command, where *id* has the same meaning as for :meth:`stat`.
+   Send a ``BODY`` command, where *id* has the same meaning as for :meth:`.stat`.
    If the *file* parameter is supplied, then the body is stored in a file.  If
    *file* is a string, then the method will open a file object with that name,
    write to it then close it. If *file* is a file object, then it will start
@@ -263,7 +263,7 @@
 .. method:: NNTP.article(id)
 
    Send an ``ARTICLE`` command, where *id* has the same meaning as for
-   :meth:`stat`.  Return as for :meth:`head`.
+   :meth:`.stat`.  Return as for :meth:`head`.
 
 
 .. method:: NNTP.slave()
@@ -290,7 +290,7 @@
 .. method:: NNTP.post(file)
 
    Post an article using the ``POST`` command.  The *file* argument is an open file
-   object which is read until EOF using its :meth:`readline` method.  It should be
+   object which is read until EOF using its :meth:`~file.readline` method.  It should be
    a well-formed news article, including the required headers.  The :meth:`post`
    method automatically escapes lines beginning with ``.``.
 
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index 9d7bd5a..679cedb 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -1936,6 +1936,10 @@
    Note that some platforms including FreeBSD <= 6.3, Cygwin and OS/2 EMX have
    known issues when using fork() from a thread.
 
+   .. warning::
+
+      See :mod:`ssl` for applications that use the SSL module with fork().
+
    Availability: Unix.
 
 
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index 550c249..898e7d2 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -30,6 +30,14 @@
    operating system socket APIs.  The installed version of OpenSSL may also
    cause variations in behavior.
 
+.. warning::
+
+   OpenSSL's internal random number generator does not properly handle fork.
+   Applications must change the PRNG state of the parent process if they use
+   any SSL feature with :func:`os.fork`. Any successful call of
+   :func:`~ssl.RAND_add`, :func:`~ssl.RAND_bytes` or
+   :func:`~ssl.RAND_pseudo_bytes` is sufficient.
+
 This section documents the objects and functions in the ``ssl`` module; for more
 general information about TLS, SSL, and certificates, the reader is referred to
 the documents in the "See Also" section at the bottom.
diff --git a/Lib/distutils/command/build_py.py b/Lib/distutils/command/build_py.py
index 04c455f..c123c62 100644
--- a/Lib/distutils/command/build_py.py
+++ b/Lib/distutils/command/build_py.py
@@ -128,7 +128,8 @@
             # Each pattern has to be converted to a platform-specific path
             filelist = glob(os.path.join(src_dir, convert_path(pattern)))
             # Files that match more than one pattern are only added once
-            files.extend([fn for fn in filelist if fn not in files])
+            files.extend([fn for fn in filelist if fn not in files
+                and os.path.isfile(fn)])
         return files
 
     def build_package_data(self):
diff --git a/Lib/distutils/tests/test_build_py.py b/Lib/distutils/tests/test_build_py.py
index 6c6ec20..c4498bc 100644
--- a/Lib/distutils/tests/test_build_py.py
+++ b/Lib/distutils/tests/test_build_py.py
@@ -99,6 +99,37 @@
             os.chdir(cwd)
             sys.stdout = old_stdout
 
+    def test_dir_in_package_data(self):
+        """
+        A directory in package_data should not be added to the filelist.
+        """
+        # See bug 19286
+        sources = self.mkdtemp()
+        pkg_dir = os.path.join(sources, "pkg")
+
+        os.mkdir(pkg_dir)
+        open(os.path.join(pkg_dir, "__init__.py"), "w").close()
+
+        docdir = os.path.join(pkg_dir, "doc")
+        os.mkdir(docdir)
+        open(os.path.join(docdir, "testfile"), "w").close()
+
+        # create the directory that could be incorrectly detected as a file
+        os.mkdir(os.path.join(docdir, 'otherdir'))
+
+        os.chdir(sources)
+        dist = Distribution({"packages": ["pkg"],
+                             "package_data": {"pkg": ["doc/*"]}})
+        # script_name need not exist, it just need to be initialized
+        dist.script_name = os.path.join(sources, "setup.py")
+        dist.script_args = ["build"]
+        dist.parse_command_line()
+
+        try:
+            dist.run_commands()
+        except DistutilsFileError:
+            self.fail("failed package_data when data dir includes a dir")
+
     def test_dont_write_bytecode(self):
         # makes sure byte_compile is not used
         pkg_dir, dist = self.create_dist()
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
index 529a3e4..718be6e 100644
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -2908,8 +2908,9 @@
     def debug(self, boolean=None):
         """Turn on the internal consistency checks of the B-Tree inside the text
         widget according to BOOLEAN."""
-        return self.tk.getboolean(self.tk.call(
-            self._w, 'debug', boolean))
+        if boolean is None:
+            return self.tk.call(self._w, 'debug')
+        self.tk.call(self._w, 'debug', boolean)
     def delete(self, index1, index2=None):
         """Delete the characters between INDEX1 and INDEX2 (not included)."""
         self.tk.call(self._w, 'delete', index1, index2)
@@ -3411,7 +3412,7 @@
         bounding box may refer to a region outside the
         visible area of the window.
         """
-        return self.tk.call(self._w, 'bbox', index)
+        return self._getints(self.tk.call(self._w, 'bbox', index)) or None
 
     def delete(self, first, last=None):
         """Delete one or more elements of the spinbox.
diff --git a/Lib/lib-tk/test/test_tkinter/test_text.py b/Lib/lib-tk/test/test_tkinter/test_text.py
index e6c08be..ca21b60 100644
--- a/Lib/lib-tk/test/test_tkinter/test_text.py
+++ b/Lib/lib-tk/test/test_tkinter/test_text.py
@@ -14,6 +14,17 @@
     def tearDown(self):
         self.text.destroy()
 
+    def test_debug(self):
+        text = self.text
+        olddebug = text.debug()
+        try:
+            text.debug(0)
+            self.assertEqual(text.debug(), 0)
+            text.debug(1)
+            self.assertEqual(text.debug(), 1)
+        finally:
+            text.debug(olddebug)
+            self.assertEqual(text.debug(), olddebug)
 
     def test_search(self):
         text = self.text
diff --git a/Lib/lib-tk/test/test_tkinter/test_widgets.py b/Lib/lib-tk/test/test_tkinter/test_widgets.py
new file mode 100644
index 0000000..f0a4eeb
--- /dev/null
+++ b/Lib/lib-tk/test/test_tkinter/test_widgets.py
@@ -0,0 +1,942 @@
+import unittest
+import Tkinter
+import os
+from test.test_support import requires, run_unittest
+
+from test_ttk.support import tcl_version, requires_tcl, widget_eq
+from widget_tests import (
+    add_standard_options, noconv, noconv_meth, int_round, pixels_round,
+    AbstractWidgetTest, StandardOptionsTests,
+    IntegerSizeTests, PixelSizeTests)
+
+requires('gui')
+
+
+class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
+    _conv_pad_pixels = noconv_meth
+
+    def test_class(self):
+        widget = self.create()
+        self.assertEqual(widget['class'],
+                         widget.__class__.__name__.title())
+        self.checkInvalidParam(widget, 'class', 'Foo',
+                errmsg="can't modify -class option after widget is created")
+        widget2 = self.create(class_='Foo')
+        self.assertEqual(widget2['class'], 'Foo')
+
+    def test_colormap(self):
+        widget = self.create()
+        self.assertEqual(widget['colormap'], '')
+        self.checkInvalidParam(widget, 'colormap', 'new',
+                errmsg="can't modify -colormap option after widget is created")
+        widget2 = self.create(colormap='new')
+        self.assertEqual(widget2['colormap'], 'new')
+
+    def test_container(self):
+        widget = self.create()
+        self.assertEqual(widget['container'], 0 if self.wantobjects else '0')
+        self.checkInvalidParam(widget, 'container', 1,
+                errmsg="can't modify -container option after widget is created")
+        widget2 = self.create(container=True)
+        self.assertEqual(widget2['container'], 1 if self.wantobjects else '1')
+
+    def test_visual(self):
+        widget = self.create()
+        self.assertEqual(widget['visual'], '')
+        self.checkInvalidParam(widget, 'visual', 'default',
+                errmsg="can't modify -visual option after widget is created")
+        widget2 = self.create(visual='default')
+        self.assertEqual(widget2['visual'], 'default')
+
+
+@add_standard_options(StandardOptionsTests)
+class ToplevelTest(AbstractToplevelTest, unittest.TestCase):
+    OPTIONS = (
+        'background', 'borderwidth',
+        'class', 'colormap', 'container', 'cursor', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'menu', 'padx', 'pady', 'relief', 'screen',
+        'takefocus', 'use', 'visual', 'width',
+    )
+
+    def _create(self, **kwargs):
+        return Tkinter.Toplevel(self.root, **kwargs)
+
+    def test_menu(self):
+        widget = self.create()
+        menu = Tkinter.Menu(self.root)
+        self.checkParam(widget, 'menu', menu, eq=widget_eq)
+        self.checkParam(widget, 'menu', '')
+
+    def test_screen(self):
+        widget = self.create()
+        self.assertEqual(widget['screen'], '')
+        try:
+            display = os.environ['DISPLAY']
+        except KeyError:
+            self.skipTest('No $DISPLAY set.')
+        self.checkInvalidParam(widget, 'screen', display,
+                errmsg="can't modify -screen option after widget is created")
+        widget2 = self.create(screen=display)
+        self.assertEqual(widget2['screen'], display)
+
+    def test_use(self):
+        widget = self.create()
+        self.assertEqual(widget['use'], '')
+        parent = self.create(container=True)
+        wid = parent.winfo_id()
+        widget2 = self.create(use=wid)
+        self.assertEqual(int(widget2['use']), wid)
+
+
+@add_standard_options(StandardOptionsTests)
+class FrameTest(AbstractToplevelTest, unittest.TestCase):
+    OPTIONS = (
+        'background', 'borderwidth',
+        'class', 'colormap', 'container', 'cursor', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'relief', 'takefocus', 'visual', 'width',
+    )
+
+    def _create(self, **kwargs):
+        return Tkinter.Frame(self.root, **kwargs)
+
+
+@add_standard_options(StandardOptionsTests)
+class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
+    OPTIONS = (
+        'background', 'borderwidth',
+        'class', 'colormap', 'container', 'cursor',
+        'font', 'foreground', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'labelanchor', 'labelwidget', 'padx', 'pady', 'relief',
+        'takefocus', 'text', 'visual', 'width',
+    )
+
+    def _create(self, **kwargs):
+        return Tkinter.LabelFrame(self.root, **kwargs)
+
+    def test_labelanchor(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'labelanchor',
+                            'e', 'en', 'es', 'n', 'ne', 'nw',
+                            's', 'se', 'sw', 'w', 'wn', 'ws')
+        self.checkInvalidParam(widget, 'labelanchor', 'center')
+
+    def test_labelwidget(self):
+        widget = self.create()
+        label = Tkinter.Label(self.root, text='Mupp', name='foo')
+        self.checkParam(widget, 'labelwidget', label, expected='.foo')
+        label.destroy()
+
+
+class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests):
+    _conv_pixels = noconv_meth
+
+    def test_highlightthickness(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'highlightthickness',
+                              0, 1.3, 2.6, 6, -2, '10p')
+
+
+@add_standard_options(StandardOptionsTests)
+class LabelTest(AbstractLabelTest, unittest.TestCase):
+    OPTIONS = (
+        'activebackground', 'activeforeground', 'anchor',
+        'background', 'bitmap', 'borderwidth', 'compound', 'cursor',
+        'disabledforeground', 'font', 'foreground', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'image', 'justify', 'padx', 'pady', 'relief', 'state',
+        'takefocus', 'text', 'textvariable',
+        'underline', 'width', 'wraplength',
+    )
+
+    def _create(self, **kwargs):
+        return Tkinter.Label(self.root, **kwargs)
+
+
+@add_standard_options(StandardOptionsTests)
+class ButtonTest(AbstractLabelTest, unittest.TestCase):
+    OPTIONS = (
+        'activebackground', 'activeforeground', 'anchor',
+        'background', 'bitmap', 'borderwidth',
+        'command', 'compound', 'cursor', 'default',
+        'disabledforeground', 'font', 'foreground', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'image', 'justify', 'overrelief', 'padx', 'pady', 'relief',
+        'repeatdelay', 'repeatinterval',
+        'state', 'takefocus', 'text', 'textvariable',
+        'underline', 'width', 'wraplength')
+
+    def _create(self, **kwargs):
+        return Tkinter.Button(self.root, **kwargs)
+
+    def test_default(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'default', 'active', 'disabled', 'normal')
+
+
+@add_standard_options(StandardOptionsTests)
+class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
+    OPTIONS = (
+        'activebackground', 'activeforeground', 'anchor',
+        'background', 'bitmap', 'borderwidth',
+        'command', 'compound', 'cursor',
+        'disabledforeground', 'font', 'foreground', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'image', 'indicatoron', 'justify',
+        'offrelief', 'offvalue', 'onvalue', 'overrelief',
+        'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state',
+        'takefocus', 'text', 'textvariable',
+        'tristateimage', 'tristatevalue',
+        'underline', 'variable', 'width', 'wraplength',
+    )
+
+    def _create(self, **kwargs):
+        return Tkinter.Checkbutton(self.root, **kwargs)
+
+
+    def test_offvalue(self):
+        widget = self.create()
+        self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
+
+    def test_onvalue(self):
+        widget = self.create()
+        self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
+
+
+@add_standard_options(StandardOptionsTests)
+class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
+    OPTIONS = (
+        'activebackground', 'activeforeground', 'anchor',
+        'background', 'bitmap', 'borderwidth',
+        'command', 'compound', 'cursor',
+        'disabledforeground', 'font', 'foreground', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'image', 'indicatoron', 'justify', 'offrelief', 'overrelief',
+        'padx', 'pady', 'relief', 'selectcolor', 'selectimage', 'state',
+        'takefocus', 'text', 'textvariable',
+        'tristateimage', 'tristatevalue',
+        'underline', 'value', 'variable', 'width', 'wraplength',
+    )
+
+    def _create(self, **kwargs):
+        return Tkinter.Radiobutton(self.root, **kwargs)
+
+    def test_value(self):
+        widget = self.create()
+        self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
+
+
+@add_standard_options(StandardOptionsTests)
+class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
+    OPTIONS = (
+        'activebackground', 'activeforeground', 'anchor',
+        'background', 'bitmap', 'borderwidth',
+        'compound', 'cursor', 'direction',
+        'disabledforeground', 'font', 'foreground', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'image', 'indicatoron', 'justify', 'menu',
+        'padx', 'pady', 'relief', 'state',
+        'takefocus', 'text', 'textvariable',
+        'underline', 'width', 'wraplength',
+    )
+    _conv_pixels = staticmethod(pixels_round)
+
+    def _create(self, **kwargs):
+        return Tkinter.Menubutton(self.root, **kwargs)
+
+    def test_direction(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'direction',
+                'above', 'below', 'flush', 'left', 'right')
+
+    def test_height(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str)
+
+    test_highlightthickness = StandardOptionsTests.test_highlightthickness.im_func
+
+    def test_image(self):
+        widget = self.create()
+        image = Tkinter.PhotoImage('image1')
+        self.checkParam(widget, 'image', image, conv=str)
+        errmsg = 'image "spam" doesn\'t exist'
+        with self.assertRaises(Tkinter.TclError) as cm:
+            widget['image'] = 'spam'
+        if errmsg is not None:
+            self.assertEqual(str(cm.exception), errmsg)
+        with self.assertRaises(Tkinter.TclError) as cm:
+            widget.configure({'image': 'spam'})
+        if errmsg is not None:
+            self.assertEqual(str(cm.exception), errmsg)
+
+    def test_menu(self):
+        widget = self.create()
+        menu = Tkinter.Menu(widget, name='menu')
+        self.checkParam(widget, 'menu', menu, eq=widget_eq)
+        menu.destroy()
+
+    def test_padx(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m')
+        self.checkParam(widget, 'padx', -2, expected=0)
+
+    def test_pady(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m')
+        self.checkParam(widget, 'pady', -2, expected=0)
+
+    def test_width(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str)
+
+
+class OptionMenuTest(MenubuttonTest, unittest.TestCase):
+
+    def _create(self, default='b', values=('a', 'b', 'c'), **kwargs):
+        return Tkinter.OptionMenu(self.root, None, default, *values, **kwargs)
+
+
+@add_standard_options(IntegerSizeTests, StandardOptionsTests)
+class EntryTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'background', 'borderwidth', 'cursor',
+        'disabledbackground', 'disabledforeground',
+        'exportselection', 'font', 'foreground',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'insertbackground', 'insertborderwidth',
+        'insertofftime', 'insertontime', 'insertwidth',
+        'invalidcommand', 'justify', 'readonlybackground', 'relief',
+        'selectbackground', 'selectborderwidth', 'selectforeground',
+        'show', 'state', 'takefocus', 'textvariable',
+        'validate', 'validatecommand', 'width', 'xscrollcommand',
+    )
+
+    def _create(self, **kwargs):
+        return Tkinter.Entry(self.root, **kwargs)
+
+    def test_disabledbackground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'disabledbackground')
+
+    def test_insertborderwidth(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'insertborderwidth', 0, 1.3, -2)
+        self.checkParam(widget, 'insertborderwidth', 2, expected=1)
+        self.checkParam(widget, 'insertborderwidth', '10p', expected=1)
+
+    def test_insertwidth(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p')
+        if tcl_version[:2] == (8, 5):
+            self.checkParam(widget, 'insertwidth', 0.9, expected=2)
+        else:
+            self.checkParam(widget, 'insertwidth', 0.9, expected=1)
+        self.checkParam(widget, 'insertwidth', 0.1, expected=2)
+        self.checkParam(widget, 'insertwidth', -2, expected=2)
+
+    def test_invalidcommand(self):
+        widget = self.create()
+        self.checkCommandParam(widget, 'invalidcommand')
+        self.checkCommandParam(widget, 'invcmd')
+
+    def test_readonlybackground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'readonlybackground')
+
+    def test_show(self):
+        widget = self.create()
+        self.checkParam(widget, 'show', '*')
+        self.checkParam(widget, 'show', '')
+        self.checkParam(widget, 'show', ' ')
+
+    def test_state(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'state',
+                            'disabled', 'normal', 'readonly')
+
+    def test_validate(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'validate',
+                'all', 'key', 'focus', 'focusin', 'focusout', 'none')
+
+    def test_validatecommand(self):
+        widget = self.create()
+        self.checkCommandParam(widget, 'validatecommand')
+        self.checkCommandParam(widget, 'vcmd')
+
+
+@add_standard_options(StandardOptionsTests)
+class SpinboxTest(EntryTest, unittest.TestCase):
+    OPTIONS = (
+        'activebackground', 'background', 'borderwidth',
+        'buttonbackground', 'buttoncursor', 'buttondownrelief', 'buttonuprelief',
+        'command', 'cursor', 'disabledbackground', 'disabledforeground',
+        'exportselection', 'font', 'foreground', 'format', 'from',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'increment',
+        'insertbackground', 'insertborderwidth',
+        'insertofftime', 'insertontime', 'insertwidth',
+        'invalidcommand', 'justify', 'relief', 'readonlybackground',
+        'repeatdelay', 'repeatinterval',
+        'selectbackground', 'selectborderwidth', 'selectforeground',
+        'state', 'takefocus', 'textvariable', 'to',
+        'validate', 'validatecommand', 'values',
+        'width', 'wrap', 'xscrollcommand',
+    )
+
+    def _create(self, **kwargs):
+        return Tkinter.Spinbox(self.root, **kwargs)
+
+    test_show = None
+
+    def test_buttonbackground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'buttonbackground')
+
+    def test_buttoncursor(self):
+        widget = self.create()
+        self.checkCursorParam(widget, 'buttoncursor')
+
+    def test_buttondownrelief(self):
+        widget = self.create()
+        self.checkReliefParam(widget, 'buttondownrelief')
+
+    def test_buttonuprelief(self):
+        widget = self.create()
+        self.checkReliefParam(widget, 'buttonuprelief')
+
+    def test_format(self):
+        widget = self.create()
+        self.checkParam(widget, 'format', '%2f')
+        self.checkParam(widget, 'format', '%2.2f')
+        self.checkParam(widget, 'format', '%.2f')
+        self.checkParam(widget, 'format', '%2.f')
+        self.checkInvalidParam(widget, 'format', '%2e-1f')
+        self.checkInvalidParam(widget, 'format', '2.2')
+        self.checkInvalidParam(widget, 'format', '%2.-2f')
+        self.checkParam(widget, 'format', '%-2.02f')
+        self.checkParam(widget, 'format', '% 2.02f')
+        self.checkParam(widget, 'format', '% -2.200f')
+        self.checkParam(widget, 'format', '%09.200f')
+        self.checkInvalidParam(widget, 'format', '%d')
+
+    def test_from(self):
+        widget = self.create()
+        self.checkParam(widget, 'to', 100.0)
+        self.checkFloatParam(widget, 'from', -10, 10.2, 11.7)
+        self.checkInvalidParam(widget, 'from', 200,
+                errmsg='-to value must be greater than -from value')
+
+    def test_increment(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'increment', -1, 1, 10.2, 12.8, 0)
+
+    def test_to(self):
+        widget = self.create()
+        self.checkParam(widget, 'from', -100.0)
+        self.checkFloatParam(widget, 'to', -10, 10.2, 11.7)
+        self.checkInvalidParam(widget, 'to', -200,
+                errmsg='-to value must be greater than -from value')
+
+    def test_values(self):
+        # XXX
+        widget = self.create()
+        self.assertEqual(widget['values'], '')
+        self.checkParam(widget, 'values', 'mon tue wed thur')
+        self.checkParam(widget, 'values', ('mon', 'tue', 'wed', 'thur'),
+                        expected='mon tue wed thur')
+        self.checkParam(widget, 'values', (42, 3.14, '', 'any string'),
+                        expected='42 3.14 {} {any string}')
+        self.checkParam(widget, 'values', '')
+
+    def test_wrap(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'wrap')
+
+    def test_bbox(self):
+        widget = self.create()
+        bbox = widget.bbox(0)
+        self.assertEqual(len(bbox), 4)
+        for item in bbox:
+            self.assertIsInstance(item, int)
+
+        self.assertRaises(Tkinter.TclError, widget.bbox, 'noindex')
+        self.assertRaises(Tkinter.TclError, widget.bbox, None)
+        self.assertRaises(TypeError, widget.bbox)
+        self.assertRaises(TypeError, widget.bbox, 0, 1)
+
+
+@add_standard_options(StandardOptionsTests)
+class TextTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'autoseparators', 'background', 'blockcursor', 'borderwidth',
+        'cursor', 'endline', 'exportselection',
+        'font', 'foreground', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'inactiveselectbackground', 'insertbackground', 'insertborderwidth',
+        'insertofftime', 'insertontime', 'insertunfocussed', 'insertwidth',
+        'maxundo', 'padx', 'pady', 'relief',
+        'selectbackground', 'selectborderwidth', 'selectforeground',
+        'setgrid', 'spacing1', 'spacing2', 'spacing3', 'startline', 'state',
+        'tabs', 'tabstyle', 'takefocus', 'undo', 'width', 'wrap',
+        'xscrollcommand', 'yscrollcommand',
+    )
+    if tcl_version < (8, 5):
+        wantobjects = False
+
+    def _create(self, **kwargs):
+        return Tkinter.Text(self.root, **kwargs)
+
+    def test_autoseparators(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'autoseparators')
+
+    @requires_tcl(8, 5)
+    def test_blockcursor(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'blockcursor')
+
+    @requires_tcl(8, 5)
+    def test_endline(self):
+        widget = self.create()
+        text = '\n'.join('Line %d' for i in range(100))
+        widget.insert('end', text)
+        self.checkParam(widget, 'endline', 200, expected='')
+        self.checkParam(widget, 'endline', -10, expected='')
+        self.checkInvalidParam(widget, 'endline', 'spam',
+                errmsg='expected integer but got "spam"')
+        self.checkParam(widget, 'endline', 50)
+        self.checkParam(widget, 'startline', 15)
+        self.checkInvalidParam(widget, 'endline', 10,
+                errmsg='-startline must be less than or equal to -endline')
+
+    def test_height(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c')
+        self.checkParam(widget, 'height', -100, expected=1)
+        self.checkParam(widget, 'height', 0, expected=1)
+
+    def test_maxundo(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'maxundo', 0, 5, -1)
+
+    @requires_tcl(8, 5)
+    def test_inactiveselectbackground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'inactiveselectbackground')
+
+    @requires_tcl(8, 6)
+    def test_insertunfocussed(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'insertunfocussed',
+                            'hollow', 'none', 'solid')
+
+    def test_selectborderwidth(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'selectborderwidth',
+                              1.3, 2.6, -2, '10p', conv=False,
+                              keep_orig=tcl_version >= (8, 5))
+
+    def test_spacing1(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c')
+        self.checkParam(widget, 'spacing1', -5, expected=0)
+
+    def test_spacing2(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c')
+        self.checkParam(widget, 'spacing2', -1, expected=0)
+
+    def test_spacing3(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c')
+        self.checkParam(widget, 'spacing3', -10, expected=0)
+
+    @requires_tcl(8, 5)
+    def test_startline(self):
+        widget = self.create()
+        text = '\n'.join('Line %d' for i in range(100))
+        widget.insert('end', text)
+        self.checkParam(widget, 'startline', 200, expected='')
+        self.checkParam(widget, 'startline', -10, expected='')
+        self.checkInvalidParam(widget, 'startline', 'spam',
+                errmsg='expected integer but got "spam"')
+        self.checkParam(widget, 'startline', 10)
+        self.checkParam(widget, 'endline', 50)
+        self.checkInvalidParam(widget, 'startline', 70,
+                errmsg='-startline must be less than or equal to -endline')
+
+    def test_state(self):
+        widget = self.create()
+        if tcl_version < (8, 5):
+            self.checkParams(widget, 'state', 'disabled', 'normal')
+        else:
+            self.checkEnumParam(widget, 'state', 'disabled', 'normal')
+
+    def test_tabs(self):
+        widget = self.create()
+        self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'))
+        self.checkParam(widget, 'tabs', '10.2 20.7 1i 2i',
+                        expected=('10.2', '20.7', '1i', '2i'))
+        self.checkParam(widget, 'tabs', '2c left 4c 6c center',
+                        expected=('2c', 'left', '4c', '6c', 'center'))
+        self.checkInvalidParam(widget, 'tabs', 'spam',
+                               errmsg='bad screen distance "spam"',
+                               keep_orig=tcl_version >= (8, 5))
+
+    @requires_tcl(8, 5)
+    def test_tabstyle(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor')
+
+    def test_undo(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'undo')
+
+    def test_width(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'width', 402)
+        self.checkParam(widget, 'width', -402, expected=1)
+        self.checkParam(widget, 'width', 0, expected=1)
+
+    def test_wrap(self):
+        widget = self.create()
+        if tcl_version < (8, 5):
+            self.checkParams(widget, 'wrap', 'char', 'none', 'word')
+        else:
+            self.checkEnumParam(widget, 'wrap', 'char', 'none', 'word')
+
+    def test_bbox(self):
+        widget = self.create()
+        bbox = widget.bbox('1.1')
+        self.assertEqual(len(bbox), 4)
+        for item in bbox:
+            self.assertIsInstance(item, int)
+
+        self.assertIsNone(widget.bbox('end'))
+        self.assertRaises(Tkinter.TclError, widget.bbox, 'noindex')
+        self.assertRaises(Tkinter.TclError, widget.bbox, None)
+        self.assertRaises(Tkinter.TclError, widget.bbox)
+        self.assertRaises(Tkinter.TclError, widget.bbox, '1.1', 'end')
+
+
+@add_standard_options(PixelSizeTests, StandardOptionsTests)
+class CanvasTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'background', 'borderwidth',
+        'closeenough', 'confine', 'cursor', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'insertbackground', 'insertborderwidth',
+        'insertofftime', 'insertontime', 'insertwidth',
+        'relief', 'scrollregion',
+        'selectbackground', 'selectborderwidth', 'selectforeground',
+        'state', 'takefocus',
+        'xscrollcommand', 'xscrollincrement',
+        'yscrollcommand', 'yscrollincrement', 'width',
+    )
+
+    _conv_pixels = staticmethod(int_round)
+    wantobjects = False
+
+    def _create(self, **kwargs):
+        return Tkinter.Canvas(self.root, **kwargs)
+
+    def test_closeenough(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'closeenough', 24, 2.4, 3.6, -3,
+                             conv=float)
+
+    def test_confine(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'confine')
+
+    def test_scrollregion(self):
+        widget = self.create()
+        self.checkParam(widget, 'scrollregion', '0 0 200 150')
+        self.checkParam(widget, 'scrollregion', (0, 0, 200, 150),
+                        expected='0 0 200 150')
+        self.checkParam(widget, 'scrollregion', '')
+        self.checkInvalidParam(widget, 'scrollregion', 'spam',
+                               errmsg='bad scrollRegion "spam"')
+        self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 'spam'))
+        self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200))
+        self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 150, 0))
+
+    def test_state(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'state', 'disabled', 'normal',
+                errmsg='bad state value "{}": must be normal or disabled')
+
+    def test_xscrollincrement(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'xscrollincrement',
+                              40, 0, 41.2, 43.6, -40, '0.5i')
+
+    def test_yscrollincrement(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'yscrollincrement',
+                              10, 0, 11.2, 13.6, -10, '0.1i')
+
+
+@add_standard_options(IntegerSizeTests, StandardOptionsTests)
+class ListboxTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'activestyle', 'background', 'borderwidth', 'cursor',
+        'disabledforeground', 'exportselection',
+        'font', 'foreground', 'height',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'listvariable', 'relief',
+        'selectbackground', 'selectborderwidth', 'selectforeground',
+        'selectmode', 'setgrid', 'state',
+        'takefocus', 'width', 'xscrollcommand', 'yscrollcommand',
+    )
+
+    def _create(self, **kwargs):
+        return Tkinter.Listbox(self.root, **kwargs)
+
+    def test_activestyle(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'activestyle',
+                            'dotbox', 'none', 'underline')
+
+    def test_listvariable(self):
+        widget = self.create()
+        var = Tkinter.DoubleVar()
+        self.checkVariableParam(widget, 'listvariable', var)
+
+    def test_selectmode(self):
+        widget = self.create()
+        self.checkParam(widget, 'selectmode', 'single')
+        self.checkParam(widget, 'selectmode', 'browse')
+        self.checkParam(widget, 'selectmode', 'multiple')
+        self.checkParam(widget, 'selectmode', 'extended')
+
+    def test_state(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'state', 'disabled', 'normal')
+
+@add_standard_options(PixelSizeTests, StandardOptionsTests)
+class ScaleTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'activebackground', 'background', 'bigincrement', 'borderwidth',
+        'command', 'cursor', 'digits', 'font', 'foreground', 'from',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'label', 'length', 'orient', 'relief',
+        'repeatdelay', 'repeatinterval',
+        'resolution', 'showvalue', 'sliderlength', 'sliderrelief', 'state',
+        'takefocus', 'tickinterval', 'to', 'troughcolor', 'variable', 'width',
+    )
+    default_orient = 'vertical'
+
+    def _create(self, **kwargs):
+        return Tkinter.Scale(self.root, **kwargs)
+
+    def test_bigincrement(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'bigincrement', 12.4, 23.6, -5)
+
+    def test_digits(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'digits', 5, 0)
+
+    def test_from(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=round)
+
+    def test_label(self):
+        widget = self.create()
+        self.checkParam(widget, 'label', 'any string')
+        self.checkParam(widget, 'label', '')
+
+    def test_length(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
+
+    def test_resolution(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'resolution', 4.2, 0, 6.7, -2)
+
+    def test_showvalue(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'showvalue')
+
+    def test_sliderlength(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'sliderlength',
+                              10, 11.2, 15.6, -3, '3m')
+
+    def test_sliderrelief(self):
+        widget = self.create()
+        self.checkReliefParam(widget, 'sliderrelief')
+
+    def test_tickinterval(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'tickinterval', 1, 4.3, 7.6, 0,
+                             conv=round)
+        self.checkParam(widget, 'tickinterval', -2, expected=2,
+                        conv=round)
+
+    def test_to(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10,
+                             conv=round)
+
+
+@add_standard_options(PixelSizeTests, StandardOptionsTests)
+class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'activebackground', 'activerelief',
+        'background', 'borderwidth',
+        'command', 'cursor', 'elementborderwidth',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'jump', 'orient', 'relief',
+        'repeatdelay', 'repeatinterval',
+        'takefocus', 'troughcolor', 'width',
+    )
+    _conv_pixels = staticmethod(int_round)
+    wantobjects = False
+    default_orient = 'vertical'
+
+    def _create(self, **kwargs):
+        return Tkinter.Scrollbar(self.root, **kwargs)
+
+    def test_activerelief(self):
+        widget = self.create()
+        self.checkReliefParam(widget, 'activerelief')
+
+    def test_elementborderwidth(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m')
+
+    def test_orient(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'orient', 'vertical', 'horizontal',
+                errmsg='bad orientation "{}": must be vertical or horizontal')
+
+
+@add_standard_options(StandardOptionsTests)
+class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'background', 'borderwidth', 'cursor',
+        'handlepad', 'handlesize', 'height',
+        'opaqueresize', 'orient', 'relief',
+        'sashcursor', 'sashpad', 'sashrelief', 'sashwidth',
+        'showhandle', 'width',
+    )
+    default_orient = 'horizontal'
+
+    def _create(self, **kwargs):
+        return Tkinter.PanedWindow(self.root, **kwargs)
+
+    def test_handlepad(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'handlepad', 5, 6.4, 7.6, -3, '1m')
+
+    def test_handlesize(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m',
+                              conv=noconv)
+
+    def test_height(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i',
+                              conv=noconv)
+
+    def test_opaqueresize(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'opaqueresize')
+
+    def test_sashcursor(self):
+        widget = self.create()
+        self.checkCursorParam(widget, 'sashcursor')
+
+    def test_sashpad(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'sashpad', 8, 1.3, 2.6, -2, '2m')
+
+    def test_sashrelief(self):
+        widget = self.create()
+        self.checkReliefParam(widget, 'sashrelief')
+
+    def test_sashwidth(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m',
+                              conv=noconv)
+
+    def test_showhandle(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'showhandle')
+
+    def test_width(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i',
+                              conv=noconv)
+
+
+@add_standard_options(StandardOptionsTests)
+class MenuTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'activebackground', 'activeborderwidth', 'activeforeground',
+        'background', 'borderwidth', 'cursor',
+        'disabledforeground', 'font', 'foreground',
+        'postcommand', 'relief', 'selectcolor', 'takefocus',
+        'tearoff', 'tearoffcommand', 'title', 'type',
+    )
+    _conv_pixels = noconv_meth
+
+    def _create(self, **kwargs):
+        return Tkinter.Menu(self.root, **kwargs)
+
+    def test_postcommand(self):
+        widget = self.create()
+        self.checkCommandParam(widget, 'postcommand')
+
+    def test_tearoff(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'tearoff')
+
+    def test_tearoffcommand(self):
+        widget = self.create()
+        self.checkCommandParam(widget, 'tearoffcommand')
+
+    def test_title(self):
+        widget = self.create()
+        self.checkParam(widget, 'title', 'any string')
+
+    def test_type(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'type',
+                'normal', 'tearoff', 'menubar')
+
+
+@add_standard_options(PixelSizeTests, StandardOptionsTests)
+class MessageTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'anchor', 'aspect', 'background', 'borderwidth',
+        'cursor', 'font', 'foreground',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'justify', 'padx', 'pady', 'relief',
+        'takefocus', 'text', 'textvariable', 'width',
+    )
+    _conv_pad_pixels = noconv_meth
+
+    def _create(self, **kwargs):
+        return Tkinter.Message(self.root, **kwargs)
+
+    def test_aspect(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'aspect', 250, 0, -300)
+
+
+tests_gui = [
+        ButtonTest, CanvasTest, CheckbuttonTest, EntryTest,
+        FrameTest, LabelFrameTest,LabelTest, ListboxTest,
+        MenubuttonTest, MenuTest, MessageTest, OptionMenuTest,
+        PanedWindowTest, RadiobuttonTest, ScaleTest, ScrollbarTest,
+        SpinboxTest, TextTest, ToplevelTest,
+]
+
+if __name__ == '__main__':
+    run_unittest(*tests_gui)
diff --git a/Lib/lib-tk/test/test_ttk/support.py b/Lib/lib-tk/test/test_ttk/support.py
index 57e7803..922c897 100644
--- a/Lib/lib-tk/test/test_ttk/support.py
+++ b/Lib/lib-tk/test/test_ttk/support.py
@@ -1,3 +1,4 @@
+import unittest
 import Tkinter
 
 def get_tk_root():
@@ -31,3 +32,42 @@
     widget.event_generate('<Motion>', x=x, y=y)
     widget.event_generate('<ButtonPress-1>', x=x, y=y)
     widget.event_generate('<ButtonRelease-1>', x=x, y=y)
+
+
+import _tkinter
+tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))
+
+def requires_tcl(*version):
+    return unittest.skipUnless(tcl_version >= version,
+            'requires Tcl version >= ' + '.'.join(map(str, version)))
+
+units = {
+    'c': 72 / 2.54,     # centimeters
+    'i': 72,            # inches
+    'm': 72 / 25.4,     # millimeters
+    'p': 1,             # points
+}
+
+def pixels_conv(value):
+    return float(value[:-1]) * units[value[-1:]]
+
+def tcl_obj_eq(actual, expected):
+    if actual == expected:
+        return True
+    if isinstance(actual, _tkinter.Tcl_Obj):
+        if isinstance(expected, str):
+            return str(actual) == expected
+    if isinstance(actual, tuple):
+        if isinstance(expected, tuple):
+            return (len(actual) == len(expected) and
+                    all(tcl_obj_eq(act, exp)
+                        for act, exp in zip(actual, expected)))
+    return False
+
+def widget_eq(actual, expected):
+    if actual == expected:
+        return True
+    if isinstance(actual, (str, Tkinter.Widget)):
+        if isinstance(expected, (str, Tkinter.Widget)):
+            return str(actual) == str(expected)
+    return False
diff --git a/Lib/lib-tk/test/test_ttk/test_widgets.py b/Lib/lib-tk/test/test_ttk/test_widgets.py
index c594602..afeef0d 100644
--- a/Lib/lib-tk/test/test_ttk/test_widgets.py
+++ b/Lib/lib-tk/test/test_ttk/test_widgets.py
@@ -6,9 +6,53 @@
 
 import support
 from test_functions import MockTclObj, MockStateSpec
+from support import tcl_version
+from widget_tests import (add_standard_options, noconv, noconv_meth,
+    AbstractWidgetTest, StandardOptionsTests,
+    IntegerSizeTests, PixelSizeTests)
 
 requires('gui')
 
+
+class StandardTtkOptionsTests(StandardOptionsTests):
+
+    def test_class(self):
+        widget = self.create()
+        self.assertEqual(widget['class'], '')
+        errmsg='attempt to change read-only option'
+        if tcl_version < (8, 6):
+            errmsg='Attempt to change read-only option'
+        self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg)
+        widget2 = self.create(class_='Foo')
+        self.assertEqual(widget2['class'], 'Foo')
+
+    def test_padding(self):
+        widget = self.create()
+        self.checkParam(widget, 'padding', 0, expected=('0',))
+        self.checkParam(widget, 'padding', 5, expected=('5',))
+        self.checkParam(widget, 'padding', (5, 6), expected=('5', '6'))
+        self.checkParam(widget, 'padding', (5, 6, 7),
+                        expected=('5', '6', '7'))
+        self.checkParam(widget, 'padding', (5, 6, 7, 8),
+                        expected=('5', '6', '7', '8'))
+        self.checkParam(widget, 'padding', ('5p', '6p', '7p', '8p'))
+        self.checkParam(widget, 'padding', (), expected='')
+
+    def test_style(self):
+        widget = self.create()
+        self.assertEqual(widget['style'], '')
+        errmsg = 'Layout Foo not found'
+        if hasattr(self, 'default_orient'):
+            errmsg = ('Layout %s.Foo not found' %
+                      getattr(self, 'default_orient').title())
+        self.checkInvalidParam(widget, 'style', 'Foo',
+                errmsg=errmsg)
+        widget2 = self.create(class_='Foo')
+        self.assertEqual(widget2['class'], 'Foo')
+        # XXX
+        pass
+
+
 class WidgetTest(unittest.TestCase):
     """Tests methods available in every ttk widget."""
 
@@ -72,7 +116,112 @@
         self.assertEqual(self.widget.state(), ('active', ))
 
 
-class ButtonTest(unittest.TestCase):
+class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
+    _conv_pixels = noconv_meth
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class FrameTest(AbstractToplevelTest, unittest.TestCase):
+    OPTIONS = (
+        'borderwidth', 'class', 'cursor', 'height',
+        'padding', 'relief', 'style', 'takefocus',
+        'width',
+    )
+
+    def _create(self, **kwargs):
+        return ttk.Frame(self.root, **kwargs)
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
+    OPTIONS = (
+        'borderwidth', 'class', 'cursor', 'height',
+        'labelanchor', 'labelwidget',
+        'padding', 'relief', 'style', 'takefocus',
+        'text', 'underline', 'width',
+    )
+
+    def _create(self, **kwargs):
+        return ttk.LabelFrame(self.root, **kwargs)
+
+    def test_labelanchor(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'labelanchor',
+                'e', 'en', 'es', 'n', 'ne', 'nw', 's', 'se', 'sw', 'w', 'wn', 'ws',
+                errmsg='Bad label anchor specification {}')
+        self.checkInvalidParam(widget, 'labelanchor', 'center')
+
+    def test_labelwidget(self):
+        widget = self.create()
+        label = ttk.Label(self.root, text='Mupp', name='foo')
+        self.checkParam(widget, 'labelwidget', label, expected='.foo')
+        label.destroy()
+
+
+class AbstractLabelTest(AbstractWidgetTest):
+
+    def checkImageParam(self, widget, name):
+        image = Tkinter.PhotoImage('image1')
+        image2 = Tkinter.PhotoImage('image2')
+        self.checkParam(widget, name, image, expected=('image1',))
+        self.checkParam(widget, name, 'image1', expected=('image1',))
+        self.checkParam(widget, name, (image,), expected=('image1',))
+        self.checkParam(widget, name, (image, 'active', image2),
+                        expected=('image1', 'active', 'image2'))
+        self.checkParam(widget, name, 'image1 active image2',
+                        expected=('image1', 'active', 'image2'))
+        self.checkInvalidParam(widget, name, 'spam',
+                errmsg='image "spam" doesn\'t exist')
+
+    def test_compound(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'compound',
+                'none', 'text', 'image', 'center',
+                'top', 'bottom', 'left', 'right')
+
+    def test_state(self):
+        widget = self.create()
+        self.checkParams(widget, 'state', 'active', 'disabled', 'normal')
+
+    def test_width(self):
+        widget = self.create()
+        self.checkParams(widget, 'width', 402, -402, 0)
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class LabelTest(AbstractLabelTest, unittest.TestCase):
+    OPTIONS = (
+        'anchor', 'background',
+        'class', 'compound', 'cursor', 'font', 'foreground',
+        'image', 'justify', 'padding', 'relief', 'state', 'style',
+        'takefocus', 'text', 'textvariable',
+        'underline', 'width', 'wraplength',
+    )
+    _conv_pixels = noconv_meth
+
+    def _create(self, **kwargs):
+        return ttk.Label(self.root, **kwargs)
+
+    def test_font(self):
+        widget = self.create()
+        self.checkParam(widget, 'font',
+                        '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class ButtonTest(AbstractLabelTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'command', 'compound', 'cursor', 'default',
+        'image', 'state', 'style', 'takefocus', 'text', 'textvariable',
+        'underline', 'width',
+    )
+
+    def _create(self, **kwargs):
+        return ttk.Button(self.root, **kwargs)
+
+    def test_default(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'default', 'normal', 'active', 'disabled')
 
     def test_invoke(self):
         success = []
@@ -81,7 +230,27 @@
         self.assertTrue(success)
 
 
-class CheckbuttonTest(unittest.TestCase):
+@add_standard_options(StandardTtkOptionsTests)
+class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'command', 'compound', 'cursor',
+        'image',
+        'offvalue', 'onvalue',
+        'state', 'style',
+        'takefocus', 'text', 'textvariable',
+        'underline', 'variable', 'width',
+    )
+
+    def _create(self, **kwargs):
+        return ttk.Checkbutton(self.root, **kwargs)
+
+    def test_offvalue(self):
+        widget = self.create()
+        self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
+
+    def test_onvalue(self):
+        widget = self.create()
+        self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
 
     def test_invoke(self):
         success = []
@@ -104,21 +273,40 @@
 
         cbtn['command'] = ''
         res = cbtn.invoke()
-        self.assertEqual(str(res), '')
+        self.assertFalse(str(res))
         self.assertFalse(len(success) > 1)
         self.assertEqual(cbtn['offvalue'],
             cbtn.tk.globalgetvar(cbtn['variable']))
 
 
-class ComboboxTest(unittest.TestCase):
+@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+class ComboboxTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'cursor', 'exportselection', 'height',
+        'justify', 'postcommand', 'state', 'style',
+        'takefocus', 'textvariable', 'values', 'width',
+    )
 
     def setUp(self):
+        super(ComboboxTest, self).setUp()
         support.root_deiconify()
-        self.combo = ttk.Combobox()
+        self.combo = self.create()
 
     def tearDown(self):
         self.combo.destroy()
         support.root_withdraw()
+        super(ComboboxTest, self).tearDown()
+
+    def _create(self, **kwargs):
+        return ttk.Combobox(self.root, **kwargs)
+
+    def test_height(self):
+        widget = self.create()
+        self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i')
+
+    def test_state(self):
+        widget = self.create()
+        self.checkParams(widget, 'state', 'active', 'disabled', 'normal')
 
     def _show_drop_down_listbox(self):
         width = self.combo.winfo_width()
@@ -166,8 +354,16 @@
             self.assertEqual(self.combo.get(), getval)
             self.assertEqual(self.combo.current(), currval)
 
+        self.assertEqual(self.combo['values'],
+                         () if tcl_version < (8, 5) else '')
         check_get_current('', -1)
 
+        self.checkParam(self.combo, 'values', 'mon tue wed thur',
+                        expected=('mon', 'tue', 'wed', 'thur'))
+        self.checkParam(self.combo, 'values', ('mon', 'tue', 'wed', 'thur'))
+        self.checkParam(self.combo, 'values', (42, 3.14, '', 'any string'))
+        self.checkParam(self.combo, 'values', () if tcl_version < (8, 5) else '')
+
         self.combo['values'] = ['a', 1, 'c']
 
         self.combo.set('c')
@@ -208,15 +404,52 @@
         combo2.destroy()
 
 
-class EntryTest(unittest.TestCase):
+@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+class EntryTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'background', 'class', 'cursor',
+        'exportselection', 'font',
+        'invalidcommand', 'justify',
+        'show', 'state', 'style', 'takefocus', 'textvariable',
+        'validate', 'validatecommand', 'width', 'xscrollcommand',
+    )
 
     def setUp(self):
+        super(EntryTest, self).setUp()
         support.root_deiconify()
-        self.entry = ttk.Entry()
+        self.entry = self.create()
 
     def tearDown(self):
         self.entry.destroy()
         support.root_withdraw()
+        super(EntryTest, self).tearDown()
+
+    def _create(self, **kwargs):
+        return ttk.Entry(self.root, **kwargs)
+
+    def test_invalidcommand(self):
+        widget = self.create()
+        self.checkCommandParam(widget, 'invalidcommand')
+
+    def test_show(self):
+        widget = self.create()
+        self.checkParam(widget, 'show', '*')
+        self.checkParam(widget, 'show', '')
+        self.checkParam(widget, 'show', ' ')
+
+    def test_state(self):
+        widget = self.create()
+        self.checkParams(widget, 'state',
+                         'disabled', 'normal', 'readonly')
+
+    def test_validate(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'validate',
+                'all', 'key', 'focus', 'focusin', 'focusout', 'none')
+
+    def test_validatecommand(self):
+        widget = self.create()
+        self.checkCommandParam(widget, 'validatecommand')
 
 
     def test_bbox(self):
@@ -312,16 +545,36 @@
         self.assertEqual(self.entry.state(), ())
 
 
-class PanedwindowTest(unittest.TestCase):
+@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'cursor', 'height',
+        'orient', 'style', 'takefocus', 'width',
+    )
 
     def setUp(self):
+        super(PanedWindowTest, self).setUp()
         support.root_deiconify()
-        self.paned = ttk.Panedwindow()
+        self.paned = self.create()
 
     def tearDown(self):
         self.paned.destroy()
         support.root_withdraw()
+        super(PanedWindowTest, self).tearDown()
 
+    def _create(self, **kwargs):
+        return ttk.PanedWindow(self.root, **kwargs)
+
+    def test_orient(self):
+        widget = self.create()
+        self.assertEqual(str(widget['orient']), 'vertical')
+        errmsg='attempt to change read-only option'
+        if tcl_version < (8, 6):
+            errmsg='Attempt to change read-only option'
+        self.checkInvalidParam(widget, 'orient', 'horizontal',
+                errmsg=errmsg)
+        widget2 = self.create(orient='horizontal')
+        self.assertEqual(str(widget2['orient']), 'horizontal')
 
     def test_add(self):
         # attempt to add a child that is not a direct child of the paned window
@@ -431,7 +684,22 @@
         self.assertTrue(isinstance(self.paned.sashpos(0), int))
 
 
-class RadiobuttonTest(unittest.TestCase):
+@add_standard_options(StandardTtkOptionsTests)
+class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'command', 'compound', 'cursor',
+        'image',
+        'state', 'style',
+        'takefocus', 'text', 'textvariable',
+        'underline', 'value', 'variable', 'width',
+    )
+
+    def _create(self, **kwargs):
+        return ttk.Radiobutton(self.root, **kwargs)
+
+    def test_value(self):
+        widget = self.create()
+        self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
 
     def test_invoke(self):
         success = []
@@ -461,19 +729,68 @@
         self.assertEqual(str(cbtn['variable']), str(cbtn2['variable']))
 
 
+class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'compound', 'cursor', 'direction',
+        'image', 'menu', 'state', 'style',
+        'takefocus', 'text', 'textvariable',
+        'underline', 'width',
+    )
 
-class ScaleTest(unittest.TestCase):
+    def _create(self, **kwargs):
+        return ttk.Menubutton(self.root, **kwargs)
+
+    def test_direction(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'direction',
+                'above', 'below', 'left', 'right', 'flush')
+
+    def test_menu(self):
+        widget = self.create()
+        menu = Tkinter.Menu(widget, name='menu')
+        self.checkParam(widget, 'menu', menu, conv=str)
+        menu.destroy()
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class ScaleTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'command', 'cursor', 'from', 'length',
+        'orient', 'style', 'takefocus', 'to', 'value', 'variable',
+    )
+    _conv_pixels = noconv_meth
+    default_orient = 'horizontal'
 
     def setUp(self):
+        super(ScaleTest, self).setUp()
         support.root_deiconify()
-        self.scale = ttk.Scale()
+        self.scale = self.create()
         self.scale.pack()
         self.scale.update()
 
     def tearDown(self):
         self.scale.destroy()
         support.root_withdraw()
+        super(ScaleTest, self).tearDown()
 
+    def _create(self, **kwargs):
+        return ttk.Scale(self.root, **kwargs)
+
+    def test_from(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=False)
+
+    def test_length(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
+
+    def test_to(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10, conv=False)
+
+    def test_value(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'value', 300, 14.9, 15.1, -10, conv=False)
 
     def test_custom_event(self):
         failure = [1, 1, 1] # will need to be empty
@@ -538,11 +855,64 @@
         self.assertRaises(Tkinter.TclError, self.scale.set, None)
 
 
-class NotebookTest(unittest.TestCase):
+@add_standard_options(StandardTtkOptionsTests)
+class ProgressbarTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'cursor', 'orient', 'length',
+        'mode', 'maximum', 'phase',
+        'style', 'takefocus', 'value', 'variable',
+    )
+    _conv_pixels = noconv_meth
+    default_orient = 'horizontal'
+
+    def _create(self, **kwargs):
+        return ttk.Progressbar(self.root, **kwargs)
+
+    def test_length(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'length', 100.1, 56.7, '2i')
+
+    def test_maximum(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'maximum', 150.2, 77.7, 0, -10, conv=False)
+
+    def test_mode(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'mode', 'determinate', 'indeterminate')
+
+    def test_phase(self):
+        # XXX
+        pass
+
+    def test_value(self):
+        widget = self.create()
+        self.checkFloatParam(widget, 'value', 150.2, 77.7, 0, -10,
+                             conv=False)
+
+
+@unittest.skipIf(sys.platform == 'darwin',
+                 'ttk.Scrollbar is special on MacOSX')
+@add_standard_options(StandardTtkOptionsTests)
+class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'command', 'cursor', 'orient', 'style', 'takefocus',
+    )
+    default_orient = 'vertical'
+
+    def _create(self, **kwargs):
+        return ttk.Scrollbar(self.root, **kwargs)
+
+
+@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
+class NotebookTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'cursor', 'height', 'padding', 'style', 'takefocus',
+    )
 
     def setUp(self):
+        super(NotebookTest, self).setUp()
         support.root_deiconify()
-        self.nb = ttk.Notebook(padding=0)
+        self.nb = self.create(padding=0)
         self.child1 = ttk.Label()
         self.child2 = ttk.Label()
         self.nb.add(self.child1, text='a')
@@ -553,7 +923,10 @@
         self.child2.destroy()
         self.nb.destroy()
         support.root_withdraw()
+        super(NotebookTest, self).tearDown()
 
+    def _create(self, **kwargs):
+        return ttk.Notebook(self.root, **kwargs)
 
     def test_tab_identifiers(self):
         self.nb.forget(0)
@@ -745,16 +1118,68 @@
         self.assertEqual(self.nb.select(), str(self.child1))
 
 
-class TreeviewTest(unittest.TestCase):
+@add_standard_options(StandardTtkOptionsTests)
+class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'columns', 'cursor', 'displaycolumns',
+        'height', 'padding', 'selectmode', 'show',
+        'style', 'takefocus', 'xscrollcommand', 'yscrollcommand',
+    )
 
     def setUp(self):
+        super(TreeviewTest, self).setUp()
         support.root_deiconify()
-        self.tv = ttk.Treeview(padding=0)
+        self.tv = self.create(padding=0)
 
     def tearDown(self):
         self.tv.destroy()
         support.root_withdraw()
+        super(TreeviewTest, self).tearDown()
 
+    def _create(self, **kwargs):
+        return ttk.Treeview(self.root, **kwargs)
+
+    def test_columns(self):
+        widget = self.create()
+        self.checkParam(widget, 'columns', 'a b c',
+                        expected=('a', 'b', 'c'))
+        self.checkParam(widget, 'columns', ('a', 'b', 'c'))
+        self.checkParam(widget, 'columns', () if tcl_version < (8, 5) else '')
+
+    def test_displaycolumns(self):
+        widget = self.create()
+        widget['columns'] = ('a', 'b', 'c')
+        self.checkParam(widget, 'displaycolumns', 'b a c',
+                        expected=('b', 'a', 'c'))
+        self.checkParam(widget, 'displaycolumns', ('b', 'a', 'c'))
+        self.checkParam(widget, 'displaycolumns', '#all',
+                        expected=('#all',))
+        self.checkParam(widget, 'displaycolumns', (2, 1, 0))
+        self.checkInvalidParam(widget, 'displaycolumns', ('a', 'b', 'd'),
+                               errmsg='Invalid column index d')
+        self.checkInvalidParam(widget, 'displaycolumns', (1, 2, 3),
+                               errmsg='Column index 3 out of bounds')
+        self.checkInvalidParam(widget, 'displaycolumns', (1, -2),
+                               errmsg='Column index -2 out of bounds')
+
+    def test_height(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False)
+        self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=noconv)
+
+    def test_selectmode(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'selectmode',
+                            'none', 'browse', 'extended')
+
+    def test_show(self):
+        widget = self.create()
+        self.checkParam(widget, 'show', 'tree headings',
+                        expected=('tree', 'headings'))
+        self.checkParam(widget, 'show', ('tree', 'headings'))
+        self.checkParam(widget, 'show', ('headings', 'tree'))
+        self.checkParam(widget, 'show', 'tree', expected=('tree',))
+        self.checkParam(widget, 'show', 'headings', expected=('headings',))
 
     def test_bbox(self):
         self.tv.pack()
@@ -945,12 +1370,10 @@
         self.assertRaises(Tkinter.TclError, self.tv.heading, '#0',
             anchor=1)
 
-    # XXX skipping for now; should be fixed to work with newer ttk
-    @unittest.skip("skipping pending resolution of Issue #10734")
     def test_heading_callback(self):
         def simulate_heading_click(x, y):
             support.simulate_mouse_click(self.tv, x, y)
-            self.tv.update_idletasks()
+            self.tv.update()
 
         success = [] # no success for now
 
@@ -1148,10 +1571,35 @@
         self.assertTrue(isinstance(self.tv.tag_configure('test'), dict))
 
 
+@add_standard_options(StandardTtkOptionsTests)
+class SeparatorTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'cursor', 'orient', 'style', 'takefocus',
+        # 'state'?
+    )
+    default_orient = 'horizontal'
+
+    def _create(self, **kwargs):
+        return ttk.Separator(self.root, **kwargs)
+
+
+@add_standard_options(StandardTtkOptionsTests)
+class SizegripTest(AbstractWidgetTest, unittest.TestCase):
+    OPTIONS = (
+        'class', 'cursor', 'style', 'takefocus',
+        # 'state'?
+    )
+
+    def _create(self, **kwargs):
+        return ttk.Sizegrip(self.root, **kwargs)
+
+
 tests_gui = (
-        WidgetTest, ButtonTest, CheckbuttonTest, RadiobuttonTest,
-        ComboboxTest, EntryTest, PanedwindowTest, ScaleTest, NotebookTest,
-        TreeviewTest
+        ButtonTest, CheckbuttonTest, ComboboxTest, EntryTest,
+        FrameTest, LabelFrameTest, LabelTest, MenubuttonTest,
+        NotebookTest, PanedWindowTest, ProgressbarTest,
+        RadiobuttonTest, ScaleTest, ScrollbarTest, SeparatorTest,
+        SizegripTest, TreeviewTest, WidgetTest,
         )
 
 if __name__ == "__main__":
diff --git a/Lib/lib-tk/test/widget_tests.py b/Lib/lib-tk/test/widget_tests.py
new file mode 100644
index 0000000..f17ea5f
--- /dev/null
+++ b/Lib/lib-tk/test/widget_tests.py
@@ -0,0 +1,523 @@
+# Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py
+
+import Tkinter
+from ttk import setup_master, Scale
+from test_ttk.support import tcl_version, requires_tcl, pixels_conv, tcl_obj_eq
+
+
+noconv = str if tcl_version < (8, 5) else False
+noconv_meth = noconv and staticmethod(noconv)
+
+def int_round(x):
+    return int(round(x))
+
+pixels_round = int_round
+if tcl_version[:2] == (8, 5):
+    # Issue #19085: Workaround a bug in Tk
+    # http://core.tcl.tk/tk/info/3497848
+    _pixels_round = None
+    def pixels_round(x):
+        global _pixels_round
+        if _pixels_round is None:
+            root = setup_master()
+            patchlevel = root.call('info', 'patchlevel')
+            patchlevel = tuple(map(int, patchlevel.split('.')))
+            if patchlevel < (8, 5, 12):
+                _pixels_round = int
+            else:
+                _pixels_round = int_round
+        return _pixels_round(x)
+
+
+_sentinel = object()
+
+class AbstractWidgetTest(object):
+    _conv_pixels = staticmethod(pixels_round)
+    _conv_pad_pixels = None
+    wantobjects = True
+
+    def setUp(self):
+        self.root = setup_master()
+        self.scaling = float(self.root.call('tk', 'scaling'))
+        if not self.root.wantobjects():
+            self.wantobjects = False
+
+    def create(self, **kwargs):
+        widget = self._create(**kwargs)
+        self.addCleanup(widget.destroy)
+        return widget
+
+    def assertEqual2(self, actual, expected, msg=None, eq=object.__eq__):
+        if eq(actual, expected):
+            return
+        self.assertEqual(actual, expected, msg)
+
+    def checkParam(self, widget, name, value, expected=_sentinel,
+                   conv=False, eq=None):
+        widget[name] = value
+        if expected is _sentinel:
+            expected = value
+        if conv:
+            expected = conv(expected)
+        if not self.wantobjects:
+            if isinstance(expected, tuple):
+                expected = Tkinter._join(expected)
+            else:
+                expected = str(expected)
+        if eq is None:
+            eq = tcl_obj_eq
+        self.assertEqual2(widget[name], expected, eq=eq)
+        self.assertEqual2(widget.cget(name), expected, eq=eq)
+        # XXX
+        if not isinstance(widget, Scale):
+            t = widget.configure(name)
+            self.assertEqual(len(t), 5)
+            ## XXX
+            if not isinstance(t[4], tuple):
+                self.assertEqual2(t[4], expected, eq=eq)
+
+    def checkInvalidParam(self, widget, name, value, errmsg=None,
+                          keep_orig=True):
+        orig = widget[name]
+        if errmsg is not None:
+            errmsg = errmsg.format(value)
+        with self.assertRaises(Tkinter.TclError) as cm:
+            widget[name] = value
+        if errmsg is not None:
+            self.assertEqual(str(cm.exception), errmsg)
+        if keep_orig:
+            self.assertEqual(widget[name], orig)
+        else:
+            widget[name] = orig
+        with self.assertRaises(Tkinter.TclError) as cm:
+            widget.configure({name: value})
+        if errmsg is not None:
+            self.assertEqual(str(cm.exception), errmsg)
+        if keep_orig:
+            self.assertEqual(widget[name], orig)
+        else:
+            widget[name] = orig
+
+    def checkParams(self, widget, name, *values, **kwargs):
+        for value in values:
+            self.checkParam(widget, name, value, **kwargs)
+
+    def checkIntegerParam(self, widget, name, *values, **kwargs):
+        self.checkParams(widget, name, *values, **kwargs)
+        self.checkInvalidParam(widget, name, '',
+                errmsg='expected integer but got ""')
+        self.checkInvalidParam(widget, name, '10p',
+                errmsg='expected integer but got "10p"')
+        self.checkInvalidParam(widget, name, 3.2,
+                errmsg='expected integer but got "3.2"')
+
+    def checkFloatParam(self, widget, name, *values, **kwargs):
+        if 'conv' in kwargs:
+            conv = kwargs.pop('conv')
+        else:
+            conv = float
+        for value in values:
+            self.checkParam(widget, name, value, conv=conv, **kwargs)
+        self.checkInvalidParam(widget, name, '',
+                errmsg='expected floating-point number but got ""')
+        self.checkInvalidParam(widget, name, 'spam',
+                errmsg='expected floating-point number but got "spam"')
+
+    def checkBooleanParam(self, widget, name):
+        for value in (False, 0, 'false', 'no', 'off'):
+            self.checkParam(widget, name, value, expected=0)
+        for value in (True, 1, 'true', 'yes', 'on'):
+            self.checkParam(widget, name, value, expected=1)
+        self.checkInvalidParam(widget, name, '',
+                errmsg='expected boolean value but got ""')
+        self.checkInvalidParam(widget, name, 'spam',
+                errmsg='expected boolean value but got "spam"')
+
+    def checkColorParam(self, widget, name, allow_empty=None, **kwargs):
+        self.checkParams(widget, name,
+                         '#ff0000', '#00ff00', '#0000ff', '#123456',
+                         'red', 'green', 'blue', 'white', 'black', 'grey',
+                         **kwargs)
+        self.checkInvalidParam(widget, name, 'spam',
+                errmsg='unknown color name "spam"')
+
+    def checkCursorParam(self, widget, name, **kwargs):
+        self.checkParams(widget, name, 'arrow', 'watch', 'cross', '',**kwargs)
+        if tcl_version >= (8, 5):
+            self.checkParam(widget, name, 'none')
+        self.checkInvalidParam(widget, name, 'spam',
+                errmsg='bad cursor spec "spam"')
+
+    def checkCommandParam(self, widget, name):
+        def command(*args):
+            pass
+        widget[name] = command
+        self.assertTrue(widget[name])
+        self.checkParams(widget, name, '')
+
+    def checkEnumParam(self, widget, name, *values, **kwargs):
+        if 'errmsg' in kwargs:
+            errmsg = kwargs.pop('errmsg')
+        else:
+            errmsg = None
+        self.checkParams(widget, name, *values, **kwargs)
+        if errmsg is None:
+            errmsg2 = ' %s "{}": must be %s%s or %s' % (
+                    name,
+                    ', '.join(values[:-1]),
+                    ',' if len(values) > 2 else '',
+                    values[-1])
+            self.checkInvalidParam(widget, name, '',
+                                   errmsg='ambiguous' + errmsg2)
+            errmsg = 'bad' + errmsg2
+        self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
+
+    def checkPixelsParam(self, widget, name, *values, **kwargs):
+        if 'conv' in kwargs:
+            conv = kwargs.pop('conv')
+        else:
+            conv = None
+        if conv is None:
+            conv = self._conv_pixels
+        if 'keep_orig' in kwargs:
+            keep_orig = kwargs.pop('keep_orig')
+        else:
+            keep_orig = True
+        for value in values:
+            expected = _sentinel
+            conv1 = conv
+            if isinstance(value, str):
+                if conv1 and conv1 is not str:
+                    expected = pixels_conv(value) * self.scaling
+                    conv1 = int_round
+            self.checkParam(widget, name, value, expected=expected,
+                            conv=conv1, **kwargs)
+        self.checkInvalidParam(widget, name, '6x',
+                errmsg='bad screen distance "6x"', keep_orig=keep_orig)
+        self.checkInvalidParam(widget, name, 'spam',
+                errmsg='bad screen distance "spam"', keep_orig=keep_orig)
+
+    def checkReliefParam(self, widget, name):
+        self.checkParams(widget, name,
+                         'flat', 'groove', 'raised', 'ridge', 'solid', 'sunken')
+        errmsg='bad relief "spam": must be '\
+               'flat, groove, raised, ridge, solid, or sunken'
+        if tcl_version < (8, 6):
+            errmsg = None
+        self.checkInvalidParam(widget, name, 'spam',
+                errmsg=errmsg)
+
+    def checkImageParam(self, widget, name):
+        image = Tkinter.PhotoImage('image1')
+        self.checkParam(widget, name, image, conv=str)
+        self.checkInvalidParam(widget, name, 'spam',
+                errmsg='image "spam" doesn\'t exist')
+        widget[name] = ''
+
+    def checkVariableParam(self, widget, name, var):
+        self.checkParam(widget, name, var, conv=str)
+
+
+class StandardOptionsTests(object):
+    STANDARD_OPTIONS = (
+        'activebackground', 'activeborderwidth', 'activeforeground', 'anchor',
+        'background', 'bitmap', 'borderwidth', 'compound', 'cursor',
+        'disabledforeground', 'exportselection', 'font', 'foreground',
+        'highlightbackground', 'highlightcolor', 'highlightthickness',
+        'image', 'insertbackground', 'insertborderwidth',
+        'insertofftime', 'insertontime', 'insertwidth',
+        'jump', 'justify', 'orient', 'padx', 'pady', 'relief',
+        'repeatdelay', 'repeatinterval',
+        'selectbackground', 'selectborderwidth', 'selectforeground',
+        'setgrid', 'takefocus', 'text', 'textvariable', 'troughcolor',
+        'underline', 'wraplength', 'xscrollcommand', 'yscrollcommand',
+    )
+
+    def test_activebackground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'activebackground')
+
+    def test_activeborderwidth(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'activeborderwidth',
+                              0, 1.3, 2.9, 6, -2, '10p')
+
+    def test_activeforeground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'activeforeground')
+
+    def test_anchor(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'anchor',
+                'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
+
+    def test_background(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'background')
+        if 'bg' in self.OPTIONS:
+            self.checkColorParam(widget, 'bg')
+
+    def test_bitmap(self):
+        widget = self.create()
+        self.checkParam(widget, 'bitmap', 'questhead')
+        self.checkParam(widget, 'bitmap', 'gray50')
+        self.checkInvalidParam(widget, 'bitmap', 'spam',
+                errmsg='bitmap "spam" not defined')
+
+    def test_borderwidth(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'borderwidth',
+                              0, 1.3, 2.6, 6, -2, '10p')
+        if 'bd' in self.OPTIONS:
+            self.checkPixelsParam(widget, 'bd', 0, 1.3, 2.6, 6, -2, '10p')
+
+    def test_compound(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'compound',
+                'bottom', 'center', 'left', 'none', 'right', 'top')
+
+    def test_cursor(self):
+        widget = self.create()
+        self.checkCursorParam(widget, 'cursor')
+
+    def test_disabledforeground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'disabledforeground')
+
+    def test_exportselection(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'exportselection')
+
+    def test_font(self):
+        widget = self.create()
+        self.checkParam(widget, 'font',
+                        '-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
+        self.checkInvalidParam(widget, 'font', '',
+                               errmsg='font "" doesn\'t exist')
+
+    def test_foreground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'foreground')
+        if 'fg' in self.OPTIONS:
+            self.checkColorParam(widget, 'fg')
+
+    def test_highlightbackground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'highlightbackground')
+
+    def test_highlightcolor(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'highlightcolor')
+
+    def test_highlightthickness(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'highlightthickness',
+                              0, 1.3, 2.6, 6, '10p')
+        self.checkParam(widget, 'highlightthickness', -2, expected=0,
+                        conv=self._conv_pixels)
+
+    def test_image(self):
+        widget = self.create()
+        self.checkImageParam(widget, 'image')
+
+    def test_insertbackground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'insertbackground')
+
+    def test_insertborderwidth(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'insertborderwidth',
+                              0, 1.3, 2.6, 6, -2, '10p')
+
+    def test_insertofftime(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'insertofftime', 100)
+
+    def test_insertontime(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'insertontime', 100)
+
+    def test_insertwidth(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'insertwidth', 1.3, 2.6, -2, '10p')
+
+    def test_jump(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'jump')
+
+    def test_justify(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'justify', 'left', 'right', 'center',
+                errmsg='bad justification "{}": must be '
+                       'left, right, or center')
+        self.checkInvalidParam(widget, 'justify', '',
+                errmsg='ambiguous justification "": must be '
+                       'left, right, or center')
+
+    def test_orient(self):
+        widget = self.create()
+        self.assertEqual(str(widget['orient']), self.default_orient)
+        self.checkEnumParam(widget, 'orient', 'horizontal', 'vertical')
+
+    def test_padx(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, -2, '12m',
+                              conv=self._conv_pad_pixels)
+
+    def test_pady(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, -2, '12m',
+                              conv=self._conv_pad_pixels)
+
+    def test_relief(self):
+        widget = self.create()
+        self.checkReliefParam(widget, 'relief')
+
+    def test_repeatdelay(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'repeatdelay', -500, 500)
+
+    def test_repeatinterval(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'repeatinterval', -500, 500)
+
+    def test_selectbackground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'selectbackground')
+
+    def test_selectborderwidth(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'selectborderwidth', 1.3, 2.6, -2, '10p')
+
+    def test_selectforeground(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'selectforeground')
+
+    def test_setgrid(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'setgrid')
+
+    def test_state(self):
+        widget = self.create()
+        self.checkEnumParam(widget, 'state', 'active', 'disabled', 'normal')
+
+    def test_takefocus(self):
+        widget = self.create()
+        self.checkParams(widget, 'takefocus', '0', '1', '')
+
+    def test_text(self):
+        widget = self.create()
+        self.checkParams(widget, 'text', '', 'any string')
+
+    def test_textvariable(self):
+        widget = self.create()
+        var = Tkinter.StringVar()
+        self.checkVariableParam(widget, 'textvariable', var)
+
+    def test_troughcolor(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'troughcolor')
+
+    def test_underline(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'underline', 0, 1, 10)
+
+    def test_wraplength(self):
+        widget = self.create()
+        if tcl_version < (8, 5):
+            self.checkPixelsParam(widget, 'wraplength', 100)
+        else:
+            self.checkParams(widget, 'wraplength', 100)
+
+    def test_xscrollcommand(self):
+        widget = self.create()
+        self.checkCommandParam(widget, 'xscrollcommand')
+
+    def test_yscrollcommand(self):
+        widget = self.create()
+        self.checkCommandParam(widget, 'yscrollcommand')
+
+    # non-standard but common options
+
+    def test_command(self):
+        widget = self.create()
+        self.checkCommandParam(widget, 'command')
+
+    def test_indicatoron(self):
+        widget = self.create()
+        self.checkBooleanParam(widget, 'indicatoron')
+
+    def test_offrelief(self):
+        widget = self.create()
+        self.checkReliefParam(widget, 'offrelief')
+
+    def test_overrelief(self):
+        widget = self.create()
+        self.checkReliefParam(widget, 'overrelief')
+
+    def test_selectcolor(self):
+        widget = self.create()
+        self.checkColorParam(widget, 'selectcolor')
+
+    def test_selectimage(self):
+        widget = self.create()
+        self.checkImageParam(widget, 'selectimage')
+
+    @requires_tcl(8, 5)
+    def test_tristateimage(self):
+        widget = self.create()
+        self.checkImageParam(widget, 'tristateimage')
+
+    @requires_tcl(8, 5)
+    def test_tristatevalue(self):
+        widget = self.create()
+        self.checkParam(widget, 'tristatevalue', 'unknowable')
+
+    def test_variable(self):
+        widget = self.create()
+        var = Tkinter.DoubleVar()
+        self.checkVariableParam(widget, 'variable', var)
+
+
+class IntegerSizeTests(object):
+    def test_height(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'height', 100, -100, 0)
+
+    def test_width(self):
+        widget = self.create()
+        self.checkIntegerParam(widget, 'width', 402, -402, 0)
+
+
+class PixelSizeTests(object):
+    def test_height(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '3c')
+
+    def test_width(self):
+        widget = self.create()
+        self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i')
+
+
+def add_standard_options(*source_classes):
+    # This decorator adds test_xxx methods from source classes for every xxx
+    # option in the OPTIONS class attribute if they are not defined explicitly.
+    def decorator(cls):
+        for option in cls.OPTIONS:
+            methodname = 'test_' + option
+            if not hasattr(cls, methodname):
+                for source_class in source_classes:
+                    if hasattr(source_class, methodname):
+                        setattr(cls, methodname,
+                                getattr(source_class, methodname).im_func)
+                        break
+                else:
+                    def test(self, option=option):
+                        widget = self.create()
+                        widget[option]
+                        raise AssertionError('Option "%s" is not tested in %s' %
+                                             (option, cls.__name__))
+                    test.__name__ = methodname
+                    setattr(cls, methodname, test)
+        return cls
+    return decorator
diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py
index 4d18600..04531b9 100644
--- a/Lib/multiprocessing/pool.py
+++ b/Lib/multiprocessing/pool.py
@@ -169,7 +169,8 @@
 
         self._task_handler = threading.Thread(
             target=Pool._handle_tasks,
-            args=(self._taskqueue, self._quick_put, self._outqueue, self._pool)
+            args=(self._taskqueue, self._quick_put, self._outqueue,
+                  self._pool, self._cache)
             )
         self._task_handler.daemon = True
         self._task_handler._state = RUN
@@ -329,7 +330,7 @@
         debug('worker handler exiting')
 
     @staticmethod
-    def _handle_tasks(taskqueue, put, outqueue, pool):
+    def _handle_tasks(taskqueue, put, outqueue, pool, cache):
         thread = threading.current_thread()
 
         for taskseq, set_length in iter(taskqueue.get, None):
@@ -340,9 +341,12 @@
                     break
                 try:
                     put(task)
-                except IOError:
-                    debug('could not put task on queue')
-                    break
+                except Exception as e:
+                    job, ind = task[:2]
+                    try:
+                        cache[job]._set(ind, (False, e))
+                    except KeyError:
+                        pass
             else:
                 if set_length:
                     debug('doing set_length()')
diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py
index bd40705..471753e 100644
--- a/Lib/sre_compile.py
+++ b/Lib/sre_compile.py
@@ -276,10 +276,10 @@
 # set is constructed. Then, this bitmap is sliced into chunks of 256
 # characters, duplicate chunks are eliminated, and each chunk is
 # given a number. In the compiled expression, the charset is
-# represented by a 16-bit word sequence, consisting of one word for
-# the number of different chunks, a sequence of 256 bytes (128 words)
+# represented by a 32-bit word sequence, consisting of one word for
+# the number of different chunks, a sequence of 256 bytes (64 words)
 # of chunk numbers indexed by their original chunk position, and a
-# sequence of chunks (16 words each).
+# sequence of 256-bit chunks (8 words each).
 
 # Compression is normally good: in a typical charset, large ranges of
 # Unicode will be either completely excluded (e.g. if only cyrillic
@@ -294,7 +294,7 @@
 
 # In UCS-4 mode, the BIGCHARSET opcode still supports only subsets
 # of the basic multilingual plane; an efficient representation
-# for all of UTF-16 has not yet been developed. This means,
+# for all of Unicode has not yet been developed. This means,
 # in particular, that negated charsets cannot be represented as
 # bigcharsets.
 
diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py
index 74dccbf..424a25c 100755
--- a/Lib/test/test_array.py
+++ b/Lib/test/test_array.py
@@ -9,6 +9,7 @@
 from weakref import proxy
 import array, cStringIO
 from cPickle import loads, dumps, HIGHEST_PROTOCOL
+import sys
 
 class ArraySubclass(array.array):
     pass
@@ -772,15 +773,15 @@
         s = None
         self.assertRaises(ReferenceError, len, p)
 
+    @unittest.skipUnless(hasattr(sys, 'getrefcount'),
+                         'test needs sys.getrefcount()')
     def test_bug_782369(self):
-        import sys
-        if hasattr(sys, "getrefcount"):
-            for i in range(10):
-                b = array.array('B', range(64))
-            rc = sys.getrefcount(10)
-            for i in range(10):
-                b = array.array('B', range(64))
-            self.assertEqual(rc, sys.getrefcount(10))
+        for i in range(10):
+            b = array.array('B', range(64))
+        rc = sys.getrefcount(10)
+        for i in range(10):
+            b = array.array('B', range(64))
+        self.assertEqual(rc, sys.getrefcount(10))
 
     def test_subclass_with_kwargs(self):
         # SF bug #1486663 -- this used to erroneously raise a TypeError
diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py
index bff6989..d3a26db 100644
--- a/Lib/test/test_compileall.py
+++ b/Lib/test/test_compileall.py
@@ -31,11 +31,10 @@
         compare = struct.pack('<4sl', imp.get_magic(), mtime)
         return data, compare
 
+    @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
     def recreation_check(self, metadata):
         """Check that compileall recreates bytecode when the new metadata is
         used."""
-        if not hasattr(os, 'stat'):
-            return
         py_compile.compile(self.source_path)
         self.assertEqual(*self.data())
         with open(self.bc_path, 'rb') as file:
diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py
index 3f82665..d3c1dec 100644
--- a/Lib/test/test_csv.py
+++ b/Lib/test/test_csv.py
@@ -1014,78 +1014,77 @@
         dialect = sniffer.sniff(self.sample9)
         self.assertTrue(dialect.doublequote)
 
-if not hasattr(sys, "gettotalrefcount"):
-    if test_support.verbose: print "*** skipping leakage tests ***"
-else:
-    class NUL:
-        def write(s, *args):
-            pass
-        writelines = write
+class NUL:
+    def write(s, *args):
+        pass
+    writelines = write
 
-    class TestLeaks(unittest.TestCase):
-        def test_create_read(self):
-            delta = 0
-            lastrc = sys.gettotalrefcount()
-            for i in xrange(20):
-                gc.collect()
-                self.assertEqual(gc.garbage, [])
-                rc = sys.gettotalrefcount()
-                csv.reader(["a,b,c\r\n"])
-                csv.reader(["a,b,c\r\n"])
-                csv.reader(["a,b,c\r\n"])
-                delta = rc-lastrc
-                lastrc = rc
-            # if csv.reader() leaks, last delta should be 3 or more
-            self.assertEqual(delta < 3, True)
+@unittest.skipUnless(hasattr(sys, "gettotalrefcount"),
+                     'requires sys.gettotalrefcount()')
+class TestLeaks(unittest.TestCase):
+    def test_create_read(self):
+        delta = 0
+        lastrc = sys.gettotalrefcount()
+        for i in xrange(20):
+            gc.collect()
+            self.assertEqual(gc.garbage, [])
+            rc = sys.gettotalrefcount()
+            csv.reader(["a,b,c\r\n"])
+            csv.reader(["a,b,c\r\n"])
+            csv.reader(["a,b,c\r\n"])
+            delta = rc-lastrc
+            lastrc = rc
+        # if csv.reader() leaks, last delta should be 3 or more
+        self.assertEqual(delta < 3, True)
 
-        def test_create_write(self):
-            delta = 0
-            lastrc = sys.gettotalrefcount()
-            s = NUL()
-            for i in xrange(20):
-                gc.collect()
-                self.assertEqual(gc.garbage, [])
-                rc = sys.gettotalrefcount()
-                csv.writer(s)
-                csv.writer(s)
-                csv.writer(s)
-                delta = rc-lastrc
-                lastrc = rc
-            # if csv.writer() leaks, last delta should be 3 or more
-            self.assertEqual(delta < 3, True)
+    def test_create_write(self):
+        delta = 0
+        lastrc = sys.gettotalrefcount()
+        s = NUL()
+        for i in xrange(20):
+            gc.collect()
+            self.assertEqual(gc.garbage, [])
+            rc = sys.gettotalrefcount()
+            csv.writer(s)
+            csv.writer(s)
+            csv.writer(s)
+            delta = rc-lastrc
+            lastrc = rc
+        # if csv.writer() leaks, last delta should be 3 or more
+        self.assertEqual(delta < 3, True)
 
-        def test_read(self):
-            delta = 0
-            rows = ["a,b,c\r\n"]*5
-            lastrc = sys.gettotalrefcount()
-            for i in xrange(20):
-                gc.collect()
-                self.assertEqual(gc.garbage, [])
-                rc = sys.gettotalrefcount()
-                rdr = csv.reader(rows)
-                for row in rdr:
-                    pass
-                delta = rc-lastrc
-                lastrc = rc
-            # if reader leaks during read, delta should be 5 or more
-            self.assertEqual(delta < 5, True)
+    def test_read(self):
+        delta = 0
+        rows = ["a,b,c\r\n"]*5
+        lastrc = sys.gettotalrefcount()
+        for i in xrange(20):
+            gc.collect()
+            self.assertEqual(gc.garbage, [])
+            rc = sys.gettotalrefcount()
+            rdr = csv.reader(rows)
+            for row in rdr:
+                pass
+            delta = rc-lastrc
+            lastrc = rc
+        # if reader leaks during read, delta should be 5 or more
+        self.assertEqual(delta < 5, True)
 
-        def test_write(self):
-            delta = 0
-            rows = [[1,2,3]]*5
-            s = NUL()
-            lastrc = sys.gettotalrefcount()
-            for i in xrange(20):
-                gc.collect()
-                self.assertEqual(gc.garbage, [])
-                rc = sys.gettotalrefcount()
-                writer = csv.writer(s)
-                for row in rows:
-                    writer.writerow(row)
-                delta = rc-lastrc
-                lastrc = rc
-            # if writer leaks during write, last delta should be 5 or more
-            self.assertEqual(delta < 5, True)
+    def test_write(self):
+        delta = 0
+        rows = [[1,2,3]]*5
+        s = NUL()
+        lastrc = sys.gettotalrefcount()
+        for i in xrange(20):
+            gc.collect()
+            self.assertEqual(gc.garbage, [])
+            rc = sys.gettotalrefcount()
+            writer = csv.writer(s)
+            for row in rows:
+                writer.writerow(row)
+            delta = rc-lastrc
+            lastrc = rc
+        # if writer leaks during write, last delta should be 5 or more
+        self.assertEqual(delta < 5, True)
 
 # commented out for now - csv module doesn't yet support Unicode
 ## class TestUnicode(unittest.TestCase):
diff --git a/Lib/test/test_enumerate.py b/Lib/test/test_enumerate.py
index 6b9ff79..aac4da7 100644
--- a/Lib/test/test_enumerate.py
+++ b/Lib/test/test_enumerate.py
@@ -188,11 +188,10 @@
         self.assertRaises(TypeError, reversed)
         self.assertRaises(TypeError, reversed, [], 'extra')
 
+    @unittest.skipUnless(hasattr(sys, 'getrefcount'), 'test needs sys.getrefcount()')
     def test_bug1229429(self):
         # this bug was never in reversed, it was in
         # PyObject_CallMethod, and reversed_new calls that sometimes.
-        if not hasattr(sys, "getrefcount"):
-            return
         def f():
             pass
         r = f.__reversed__ = object()
diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py
index 4060015..15cb336 100644
--- a/Lib/test/test_ftplib.py
+++ b/Lib/test/test_ftplib.py
@@ -15,7 +15,7 @@
 except ImportError:
     ssl = None
 
-from unittest import TestCase
+from unittest import TestCase, SkipTest, skipUnless
 from test import test_support
 from test.test_support import HOST, HOSTv6
 threading = test_support.import_module('threading')
@@ -579,8 +579,16 @@
         self.assertRaises(ftplib.Error, self.client.storlines, 'stor', f)
 
 
+@skipUnless(socket.has_ipv6, "IPv6 not enabled")
 class TestIPv6Environment(TestCase):
 
+    @classmethod
+    def setUpClass(cls):
+        try:
+            DummyFTPServer((HOST, 0), af=socket.AF_INET6)
+        except socket.error:
+            raise SkipTest("IPv6 not enabled")
+
     def setUp(self):
         self.server = DummyFTPServer((HOSTv6, 0), af=socket.AF_INET6)
         self.server.start()
@@ -615,6 +623,7 @@
         retr()
 
 
+@skipUnless(ssl, "SSL not available")
 class TestTLS_FTPClassMixin(TestFTPClass):
     """Repeat TestFTPClass tests starting the TLS layer for both control
     and data connections first.
@@ -630,6 +639,7 @@
         self.client.prot_p()
 
 
+@skipUnless(ssl, "SSL not available")
 class TestTLS_FTPClass(TestCase):
     """Specific TLS_FTP class tests."""
 
@@ -783,17 +793,9 @@
 
 
 def test_main():
-    tests = [TestFTPClass, TestTimeouts]
-    if socket.has_ipv6:
-        try:
-            DummyFTPServer((HOST, 0), af=socket.AF_INET6)
-        except socket.error:
-            pass
-        else:
-            tests.append(TestIPv6Environment)
-
-    if ssl is not None:
-        tests.extend([TestTLS_FTPClassMixin, TestTLS_FTPClass])
+    tests = [TestFTPClass, TestTimeouts,
+             TestIPv6Environment,
+             TestTLS_FTPClassMixin, TestTLS_FTPClass]
 
     thread_info = test_support.threading_setup()
     try:
diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py
index 8552e6f..07f45c6 100644
--- a/Lib/test/test_idle.py
+++ b/Lib/test/test_idle.py
@@ -23,6 +23,10 @@
 # load_tests() if it finds it. (Unittest.main does the same.)
 load_tests = idletest.load_tests
 
+# pre-3.3 regrtest does not support the load_tests protocol. use test_main
+def test_main():
+    support.run_unittest(unittest.TestLoader().loadTestsFromModule(idletest))
+
 if __name__ == '__main__':
     # Until unittest supports resources, we emulate regrtest's -ugui
     # so loaded tests run the same as if textually present here.
diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py
index 5e8e3c1..dbf6a58 100644
--- a/Lib/test/test_mailbox.py
+++ b/Lib/test/test_mailbox.py
@@ -772,10 +772,10 @@
         for msg in self._box:
             pass
 
+    @unittest.skipUnless(hasattr(os, 'umask'), 'test needs os.umask()')
+    @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
     def test_file_permissions(self):
         # Verify that message files are created without execute permissions
-        if not hasattr(os, "stat") or not hasattr(os, "umask"):
-            return
         msg = mailbox.MaildirMessage(self._template % 0)
         orig_umask = os.umask(0)
         try:
@@ -786,12 +786,11 @@
         mode = os.stat(path).st_mode
         self.assertEqual(mode & 0111, 0)
 
+    @unittest.skipUnless(hasattr(os, 'umask'), 'test needs os.umask()')
+    @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
     def test_folder_file_perms(self):
         # From bug #3228, we want to verify that the file created inside a Maildir
         # subfolder isn't marked as executable.
-        if not hasattr(os, "stat") or not hasattr(os, "umask"):
-            return
-
         orig_umask = os.umask(0)
         try:
             subfolder = self._box.add_folder('subfolder')
@@ -991,24 +990,25 @@
 
     _factory = lambda self, path, factory=None: mailbox.mbox(path, factory)
 
+    @unittest.skipUnless(hasattr(os, 'umask'), 'test needs os.umask()')
+    @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
     def test_file_perms(self):
         # From bug #3228, we want to verify that the mailbox file isn't executable,
         # even if the umask is set to something that would leave executable bits set.
         # We only run this test on platforms that support umask.
-        if hasattr(os, 'umask') and hasattr(os, 'stat'):
-            try:
-                old_umask = os.umask(0077)
-                self._box.close()
-                os.unlink(self._path)
-                self._box = mailbox.mbox(self._path, create=True)
-                self._box.add('')
-                self._box.close()
-            finally:
-                os.umask(old_umask)
+        try:
+            old_umask = os.umask(0077)
+            self._box.close()
+            os.unlink(self._path)
+            self._box = mailbox.mbox(self._path, create=True)
+            self._box.add('')
+            self._box.close()
+        finally:
+            os.umask(old_umask)
 
-            st = os.stat(self._path)
-            perms = st.st_mode
-            self.assertFalse((perms & 0111)) # Execute bits should all be off.
+        st = os.stat(self._path)
+        perms = st.st_mode
+        self.assertFalse((perms & 0111)) # Execute bits should all be off.
 
     def test_terminating_newline(self):
         message = email.message.Message()
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index a8677ce..c7f5752 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -906,38 +906,37 @@
     # still fails this part of the test on some platforms.  For now, we only
     # *run* test_exceptions() in verbose mode, so that this isn't normally
     # tested.
+    @unittest.skipUnless(verbose, 'requires verbose mode')
+    def test_exceptions(self):
+        try:
+            x = math.exp(-1000000000)
+        except:
+            # mathmodule.c is failing to weed out underflows from libm, or
+            # we've got an fp format with huge dynamic range
+            self.fail("underflowing exp() should not have raised "
+                        "an exception")
+        if x != 0:
+            self.fail("underflowing exp() should have returned 0")
 
-    if verbose:
-        def test_exceptions(self):
-            try:
-                x = math.exp(-1000000000)
-            except:
-                # mathmodule.c is failing to weed out underflows from libm, or
-                # we've got an fp format with huge dynamic range
-                self.fail("underflowing exp() should not have raised "
-                          "an exception")
-            if x != 0:
-                self.fail("underflowing exp() should have returned 0")
+        # If this fails, probably using a strict IEEE-754 conforming libm, and x
+        # is +Inf afterwards.  But Python wants overflows detected by default.
+        try:
+            x = math.exp(1000000000)
+        except OverflowError:
+            pass
+        else:
+            self.fail("overflowing exp() didn't trigger OverflowError")
 
-            # If this fails, probably using a strict IEEE-754 conforming libm, and x
-            # is +Inf afterwards.  But Python wants overflows detected by default.
-            try:
-                x = math.exp(1000000000)
-            except OverflowError:
-                pass
-            else:
-                self.fail("overflowing exp() didn't trigger OverflowError")
-
-            # If this fails, it could be a puzzle.  One odd possibility is that
-            # mathmodule.c's macros are getting confused while comparing
-            # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
-            # as a result (and so raising OverflowError instead).
-            try:
-                x = math.sqrt(-1.0)
-            except ValueError:
-                pass
-            else:
-                self.fail("sqrt(-1) didn't raise ValueError")
+        # If this fails, it could be a puzzle.  One odd possibility is that
+        # mathmodule.c's macros are getting confused while comparing
+        # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
+        # as a result (and so raising OverflowError instead).
+        try:
+            x = math.sqrt(-1.0)
+        except ValueError:
+            pass
+        else:
+            self.fail("sqrt(-1) didn't raise ValueError")
 
     @requires_IEEE_754
     def test_testfile(self):
diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index 9fd2184..62c65bd 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -320,26 +320,25 @@
         mf.close()
         f.close()
 
+    @unittest.skipUnless(hasattr(os, "stat"), "needs os.stat()")
     def test_entire_file(self):
         # test mapping of entire file by passing 0 for map length
-        if hasattr(os, "stat"):
-            f = open(TESTFN, "w+")
+        f = open(TESTFN, "w+")
 
-            f.write(2**16 * 'm') # Arbitrary character
-            f.close()
+        f.write(2**16 * 'm') # Arbitrary character
+        f.close()
 
-            f = open(TESTFN, "rb+")
-            mf = mmap.mmap(f.fileno(), 0)
-            self.assertEqual(len(mf), 2**16, "Map size should equal file size.")
-            self.assertEqual(mf.read(2**16), 2**16 * "m")
-            mf.close()
-            f.close()
+        f = open(TESTFN, "rb+")
+        mf = mmap.mmap(f.fileno(), 0)
+        self.assertEqual(len(mf), 2**16, "Map size should equal file size.")
+        self.assertEqual(mf.read(2**16), 2**16 * "m")
+        mf.close()
+        f.close()
 
+    @unittest.skipUnless(hasattr(os, "stat"), "needs os.stat()")
     def test_length_0_offset(self):
         # Issue #10916: test mapping of remainder of file by passing 0 for
         # map length with an offset doesn't cause a segfault.
-        if not hasattr(os, "stat"):
-            self.skipTest("needs os.stat")
         # NOTE: allocation granularity is currently 65536 under Win64,
         # and therefore the minimum offset alignment.
         with open(TESTFN, "wb") as f:
@@ -352,12 +351,10 @@
             finally:
                 mf.close()
 
+    @unittest.skipUnless(hasattr(os, "stat"), "needs os.stat()")
     def test_length_0_large_offset(self):
         # Issue #10959: test mapping of a file by passing 0 for
         # map length with a large offset doesn't cause a segfault.
-        if not hasattr(os, "stat"):
-            self.skipTest("needs os.stat")
-
         with open(TESTFN, "wb") as f:
             f.write(115699 * b'm') # Arbitrary character
 
@@ -538,9 +535,8 @@
                 return mmap.mmap.__new__(klass, -1, *args, **kwargs)
         anon_mmap(PAGESIZE)
 
+    @unittest.skipUnless(hasattr(mmap, 'PROT_READ'), "needs mmap.PROT_READ")
     def test_prot_readonly(self):
-        if not hasattr(mmap, 'PROT_READ'):
-            return
         mapsize = 10
         open(TESTFN, "wb").write("a"*mapsize)
         f = open(TESTFN, "rb")
@@ -584,66 +580,68 @@
         m.seek(8)
         self.assertRaises(ValueError, m.write, "bar")
 
-    if os.name == 'nt':
-        def test_tagname(self):
-            data1 = "0123456789"
-            data2 = "abcdefghij"
-            assert len(data1) == len(data2)
+    @unittest.skipUnless(os.name == 'nt', 'requires Windows')
+    def test_tagname(self):
+        data1 = "0123456789"
+        data2 = "abcdefghij"
+        assert len(data1) == len(data2)
 
-            # Test same tag
-            m1 = mmap.mmap(-1, len(data1), tagname="foo")
-            m1[:] = data1
-            m2 = mmap.mmap(-1, len(data2), tagname="foo")
-            m2[:] = data2
-            self.assertEqual(m1[:], data2)
-            self.assertEqual(m2[:], data2)
-            m2.close()
-            m1.close()
+        # Test same tag
+        m1 = mmap.mmap(-1, len(data1), tagname="foo")
+        m1[:] = data1
+        m2 = mmap.mmap(-1, len(data2), tagname="foo")
+        m2[:] = data2
+        self.assertEqual(m1[:], data2)
+        self.assertEqual(m2[:], data2)
+        m2.close()
+        m1.close()
 
-            # Test different tag
-            m1 = mmap.mmap(-1, len(data1), tagname="foo")
-            m1[:] = data1
-            m2 = mmap.mmap(-1, len(data2), tagname="boo")
-            m2[:] = data2
-            self.assertEqual(m1[:], data1)
-            self.assertEqual(m2[:], data2)
-            m2.close()
-            m1.close()
+        # Test different tag
+        m1 = mmap.mmap(-1, len(data1), tagname="foo")
+        m1[:] = data1
+        m2 = mmap.mmap(-1, len(data2), tagname="boo")
+        m2[:] = data2
+        self.assertEqual(m1[:], data1)
+        self.assertEqual(m2[:], data2)
+        m2.close()
+        m1.close()
 
-        def test_crasher_on_windows(self):
-            # Should not crash (Issue 1733986)
-            m = mmap.mmap(-1, 1000, tagname="foo")
-            try:
-                mmap.mmap(-1, 5000, tagname="foo")[:] # same tagname, but larger size
-            except:
-                pass
-            m.close()
+    @unittest.skipUnless(os.name == 'nt', 'requires Windows')
+    def test_crasher_on_windows(self):
+        # Should not crash (Issue 1733986)
+        m = mmap.mmap(-1, 1000, tagname="foo")
+        try:
+            mmap.mmap(-1, 5000, tagname="foo")[:] # same tagname, but larger size
+        except:
+            pass
+        m.close()
 
-            # Should not crash (Issue 5385)
-            open(TESTFN, "wb").write("x"*10)
-            f = open(TESTFN, "r+b")
-            m = mmap.mmap(f.fileno(), 0)
-            f.close()
-            try:
-                m.resize(0) # will raise WindowsError
-            except:
-                pass
-            try:
-                m[:]
-            except:
-                pass
-            m.close()
+        # Should not crash (Issue 5385)
+        open(TESTFN, "wb").write("x"*10)
+        f = open(TESTFN, "r+b")
+        m = mmap.mmap(f.fileno(), 0)
+        f.close()
+        try:
+            m.resize(0) # will raise WindowsError
+        except:
+            pass
+        try:
+            m[:]
+        except:
+            pass
+        m.close()
 
-        def test_invalid_descriptor(self):
-            # socket file descriptors are valid, but out of range
-            # for _get_osfhandle, causing a crash when validating the
-            # parameters to _get_osfhandle.
-            s = socket.socket()
-            try:
-                with self.assertRaises(mmap.error):
-                    m = mmap.mmap(s.fileno(), 10)
-            finally:
-                s.close()
+    @unittest.skipUnless(os.name == 'nt', 'requires Windows')
+    def test_invalid_descriptor(self):
+        # socket file descriptors are valid, but out of range
+        # for _get_osfhandle, causing a crash when validating the
+        # parameters to _get_osfhandle.
+        s = socket.socket()
+        try:
+            with self.assertRaises(mmap.error):
+                m = mmap.mmap(s.fileno(), 10)
+        finally:
+            s.close()
 
 
 class LargeMmapTests(unittest.TestCase):
diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py
index 579229a..a8928ee 100644
--- a/Lib/test/test_multiprocessing.py
+++ b/Lib/test/test_multiprocessing.py
@@ -1117,6 +1117,16 @@
         self.assertEqual(pmap(sqr, range(100), chunksize=20),
                          map(sqr, range(100)))
 
+    def test_map_unplicklable(self):
+        # Issue #19425 -- failure to pickle should not cause a hang
+        if self.TYPE == 'threads':
+            return
+        class A(object):
+            def __reduce__(self):
+                raise RuntimeError('cannot pickle')
+        with self.assertRaises(RuntimeError):
+            self.pool.map(sqr, [A()]*10)
+
     def test_map_chunksize(self):
         try:
             self.pool.map_async(sqr, [], chunksize=1).get(timeout=TIMEOUT1)
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 1d7e836..dd0696e 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -83,9 +83,8 @@
         open(name, "w")
         self.files.append(name)
 
+    @unittest.skipUnless(hasattr(os, 'tempnam'), 'test needs os.tempnam()')
     def test_tempnam(self):
-        if not hasattr(os, "tempnam"):
-            return
         with warnings.catch_warnings():
             warnings.filterwarnings("ignore", "tempnam", RuntimeWarning,
                                     r"test_os$")
@@ -99,9 +98,8 @@
             self.assertTrue(os.path.basename(name)[:3] == "pfx")
             self.check_tempfile(name)
 
+    @unittest.skipUnless(hasattr(os, 'tmpfile'), 'test needs os.tmpfile()')
     def test_tmpfile(self):
-        if not hasattr(os, "tmpfile"):
-            return
         # As with test_tmpnam() below, the Windows implementation of tmpfile()
         # attempts to create a file in the root directory of the current drive.
         # On Vista and Server 2008, this test will always fail for normal users
@@ -150,9 +148,8 @@
             fp.close()
             self.assertTrue(s == "foobar")
 
+    @unittest.skipUnless(hasattr(os, 'tmpnam'), 'test needs os.tmpnam()')
     def test_tmpnam(self):
-        if not hasattr(os, "tmpnam"):
-            return
         with warnings.catch_warnings():
             warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning,
                                     r"test_os$")
@@ -193,10 +190,8 @@
         os.unlink(self.fname)
         os.rmdir(test_support.TESTFN)
 
+    @unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
     def test_stat_attributes(self):
-        if not hasattr(os, "stat"):
-            return
-
         import stat
         result = os.stat(self.fname)
 
@@ -256,10 +251,8 @@
             pass
 
 
+    @unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()')
     def test_statvfs_attributes(self):
-        if not hasattr(os, "statvfs"):
-            return
-
         try:
             result = os.statvfs(self.fname)
         except OSError, e:
@@ -311,10 +304,10 @@
         st2 = os.stat(test_support.TESTFN)
         self.assertEqual(st2.st_mtime, int(st.st_mtime-delta))
 
-    # Restrict test to Win32, since there is no guarantee other
+    # Restrict tests to Win32, since there is no guarantee other
     # systems support centiseconds
-    if sys.platform == 'win32':
-        def get_file_system(path):
+    def get_file_system(path):
+        if sys.platform == 'win32':
             root = os.path.splitdrive(os.path.abspath(path))[0] + '\\'
             import ctypes
             kernel32 = ctypes.windll.kernel32
@@ -322,25 +315,31 @@
             if kernel32.GetVolumeInformationA(root, None, 0, None, None, None, buf, len(buf)):
                 return buf.value
 
-        if get_file_system(test_support.TESTFN) == "NTFS":
-            def test_1565150(self):
-                t1 = 1159195039.25
-                os.utime(self.fname, (t1, t1))
-                self.assertEqual(os.stat(self.fname).st_mtime, t1)
+    @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
+    @unittest.skipUnless(get_file_system(test_support.TESTFN) == "NTFS",
+                         "requires NTFS")
+    def test_1565150(self):
+        t1 = 1159195039.25
+        os.utime(self.fname, (t1, t1))
+        self.assertEqual(os.stat(self.fname).st_mtime, t1)
 
-            def test_large_time(self):
-                t1 = 5000000000 # some day in 2128
-                os.utime(self.fname, (t1, t1))
-                self.assertEqual(os.stat(self.fname).st_mtime, t1)
+    @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
+    @unittest.skipUnless(get_file_system(test_support.TESTFN) == "NTFS",
+                         "requires NTFS")
+    def test_large_time(self):
+        t1 = 5000000000 # some day in 2128
+        os.utime(self.fname, (t1, t1))
+        self.assertEqual(os.stat(self.fname).st_mtime, t1)
 
-        def test_1686475(self):
-            # Verify that an open file can be stat'ed
-            try:
-                os.stat(r"c:\pagefile.sys")
-            except WindowsError, e:
-                if e.errno == 2: # file does not exist; cannot run test
-                    return
-                self.fail("Could not stat pagefile.sys")
+    @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
+    def test_1686475(self):
+        # Verify that an open file can be stat'ed
+        try:
+            os.stat(r"c:\pagefile.sys")
+        except WindowsError, e:
+            if e.errno == 2: # file does not exist; cannot run test
+                return
+            self.fail("Could not stat pagefile.sys")
 
 from test import mapping_tests
 
@@ -598,6 +597,7 @@
         self.assertRaises(ValueError, os.execvpe, 'notepad', [], None)
 
 
+@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
 class Win32ErrorTests(unittest.TestCase):
     def test_rename(self):
         self.assertRaises(WindowsError, os.rename, test_support.TESTFN, test_support.TESTFN+".bak")
@@ -644,121 +644,118 @@
             self.fail("%r didn't raise a OSError with a bad file descriptor"
                       % f)
 
+    @unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()')
     def test_isatty(self):
-        if hasattr(os, "isatty"):
-            self.assertEqual(os.isatty(test_support.make_bad_fd()), False)
+        self.assertEqual(os.isatty(test_support.make_bad_fd()), False)
 
+    @unittest.skipUnless(hasattr(os, 'closerange'), 'test needs os.closerange()')
     def test_closerange(self):
-        if hasattr(os, "closerange"):
-            fd = test_support.make_bad_fd()
-            # Make sure none of the descriptors we are about to close are
-            # currently valid (issue 6542).
-            for i in range(10):
-                try: os.fstat(fd+i)
-                except OSError:
-                    pass
-                else:
-                    break
-            if i < 2:
-                raise unittest.SkipTest(
-                    "Unable to acquire a range of invalid file descriptors")
-            self.assertEqual(os.closerange(fd, fd + i-1), None)
+        fd = test_support.make_bad_fd()
+        # Make sure none of the descriptors we are about to close are
+        # currently valid (issue 6542).
+        for i in range(10):
+            try: os.fstat(fd+i)
+            except OSError:
+                pass
+            else:
+                break
+        if i < 2:
+            raise unittest.SkipTest(
+                "Unable to acquire a range of invalid file descriptors")
+        self.assertEqual(os.closerange(fd, fd + i-1), None)
 
+    @unittest.skipUnless(hasattr(os, 'dup2'), 'test needs os.dup2()')
     def test_dup2(self):
-        if hasattr(os, "dup2"):
-            self.check(os.dup2, 20)
+        self.check(os.dup2, 20)
 
+    @unittest.skipUnless(hasattr(os, 'fchmod'), 'test needs os.fchmod()')
     def test_fchmod(self):
-        if hasattr(os, "fchmod"):
-            self.check(os.fchmod, 0)
+        self.check(os.fchmod, 0)
 
+    @unittest.skipUnless(hasattr(os, 'fchown'), 'test needs os.fchown()')
     def test_fchown(self):
-        if hasattr(os, "fchown"):
-            self.check(os.fchown, -1, -1)
+        self.check(os.fchown, -1, -1)
 
+    @unittest.skipUnless(hasattr(os, 'fpathconf'), 'test needs os.fpathconf()')
     def test_fpathconf(self):
-        if hasattr(os, "fpathconf"):
-            self.check(os.fpathconf, "PC_NAME_MAX")
+        self.check(os.fpathconf, "PC_NAME_MAX")
 
+    @unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()')
     def test_ftruncate(self):
-        if hasattr(os, "ftruncate"):
-            self.check(os.ftruncate, 0)
+        self.check(os.ftruncate, 0)
 
+    @unittest.skipUnless(hasattr(os, 'lseek'), 'test needs os.lseek()')
     def test_lseek(self):
-        if hasattr(os, "lseek"):
-            self.check(os.lseek, 0, 0)
+        self.check(os.lseek, 0, 0)
 
+    @unittest.skipUnless(hasattr(os, 'read'), 'test needs os.read()')
     def test_read(self):
-        if hasattr(os, "read"):
-            self.check(os.read, 1)
+        self.check(os.read, 1)
 
+    @unittest.skipUnless(hasattr(os, 'tcsetpgrp'), 'test needs os.tcsetpgrp()')
     def test_tcsetpgrpt(self):
-        if hasattr(os, "tcsetpgrp"):
-            self.check(os.tcsetpgrp, 0)
+        self.check(os.tcsetpgrp, 0)
 
+    @unittest.skipUnless(hasattr(os, 'write'), 'test needs os.write()')
     def test_write(self):
-        if hasattr(os, "write"):
-            self.check(os.write, " ")
+        self.check(os.write, " ")
 
-if sys.platform != 'win32':
-    class Win32ErrorTests(unittest.TestCase):
-        pass
+@unittest.skipIf(sys.platform == "win32", "Posix specific tests")
+class PosixUidGidTests(unittest.TestCase):
+    @unittest.skipUnless(hasattr(os, 'setuid'), 'test needs os.setuid()')
+    def test_setuid(self):
+        if os.getuid() != 0:
+            self.assertRaises(os.error, os.setuid, 0)
+        self.assertRaises(OverflowError, os.setuid, 1<<32)
 
-    class PosixUidGidTests(unittest.TestCase):
-        if hasattr(os, 'setuid'):
-            def test_setuid(self):
-                if os.getuid() != 0:
-                    self.assertRaises(os.error, os.setuid, 0)
-                self.assertRaises(OverflowError, os.setuid, 1<<32)
+    @unittest.skipUnless(hasattr(os, 'setgid'), 'test needs os.setgid()')
+    def test_setgid(self):
+        if os.getuid() != 0:
+            self.assertRaises(os.error, os.setgid, 0)
+        self.assertRaises(OverflowError, os.setgid, 1<<32)
 
-        if hasattr(os, 'setgid'):
-            def test_setgid(self):
-                if os.getuid() != 0:
-                    self.assertRaises(os.error, os.setgid, 0)
-                self.assertRaises(OverflowError, os.setgid, 1<<32)
+    @unittest.skipUnless(hasattr(os, 'seteuid'), 'test needs os.seteuid()')
+    def test_seteuid(self):
+        if os.getuid() != 0:
+            self.assertRaises(os.error, os.seteuid, 0)
+        self.assertRaises(OverflowError, os.seteuid, 1<<32)
 
-        if hasattr(os, 'seteuid'):
-            def test_seteuid(self):
-                if os.getuid() != 0:
-                    self.assertRaises(os.error, os.seteuid, 0)
-                self.assertRaises(OverflowError, os.seteuid, 1<<32)
+    @unittest.skipUnless(hasattr(os, 'setegid'), 'test needs os.setegid()')
+    def test_setegid(self):
+        if os.getuid() != 0:
+            self.assertRaises(os.error, os.setegid, 0)
+        self.assertRaises(OverflowError, os.setegid, 1<<32)
 
-        if hasattr(os, 'setegid'):
-            def test_setegid(self):
-                if os.getuid() != 0:
-                    self.assertRaises(os.error, os.setegid, 0)
-                self.assertRaises(OverflowError, os.setegid, 1<<32)
+    @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
+    def test_setreuid(self):
+        if os.getuid() != 0:
+            self.assertRaises(os.error, os.setreuid, 0, 0)
+        self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
+        self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
 
-        if hasattr(os, 'setreuid'):
-            def test_setreuid(self):
-                if os.getuid() != 0:
-                    self.assertRaises(os.error, os.setreuid, 0, 0)
-                self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
-                self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
+    @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
+    def test_setreuid_neg1(self):
+        # Needs to accept -1.  We run this in a subprocess to avoid
+        # altering the test runner's process state (issue8045).
+        subprocess.check_call([
+                sys.executable, '-c',
+                'import os,sys;os.setreuid(-1,-1);sys.exit(0)'])
 
-            def test_setreuid_neg1(self):
-                # Needs to accept -1.  We run this in a subprocess to avoid
-                # altering the test runner's process state (issue8045).
-                subprocess.check_call([
-                        sys.executable, '-c',
-                        'import os,sys;os.setreuid(-1,-1);sys.exit(0)'])
+    @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()')
+    def test_setregid(self):
+        if os.getuid() != 0:
+            self.assertRaises(os.error, os.setregid, 0, 0)
+        self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
+        self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
 
-        if hasattr(os, 'setregid'):
-            def test_setregid(self):
-                if os.getuid() != 0:
-                    self.assertRaises(os.error, os.setregid, 0, 0)
-                self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
-                self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
+    @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()')
+    def test_setregid_neg1(self):
+        # Needs to accept -1.  We run this in a subprocess to avoid
+        # altering the test runner's process state (issue8045).
+        subprocess.check_call([
+                sys.executable, '-c',
+                'import os,sys;os.setregid(-1,-1);sys.exit(0)'])
 
-            def test_setregid_neg1(self):
-                # Needs to accept -1.  We run this in a subprocess to avoid
-                # altering the test runner's process state (issue8045).
-                subprocess.check_call([
-                        sys.executable, '-c',
-                        'import os,sys;os.setregid(-1,-1);sys.exit(0)'])
-else:
-    class PosixUidGidTests(unittest.TestCase):
-        pass
 
 @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
 class Win32KillTests(unittest.TestCase):
diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py
index 9505c22..e9b6daf 100644
--- a/Lib/test/test_poplib.py
+++ b/Lib/test/test_poplib.py
@@ -11,7 +11,7 @@
 import time
 import errno
 
-from unittest import TestCase
+from unittest import TestCase, skipUnless
 from test import test_support
 from test.test_support import HOST
 threading = test_support.import_module('threading')
@@ -263,17 +263,20 @@
             else:
                 DummyPOP3Handler.handle_read(self)
 
-    class TestPOP3_SSLClass(TestPOP3Class):
-        # repeat previous tests by using poplib.POP3_SSL
+requires_ssl = skipUnless(SUPPORTS_SSL, 'SSL not supported')
 
-        def setUp(self):
-            self.server = DummyPOP3Server((HOST, 0))
-            self.server.handler = DummyPOP3_SSLHandler
-            self.server.start()
-            self.client = poplib.POP3_SSL(self.server.host, self.server.port)
+@requires_ssl
+class TestPOP3_SSLClass(TestPOP3Class):
+    # repeat previous tests by using poplib.POP3_SSL
 
-        def test__all__(self):
-            self.assertIn('POP3_SSL', poplib.__all__)
+    def setUp(self):
+        self.server = DummyPOP3Server((HOST, 0))
+        self.server.handler = DummyPOP3_SSLHandler
+        self.server.start()
+        self.client = poplib.POP3_SSL(self.server.host, self.server.port)
+
+    def test__all__(self):
+        self.assertIn('POP3_SSL', poplib.__all__)
 
 
 class TestTimeouts(TestCase):
@@ -331,9 +334,8 @@
 
 
 def test_main():
-    tests = [TestPOP3Class, TestTimeouts]
-    if SUPPORTS_SSL:
-        tests.append(TestPOP3_SSLClass)
+    tests = [TestPOP3Class, TestTimeouts,
+             TestPOP3_SSLClass]
     thread_info = test_support.threading_setup()
     try:
         test_support.run_unittest(*tests)
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index b0a8cdf..b7f05b2 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -53,47 +53,55 @@
                     posix_func()
                     self.assertRaises(TypeError, posix_func, 1)
 
-    if hasattr(posix, 'getresuid'):
-        def test_getresuid(self):
-            user_ids = posix.getresuid()
-            self.assertEqual(len(user_ids), 3)
-            for val in user_ids:
-                self.assertGreaterEqual(val, 0)
+    @unittest.skipUnless(hasattr(posix, 'getresuid'),
+                         'test needs posix.getresuid()')
+    def test_getresuid(self):
+        user_ids = posix.getresuid()
+        self.assertEqual(len(user_ids), 3)
+        for val in user_ids:
+            self.assertGreaterEqual(val, 0)
 
-    if hasattr(posix, 'getresgid'):
-        def test_getresgid(self):
-            group_ids = posix.getresgid()
-            self.assertEqual(len(group_ids), 3)
-            for val in group_ids:
-                self.assertGreaterEqual(val, 0)
+    @unittest.skipUnless(hasattr(posix, 'getresgid'),
+                         'test needs posix.getresgid()')
+    def test_getresgid(self):
+        group_ids = posix.getresgid()
+        self.assertEqual(len(group_ids), 3)
+        for val in group_ids:
+            self.assertGreaterEqual(val, 0)
 
-    if hasattr(posix, 'setresuid'):
-        def test_setresuid(self):
-            current_user_ids = posix.getresuid()
-            self.assertIsNone(posix.setresuid(*current_user_ids))
-            # -1 means don't change that value.
-            self.assertIsNone(posix.setresuid(-1, -1, -1))
+    @unittest.skipUnless(hasattr(posix, 'setresuid'),
+                         'test needs posix.setresuid()')
+    def test_setresuid(self):
+        current_user_ids = posix.getresuid()
+        self.assertIsNone(posix.setresuid(*current_user_ids))
+        # -1 means don't change that value.
+        self.assertIsNone(posix.setresuid(-1, -1, -1))
 
-        def test_setresuid_exception(self):
-            # Don't do this test if someone is silly enough to run us as root.
-            current_user_ids = posix.getresuid()
-            if 0 not in current_user_ids:
-                new_user_ids = (current_user_ids[0]+1, -1, -1)
-                self.assertRaises(OSError, posix.setresuid, *new_user_ids)
+    @unittest.skipUnless(hasattr(posix, 'setresuid'),
+                         'test needs posix.setresuid()')
+    def test_setresuid_exception(self):
+        # Don't do this test if someone is silly enough to run us as root.
+        current_user_ids = posix.getresuid()
+        if 0 not in current_user_ids:
+            new_user_ids = (current_user_ids[0]+1, -1, -1)
+            self.assertRaises(OSError, posix.setresuid, *new_user_ids)
 
-    if hasattr(posix, 'setresgid'):
-        def test_setresgid(self):
-            current_group_ids = posix.getresgid()
-            self.assertIsNone(posix.setresgid(*current_group_ids))
-            # -1 means don't change that value.
-            self.assertIsNone(posix.setresgid(-1, -1, -1))
+    @unittest.skipUnless(hasattr(posix, 'setresgid'),
+                         'test needs posix.setresgid()')
+    def test_setresgid(self):
+        current_group_ids = posix.getresgid()
+        self.assertIsNone(posix.setresgid(*current_group_ids))
+        # -1 means don't change that value.
+        self.assertIsNone(posix.setresgid(-1, -1, -1))
 
-        def test_setresgid_exception(self):
-            # Don't do this test if someone is silly enough to run us as root.
-            current_group_ids = posix.getresgid()
-            if 0 not in current_group_ids:
-                new_group_ids = (current_group_ids[0]+1, -1, -1)
-                self.assertRaises(OSError, posix.setresgid, *new_group_ids)
+    @unittest.skipUnless(hasattr(posix, 'setresgid'),
+                         'test needs posix.setresgid()')
+    def test_setresgid_exception(self):
+        # Don't do this test if someone is silly enough to run us as root.
+        current_group_ids = posix.getresgid()
+        if 0 not in current_group_ids:
+            new_group_ids = (current_group_ids[0]+1, -1, -1)
+            self.assertRaises(OSError, posix.setresgid, *new_group_ids)
 
     @unittest.skipUnless(hasattr(posix, 'initgroups'),
                          "test needs os.initgroups()")
@@ -120,107 +128,118 @@
             else:
                 self.fail("Expected OSError to be raised by initgroups")
 
+    @unittest.skipUnless(hasattr(posix, 'statvfs'),
+                         'test needs posix.statvfs()')
     def test_statvfs(self):
-        if hasattr(posix, 'statvfs'):
-            self.assertTrue(posix.statvfs(os.curdir))
+        self.assertTrue(posix.statvfs(os.curdir))
 
+    @unittest.skipUnless(hasattr(posix, 'fstatvfs'),
+                         'test needs posix.fstatvfs()')
     def test_fstatvfs(self):
-        if hasattr(posix, 'fstatvfs'):
-            fp = open(test_support.TESTFN)
-            try:
-                self.assertTrue(posix.fstatvfs(fp.fileno()))
-            finally:
-                fp.close()
+        fp = open(test_support.TESTFN)
+        try:
+            self.assertTrue(posix.fstatvfs(fp.fileno()))
+        finally:
+            fp.close()
 
+    @unittest.skipUnless(hasattr(posix, 'ftruncate'),
+                         'test needs posix.ftruncate()')
     def test_ftruncate(self):
-        if hasattr(posix, 'ftruncate'):
-            fp = open(test_support.TESTFN, 'w+')
-            try:
-                # we need to have some data to truncate
-                fp.write('test')
-                fp.flush()
-                posix.ftruncate(fp.fileno(), 0)
-            finally:
-                fp.close()
+        fp = open(test_support.TESTFN, 'w+')
+        try:
+            # we need to have some data to truncate
+            fp.write('test')
+            fp.flush()
+            posix.ftruncate(fp.fileno(), 0)
+        finally:
+            fp.close()
 
+    @unittest.skipUnless(hasattr(posix, 'dup'),
+                         'test needs posix.dup()')
     def test_dup(self):
-        if hasattr(posix, 'dup'):
-            fp = open(test_support.TESTFN)
-            try:
-                fd = posix.dup(fp.fileno())
-                self.assertIsInstance(fd, int)
-                os.close(fd)
-            finally:
-                fp.close()
+        fp = open(test_support.TESTFN)
+        try:
+            fd = posix.dup(fp.fileno())
+            self.assertIsInstance(fd, int)
+            os.close(fd)
+        finally:
+            fp.close()
 
+    @unittest.skipUnless(hasattr(posix, 'confstr'),
+                         'test needs posix.confstr()')
     def test_confstr(self):
-        if hasattr(posix, 'confstr'):
-            self.assertRaises(ValueError, posix.confstr, "CS_garbage")
-            self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
+        self.assertRaises(ValueError, posix.confstr, "CS_garbage")
+        self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True)
 
+    @unittest.skipUnless(hasattr(posix, 'dup2'),
+                         'test needs posix.dup2()')
     def test_dup2(self):
-        if hasattr(posix, 'dup2'):
-            fp1 = open(test_support.TESTFN)
-            fp2 = open(test_support.TESTFN)
-            try:
-                posix.dup2(fp1.fileno(), fp2.fileno())
-            finally:
-                fp1.close()
-                fp2.close()
+        fp1 = open(test_support.TESTFN)
+        fp2 = open(test_support.TESTFN)
+        try:
+            posix.dup2(fp1.fileno(), fp2.fileno())
+        finally:
+            fp1.close()
+            fp2.close()
 
     def fdopen_helper(self, *args):
         fd = os.open(test_support.TESTFN, os.O_RDONLY)
         fp2 = posix.fdopen(fd, *args)
         fp2.close()
 
+    @unittest.skipUnless(hasattr(posix, 'fdopen'),
+                         'test needs posix.fdopen()')
     def test_fdopen(self):
-        if hasattr(posix, 'fdopen'):
-            self.fdopen_helper()
-            self.fdopen_helper('r')
-            self.fdopen_helper('r', 100)
+        self.fdopen_helper()
+        self.fdopen_helper('r')
+        self.fdopen_helper('r', 100)
 
+    @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'),
+                         'test needs posix.O_EXLOCK')
     def test_osexlock(self):
-        if hasattr(posix, "O_EXLOCK"):
+        fd = os.open(test_support.TESTFN,
+                     os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
+        self.assertRaises(OSError, os.open, test_support.TESTFN,
+                          os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
+        os.close(fd)
+
+        if hasattr(posix, "O_SHLOCK"):
             fd = os.open(test_support.TESTFN,
-                         os.O_WRONLY|os.O_EXLOCK|os.O_CREAT)
+                         os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
             self.assertRaises(OSError, os.open, test_support.TESTFN,
                               os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
             os.close(fd)
 
-            if hasattr(posix, "O_SHLOCK"):
-                fd = os.open(test_support.TESTFN,
-                             os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
-                self.assertRaises(OSError, os.open, test_support.TESTFN,
-                                  os.O_WRONLY|os.O_EXLOCK|os.O_NONBLOCK)
-                os.close(fd)
-
+    @unittest.skipUnless(hasattr(posix, 'O_SHLOCK'),
+                         'test needs posix.O_SHLOCK')
     def test_osshlock(self):
-        if hasattr(posix, "O_SHLOCK"):
-            fd1 = os.open(test_support.TESTFN,
+        fd1 = os.open(test_support.TESTFN,
+                      os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
+        fd2 = os.open(test_support.TESTFN,
+                      os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
+        os.close(fd2)
+        os.close(fd1)
+
+        if hasattr(posix, "O_EXLOCK"):
+            fd = os.open(test_support.TESTFN,
                          os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
-            fd2 = os.open(test_support.TESTFN,
-                          os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
-            os.close(fd2)
-            os.close(fd1)
+            self.assertRaises(OSError, os.open, test_support.TESTFN,
+                              os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
+            os.close(fd)
 
-            if hasattr(posix, "O_EXLOCK"):
-                fd = os.open(test_support.TESTFN,
-                             os.O_WRONLY|os.O_SHLOCK|os.O_CREAT)
-                self.assertRaises(OSError, os.open, test_support.TESTFN,
-                                  os.O_RDONLY|os.O_EXLOCK|os.O_NONBLOCK)
-                os.close(fd)
-
+    @unittest.skipUnless(hasattr(posix, 'fstat'),
+                         'test needs posix.fstat()')
     def test_fstat(self):
-        if hasattr(posix, 'fstat'):
-            fp = open(test_support.TESTFN)
-            try:
-                self.assertTrue(posix.fstat(fp.fileno()))
-            finally:
-                fp.close()
+        fp = open(test_support.TESTFN)
+        try:
+            self.assertTrue(posix.fstat(fp.fileno()))
+        finally:
+            fp.close()
 
+    @unittest.skipUnless(hasattr(posix, 'stat'),
+                         'test needs posix.stat()')
     def test_stat(self):
-        if hasattr(posix, 'stat'):
-            self.assertTrue(posix.stat(test_support.TESTFN))
+        self.assertTrue(posix.stat(test_support.TESTFN))
 
     def _test_all_chown_common(self, chown_func, first_param, stat_func):
         """Common code for chown, fchown and lchown tests."""
@@ -313,59 +332,62 @@
         self._test_all_chown_common(posix.lchown, test_support.TESTFN,
                                     getattr(posix, 'lstat', None))
 
+    @unittest.skipUnless(hasattr(posix, 'chdir'), 'test needs posix.chdir()')
     def test_chdir(self):
-        if hasattr(posix, 'chdir'):
-            posix.chdir(os.curdir)
-            self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
+        posix.chdir(os.curdir)
+        self.assertRaises(OSError, posix.chdir, test_support.TESTFN)
 
+    @unittest.skipUnless(hasattr(posix, 'lsdir'), 'test needs posix.lsdir()')
     def test_lsdir(self):
-        if hasattr(posix, 'lsdir'):
-            self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
+        self.assertIn(test_support.TESTFN, posix.lsdir(os.curdir))
 
+    @unittest.skipUnless(hasattr(posix, 'access'), 'test needs posix.access()')
     def test_access(self):
-        if hasattr(posix, 'access'):
-            self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
+        self.assertTrue(posix.access(test_support.TESTFN, os.R_OK))
 
+    @unittest.skipUnless(hasattr(posix, 'umask'), 'test needs posix.umask()')
     def test_umask(self):
-        if hasattr(posix, 'umask'):
-            old_mask = posix.umask(0)
-            self.assertIsInstance(old_mask, int)
-            posix.umask(old_mask)
+        old_mask = posix.umask(0)
+        self.assertIsInstance(old_mask, int)
+        posix.umask(old_mask)
 
+    @unittest.skipUnless(hasattr(posix, 'strerror'),
+                         'test needs posix.strerror()')
     def test_strerror(self):
-        if hasattr(posix, 'strerror'):
-            self.assertTrue(posix.strerror(0))
+        self.assertTrue(posix.strerror(0))
 
+    @unittest.skipUnless(hasattr(posix, 'pipe'), 'test needs posix.pipe()')
     def test_pipe(self):
-        if hasattr(posix, 'pipe'):
-            reader, writer = posix.pipe()
-            os.close(reader)
-            os.close(writer)
+        reader, writer = posix.pipe()
+        os.close(reader)
+        os.close(writer)
 
+    @unittest.skipUnless(hasattr(posix, 'tempnam'),
+                         'test needs posix.tempnam()')
     def test_tempnam(self):
-        if hasattr(posix, 'tempnam'):
-            with warnings.catch_warnings():
-                warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
-                self.assertTrue(posix.tempnam())
-                self.assertTrue(posix.tempnam(os.curdir))
-                self.assertTrue(posix.tempnam(os.curdir, 'blah'))
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", "tempnam", DeprecationWarning)
+            self.assertTrue(posix.tempnam())
+            self.assertTrue(posix.tempnam(os.curdir))
+            self.assertTrue(posix.tempnam(os.curdir, 'blah'))
 
+    @unittest.skipUnless(hasattr(posix, 'tmpfile'),
+                         'test needs posix.tmpfile()')
     def test_tmpfile(self):
-        if hasattr(posix, 'tmpfile'):
-            with warnings.catch_warnings():
-                warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
-                fp = posix.tmpfile()
-                fp.close()
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", "tmpfile", DeprecationWarning)
+            fp = posix.tmpfile()
+            fp.close()
 
+    @unittest.skipUnless(hasattr(posix, 'utime'), 'test needs posix.utime()')
     def test_utime(self):
-        if hasattr(posix, 'utime'):
-            now = time.time()
-            posix.utime(test_support.TESTFN, None)
-            self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
-            self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
-            self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
-            posix.utime(test_support.TESTFN, (int(now), int(now)))
-            posix.utime(test_support.TESTFN, (now, now))
+        now = time.time()
+        posix.utime(test_support.TESTFN, None)
+        self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, None))
+        self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (now, None))
+        self.assertRaises(TypeError, posix.utime, test_support.TESTFN, (None, now))
+        posix.utime(test_support.TESTFN, (int(now), int(now)))
+        posix.utime(test_support.TESTFN, (now, now))
 
     def _test_chflags_regular_file(self, chflags_func, target_file):
         st = os.stat(target_file)
@@ -428,56 +450,57 @@
         finally:
             posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags)
 
+    @unittest.skipUnless(hasattr(posix, 'getcwd'),
+                         'test needs posix.getcwd()')
     def test_getcwd_long_pathnames(self):
-        if hasattr(posix, 'getcwd'):
-            dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
-            curdir = os.getcwd()
-            base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
+        dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
+        curdir = os.getcwd()
+        base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
 
-            try:
-                os.mkdir(base_path)
-                os.chdir(base_path)
-            except:
-#               Just returning nothing instead of the SkipTest exception,
-#               because the test results in Error in that case.
-#               Is that ok?
-#                raise unittest.SkipTest, "cannot create directory for testing"
-                return
+        try:
+            os.mkdir(base_path)
+            os.chdir(base_path)
+        except:
+#           Just returning nothing instead of the SkipTest exception,
+#           because the test results in Error in that case.
+#           Is that ok?
+#            raise unittest.SkipTest, "cannot create directory for testing"
+            return
 
-            try:
-                def _create_and_do_getcwd(dirname, current_path_length = 0):
-                    try:
-                        os.mkdir(dirname)
-                    except:
-                        raise unittest.SkipTest, "mkdir cannot create directory sufficiently deep for getcwd test"
+        try:
+            def _create_and_do_getcwd(dirname, current_path_length = 0):
+                try:
+                    os.mkdir(dirname)
+                except:
+                    raise unittest.SkipTest, "mkdir cannot create directory sufficiently deep for getcwd test"
 
-                    os.chdir(dirname)
-                    try:
-                        os.getcwd()
-                        if current_path_length < 4099:
-                            _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
-                    except OSError as e:
-                        expected_errno = errno.ENAMETOOLONG
-                        # The following platforms have quirky getcwd()
-                        # behaviour -- see issue 9185 and 15765 for
-                        # more information.
-                        quirky_platform = (
-                            'sunos' in sys.platform or
-                            'netbsd' in sys.platform or
-                            'openbsd' in sys.platform
-                        )
-                        if quirky_platform:
-                            expected_errno = errno.ERANGE
-                        self.assertEqual(e.errno, expected_errno)
-                    finally:
-                        os.chdir('..')
-                        os.rmdir(dirname)
+                os.chdir(dirname)
+                try:
+                    os.getcwd()
+                    if current_path_length < 4099:
+                        _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
+                except OSError as e:
+                    expected_errno = errno.ENAMETOOLONG
+                    # The following platforms have quirky getcwd()
+                    # behaviour -- see issue 9185 and 15765 for
+                    # more information.
+                    quirky_platform = (
+                        'sunos' in sys.platform or
+                        'netbsd' in sys.platform or
+                        'openbsd' in sys.platform
+                    )
+                    if quirky_platform:
+                        expected_errno = errno.ERANGE
+                    self.assertEqual(e.errno, expected_errno)
+                finally:
+                    os.chdir('..')
+                    os.rmdir(dirname)
 
-                _create_and_do_getcwd(dirname)
+            _create_and_do_getcwd(dirname)
 
-            finally:
-                os.chdir(curdir)
-                shutil.rmtree(base_path)
+        finally:
+            os.chdir(curdir)
+            shutil.rmtree(base_path)
 
     @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
     def test_getgroups(self):
@@ -522,7 +545,7 @@
             posix.initgroups(name, self.saved_groups[0])
 
     @unittest.skipUnless(hasattr(posix, 'initgroups'),
-                         "test needs posix.initgroups()")
+                         'test needs posix.initgroups()')
     def test_initgroups(self):
         # find missing group
 
@@ -532,7 +555,7 @@
         self.assertIn(g, posix.getgroups())
 
     @unittest.skipUnless(hasattr(posix, 'setgroups'),
-                         "test needs posix.setgroups()")
+                         'test needs posix.setgroups()')
     def test_setgroups(self):
         for groups in [[0], range(16)]:
             posix.setgroups(groups)
diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py
index 8db26ed..9db7394 100644
--- a/Lib/test/test_set.py
+++ b/Lib/test/test_set.py
@@ -561,10 +561,10 @@
         s = None
         self.assertRaises(ReferenceError, str, p)
 
-    # C API test only available in a debug build
-    if hasattr(set, "test_c_api"):
-        def test_c_api(self):
-            self.assertEqual(set().test_c_api(), True)
+    @unittest.skipUnless(hasattr(set, "test_c_api"),
+                         'C API test only available in a debug build')
+    def test_c_api(self):
+        self.assertEqual(set().test_c_api(), True)
 
 class SetSubclass(set):
     pass
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index 9bdb724..8f1abd8 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -78,33 +78,34 @@
         filename = tempfile.mktemp()
         self.assertRaises(OSError, shutil.rmtree, filename)
 
-    # See bug #1071513 for why we don't run this on cygwin
-    # and bug #1076467 for why we don't run this as root.
-    if (hasattr(os, 'chmod') and sys.platform[:6] != 'cygwin'
-        and not (hasattr(os, 'geteuid') and os.geteuid() == 0)):
-        def test_on_error(self):
-            self.errorState = 0
-            os.mkdir(TESTFN)
-            self.childpath = os.path.join(TESTFN, 'a')
-            f = open(self.childpath, 'w')
-            f.close()
-            old_dir_mode = os.stat(TESTFN).st_mode
-            old_child_mode = os.stat(self.childpath).st_mode
-            # Make unwritable.
-            os.chmod(self.childpath, stat.S_IREAD)
-            os.chmod(TESTFN, stat.S_IREAD)
+    @unittest.skipUnless(hasattr(os, 'chmod'), 'requires os.chmod()')
+    @unittest.skipIf(sys.platform[:6] == 'cygwin',
+                     "This test can't be run on Cygwin (issue #1071513).")
+    @unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
+                     "This test can't be run reliably as root (issue #1076467).")
+    def test_on_error(self):
+        self.errorState = 0
+        os.mkdir(TESTFN)
+        self.childpath = os.path.join(TESTFN, 'a')
+        f = open(self.childpath, 'w')
+        f.close()
+        old_dir_mode = os.stat(TESTFN).st_mode
+        old_child_mode = os.stat(self.childpath).st_mode
+        # Make unwritable.
+        os.chmod(self.childpath, stat.S_IREAD)
+        os.chmod(TESTFN, stat.S_IREAD)
 
-            shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror)
-            # Test whether onerror has actually been called.
-            self.assertEqual(self.errorState, 2,
-                             "Expected call to onerror function did not happen.")
+        shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror)
+        # Test whether onerror has actually been called.
+        self.assertEqual(self.errorState, 2,
+                            "Expected call to onerror function did not happen.")
 
-            # Make writable again.
-            os.chmod(TESTFN, old_dir_mode)
-            os.chmod(self.childpath, old_child_mode)
+        # Make writable again.
+        os.chmod(TESTFN, old_dir_mode)
+        os.chmod(self.childpath, old_child_mode)
 
-            # Clean up.
-            shutil.rmtree(TESTFN)
+        # Clean up.
+        shutil.rmtree(TESTFN)
 
     def check_args_to_onerror(self, func, arg, exc):
         # test_rmtree_errors deliberately runs rmtree
@@ -308,37 +309,38 @@
             finally:
                 shutil.rmtree(TESTFN, ignore_errors=True)
 
-    if hasattr(os, "mkfifo"):
-        # Issue #3002: copyfile and copytree block indefinitely on named pipes
-        def test_copyfile_named_pipe(self):
-            os.mkfifo(TESTFN)
-            try:
-                self.assertRaises(shutil.SpecialFileError,
-                                  shutil.copyfile, TESTFN, TESTFN2)
-                self.assertRaises(shutil.SpecialFileError,
-                                  shutil.copyfile, __file__, TESTFN)
-            finally:
-                os.remove(TESTFN)
+    # Issue #3002: copyfile and copytree block indefinitely on named pipes
+    @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
+    def test_copyfile_named_pipe(self):
+        os.mkfifo(TESTFN)
+        try:
+            self.assertRaises(shutil.SpecialFileError,
+                              shutil.copyfile, TESTFN, TESTFN2)
+            self.assertRaises(shutil.SpecialFileError,
+                              shutil.copyfile, __file__, TESTFN)
+        finally:
+            os.remove(TESTFN)
 
-        def test_copytree_named_pipe(self):
-            os.mkdir(TESTFN)
+    @unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
+    def test_copytree_named_pipe(self):
+        os.mkdir(TESTFN)
+        try:
+            subdir = os.path.join(TESTFN, "subdir")
+            os.mkdir(subdir)
+            pipe = os.path.join(subdir, "mypipe")
+            os.mkfifo(pipe)
             try:
-                subdir = os.path.join(TESTFN, "subdir")
-                os.mkdir(subdir)
-                pipe = os.path.join(subdir, "mypipe")
-                os.mkfifo(pipe)
-                try:
-                    shutil.copytree(TESTFN, TESTFN2)
-                except shutil.Error as e:
-                    errors = e.args[0]
-                    self.assertEqual(len(errors), 1)
-                    src, dst, error_msg = errors[0]
-                    self.assertEqual("`%s` is a named pipe" % pipe, error_msg)
-                else:
-                    self.fail("shutil.Error should have been raised")
-            finally:
-                shutil.rmtree(TESTFN, ignore_errors=True)
-                shutil.rmtree(TESTFN2, ignore_errors=True)
+                shutil.copytree(TESTFN, TESTFN2)
+            except shutil.Error as e:
+                errors = e.args[0]
+                self.assertEqual(len(errors), 1)
+                src, dst, error_msg = errors[0]
+                self.assertEqual("`%s` is a named pipe" % pipe, error_msg)
+            else:
+                self.fail("shutil.Error should have been raised")
+        finally:
+            shutil.rmtree(TESTFN, ignore_errors=True)
+            shutil.rmtree(TESTFN2, ignore_errors=True)
 
     @unittest.skipUnless(hasattr(os, 'chflags') and
                          hasattr(errno, 'EOPNOTSUPP') and
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index aef9b1a..53c8b2f 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -343,16 +343,17 @@
         if not fqhn in all_host_names:
             self.fail("Error testing host resolution mechanisms. (fqdn: %s, all: %s)" % (fqhn, repr(all_host_names)))
 
+    @unittest.skipUnless(hasattr(sys, 'getrefcount'),
+                         'test needs sys.getrefcount()')
     def testRefCountGetNameInfo(self):
         # Testing reference count for getnameinfo
-        if hasattr(sys, "getrefcount"):
-            try:
-                # On some versions, this loses a reference
-                orig = sys.getrefcount(__name__)
-                socket.getnameinfo(__name__,0)
-            except TypeError:
-                self.assertEqual(sys.getrefcount(__name__), orig,
-                                 "socket.getnameinfo loses a reference")
+        try:
+            # On some versions, this loses a reference
+            orig = sys.getrefcount(__name__)
+            socket.getnameinfo(__name__,0)
+        except TypeError:
+            self.assertEqual(sys.getrefcount(__name__), orig,
+                             "socket.getnameinfo loses a reference")
 
     def testInterpreterCrash(self):
         # Making sure getnameinfo doesn't crash the interpreter
@@ -459,17 +460,17 @@
         # Check that setting it to an invalid type raises TypeError
         self.assertRaises(TypeError, socket.setdefaulttimeout, "spam")
 
+    @unittest.skipUnless(hasattr(socket, 'inet_aton'),
+                         'test needs socket.inet_aton()')
     def testIPv4_inet_aton_fourbytes(self):
-        if not hasattr(socket, 'inet_aton'):
-            return  # No inet_aton, nothing to check
         # Test that issue1008086 and issue767150 are fixed.
         # It must return 4 bytes.
         self.assertEqual('\x00'*4, socket.inet_aton('0.0.0.0'))
         self.assertEqual('\xff'*4, socket.inet_aton('255.255.255.255'))
 
+    @unittest.skipUnless(hasattr(socket, 'inet_pton'),
+                         'test needs socket.inet_pton()')
     def testIPv4toString(self):
-        if not hasattr(socket, 'inet_pton'):
-            return # No inet_pton() on this platform
         from socket import inet_aton as f, inet_pton, AF_INET
         g = lambda a: inet_pton(AF_INET, a)
 
@@ -484,9 +485,9 @@
         self.assertEqual('\xaa\xaa\xaa\xaa', g('170.170.170.170'))
         self.assertEqual('\xff\xff\xff\xff', g('255.255.255.255'))
 
+    @unittest.skipUnless(hasattr(socket, 'inet_pton'),
+                         'test needs socket.inet_pton()')
     def testIPv6toString(self):
-        if not hasattr(socket, 'inet_pton'):
-            return # No inet_pton() on this platform
         try:
             from socket import inet_pton, AF_INET6, has_ipv6
             if not has_ipv6:
@@ -503,9 +504,9 @@
             f('45ef:76cb:1a:56ef:afeb:bac:1924:aeae')
         )
 
+    @unittest.skipUnless(hasattr(socket, 'inet_ntop'),
+                         'test needs socket.inet_ntop()')
     def testStringToIPv4(self):
-        if not hasattr(socket, 'inet_ntop'):
-            return # No inet_ntop() on this platform
         from socket import inet_ntoa as f, inet_ntop, AF_INET
         g = lambda a: inet_ntop(AF_INET, a)
 
@@ -518,9 +519,9 @@
         self.assertEqual('170.85.170.85', g('\xaa\x55\xaa\x55'))
         self.assertEqual('255.255.255.255', g('\xff\xff\xff\xff'))
 
+    @unittest.skipUnless(hasattr(socket, 'inet_ntop'),
+                         'test needs socket.inet_ntop()')
     def testStringToIPv6(self):
-        if not hasattr(socket, 'inet_ntop'):
-            return # No inet_ntop() on this platform
         try:
             from socket import inet_ntop, AF_INET6, has_ipv6
             if not has_ipv6:
@@ -871,6 +872,8 @@
         self.cli.connect((HOST, self.port))
         time.sleep(1.0)
 
+@unittest.skipUnless(hasattr(socket, 'socketpair'),
+                     'test needs socket.socketpair()')
 @unittest.skipUnless(thread, 'Threading required for this test.')
 class BasicSocketPairTest(SocketPairTest):
 
@@ -1456,12 +1459,12 @@
         if not ok:
             self.fail("accept() returned success when we did not expect it")
 
+    @unittest.skipUnless(hasattr(signal, 'alarm'),
+                         'test needs signal.alarm()')
     def testInterruptedTimeout(self):
         # XXX I don't know how to do this test on MSWindows or any other
         # plaform that doesn't support signal.alarm() or os.kill(), though
         # the bug should have existed on all platforms.
-        if not hasattr(signal, "alarm"):
-            return                  # can only test on *nix
         self.serv.settimeout(5.0)   # must be longer than alarm
         class Alarm(Exception):
             pass
@@ -1521,6 +1524,7 @@
         self.assertTrue(issubclass(socket.gaierror, socket.error))
         self.assertTrue(issubclass(socket.timeout, socket.error))
 
+@unittest.skipUnless(sys.platform == 'linux', 'Linux specific test')
 class TestLinuxAbstractNamespace(unittest.TestCase):
 
     UNIX_PATH_MAX = 108
@@ -1635,11 +1639,11 @@
         for line in f:
             if line.startswith("tipc "):
                 return True
-    if test_support.verbose:
-        print "TIPC module is not loaded, please 'sudo modprobe tipc'"
     return False
 
-class TIPCTest (unittest.TestCase):
+@unittest.skipUnless(isTipcAvailable(),
+                     "TIPC module is not loaded, please 'sudo modprobe tipc'")
+class TIPCTest(unittest.TestCase):
     def testRDM(self):
         srv = socket.socket(socket.AF_TIPC, socket.SOCK_RDM)
         cli = socket.socket(socket.AF_TIPC, socket.SOCK_RDM)
@@ -1659,7 +1663,9 @@
         self.assertEqual(msg, MSG)
 
 
-class TIPCThreadableTest (unittest.TestCase, ThreadableTest):
+@unittest.skipUnless(isTipcAvailable(),
+                     "TIPC module is not loaded, please 'sudo modprobe tipc'")
+class TIPCThreadableTest(unittest.TestCase, ThreadableTest):
     def __init__(self, methodName = 'runTest'):
         unittest.TestCase.__init__(self, methodName = methodName)
         ThreadableTest.__init__(self)
@@ -1712,13 +1718,9 @@
         NetworkConnectionAttributesTest,
         NetworkConnectionBehaviourTest,
     ])
-    if hasattr(socket, "socketpair"):
-        tests.append(BasicSocketPairTest)
-    if sys.platform == 'linux2':
-        tests.append(TestLinuxAbstractNamespace)
-    if isTipcAvailable():
-        tests.append(TIPCTest)
-        tests.append(TIPCThreadableTest)
+    tests.append(BasicSocketPairTest)
+    tests.append(TestLinuxAbstractNamespace)
+    tests.extend([TIPCTest, TIPCThreadableTest])
 
     thread_info = test_support.threading_setup()
     test_support.run_unittest(*tests)
diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py
index 0dbb8e2..83f5e3f 100644
--- a/Lib/test/test_socketserver.py
+++ b/Lib/test/test_socketserver.py
@@ -27,7 +27,10 @@
 HOST = test.test_support.HOST
 
 HAVE_UNIX_SOCKETS = hasattr(socket, "AF_UNIX")
+requires_unix_sockets = unittest.skipUnless(HAVE_UNIX_SOCKETS,
+                                            'requires Unix sockets')
 HAVE_FORKING = hasattr(os, "fork") and os.name != "os2"
+requires_forking = unittest.skipUnless(HAVE_FORKING, 'requires forking')
 
 def signal_alarm(n):
     """Call signal.alarm when it exists (i.e. not on Windows)."""
@@ -188,31 +191,33 @@
                         SocketServer.StreamRequestHandler,
                         self.stream_examine)
 
-    if HAVE_FORKING:
-        def test_ForkingTCPServer(self):
-            with simple_subprocess(self):
-                self.run_server(SocketServer.ForkingTCPServer,
-                                SocketServer.StreamRequestHandler,
-                                self.stream_examine)
-
-    if HAVE_UNIX_SOCKETS:
-        def test_UnixStreamServer(self):
-            self.run_server(SocketServer.UnixStreamServer,
+    @requires_forking
+    def test_ForkingTCPServer(self):
+        with simple_subprocess(self):
+            self.run_server(SocketServer.ForkingTCPServer,
                             SocketServer.StreamRequestHandler,
                             self.stream_examine)
 
-        def test_ThreadingUnixStreamServer(self):
-            self.run_server(SocketServer.ThreadingUnixStreamServer,
+    @requires_unix_sockets
+    def test_UnixStreamServer(self):
+        self.run_server(SocketServer.UnixStreamServer,
+                        SocketServer.StreamRequestHandler,
+                        self.stream_examine)
+
+    @requires_unix_sockets
+    def test_ThreadingUnixStreamServer(self):
+        self.run_server(SocketServer.ThreadingUnixStreamServer,
+                        SocketServer.StreamRequestHandler,
+                        self.stream_examine)
+
+    @requires_unix_sockets
+    @requires_forking
+    def test_ForkingUnixStreamServer(self):
+        with simple_subprocess(self):
+            self.run_server(ForkingUnixStreamServer,
                             SocketServer.StreamRequestHandler,
                             self.stream_examine)
 
-        if HAVE_FORKING:
-            def test_ForkingUnixStreamServer(self):
-                with simple_subprocess(self):
-                    self.run_server(ForkingUnixStreamServer,
-                                    SocketServer.StreamRequestHandler,
-                                    self.stream_examine)
-
     def test_UDPServer(self):
         self.run_server(SocketServer.UDPServer,
                         SocketServer.DatagramRequestHandler,
@@ -223,12 +228,12 @@
                         SocketServer.DatagramRequestHandler,
                         self.dgram_examine)
 
-    if HAVE_FORKING:
-        def test_ForkingUDPServer(self):
-            with simple_subprocess(self):
-                self.run_server(SocketServer.ForkingUDPServer,
-                                SocketServer.DatagramRequestHandler,
-                                self.dgram_examine)
+    @requires_forking
+    def test_ForkingUDPServer(self):
+        with simple_subprocess(self):
+            self.run_server(SocketServer.ForkingUDPServer,
+                            SocketServer.DatagramRequestHandler,
+                            self.dgram_examine)
 
     @contextlib.contextmanager
     def mocked_select_module(self):
@@ -265,22 +270,24 @@
     # Alas, on Linux (at least) recvfrom() doesn't return a meaningful
     # client address so this cannot work:
 
-    # if HAVE_UNIX_SOCKETS:
-    #     def test_UnixDatagramServer(self):
-    #         self.run_server(SocketServer.UnixDatagramServer,
-    #                         SocketServer.DatagramRequestHandler,
-    #                         self.dgram_examine)
+    # @requires_unix_sockets
+    # def test_UnixDatagramServer(self):
+    #     self.run_server(SocketServer.UnixDatagramServer,
+    #                     SocketServer.DatagramRequestHandler,
+    #                     self.dgram_examine)
     #
-    #     def test_ThreadingUnixDatagramServer(self):
-    #         self.run_server(SocketServer.ThreadingUnixDatagramServer,
-    #                         SocketServer.DatagramRequestHandler,
-    #                         self.dgram_examine)
+    # @requires_unix_sockets
+    # def test_ThreadingUnixDatagramServer(self):
+    #     self.run_server(SocketServer.ThreadingUnixDatagramServer,
+    #                     SocketServer.DatagramRequestHandler,
+    #                     self.dgram_examine)
     #
-    #     if HAVE_FORKING:
-    #         def test_ForkingUnixDatagramServer(self):
-    #             self.run_server(SocketServer.ForkingUnixDatagramServer,
-    #                             SocketServer.DatagramRequestHandler,
-    #                             self.dgram_examine)
+    # @requires_unix_sockets
+    # @requires_forking
+    # def test_ForkingUnixDatagramServer(self):
+    #     self.run_server(SocketServer.ForkingUnixDatagramServer,
+    #                     SocketServer.DatagramRequestHandler,
+    #                     self.dgram_examine)
 
     @reap_threads
     def test_shutdown(self):
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index 1f3c039..e3dd712 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -271,6 +271,36 @@
         # is exited) but there is a .pyo file.
         unlink(os.path.join(dirname, modname + os.extsep + 'pyo'))
 
+# On some platforms, should not run gui test even if it is allowed
+# in `use_resources'.
+if sys.platform.startswith('win'):
+    import ctypes
+    import ctypes.wintypes
+    def _is_gui_available():
+        UOI_FLAGS = 1
+        WSF_VISIBLE = 0x0001
+        class USEROBJECTFLAGS(ctypes.Structure):
+            _fields_ = [("fInherit", ctypes.wintypes.BOOL),
+                        ("fReserved", ctypes.wintypes.BOOL),
+                        ("dwFlags", ctypes.wintypes.DWORD)]
+        dll = ctypes.windll.user32
+        h = dll.GetProcessWindowStation()
+        if not h:
+            raise ctypes.WinError()
+        uof = USEROBJECTFLAGS()
+        needed = ctypes.wintypes.DWORD()
+        res = dll.GetUserObjectInformationW(h,
+            UOI_FLAGS,
+            ctypes.byref(uof),
+            ctypes.sizeof(uof),
+            ctypes.byref(needed))
+        if not res:
+            raise ctypes.WinError()
+        return bool(uof.dwFlags & WSF_VISIBLE)
+else:
+    def _is_gui_available():
+        return True
+
 def is_resource_enabled(resource):
     """Test whether a resource is enabled.  Known resources are set by
     regrtest.py."""
@@ -281,6 +311,8 @@
 
     If the caller's module is __main__ then automatically return True.  The
     possibility of False being returned occurs when regrtest.py is executing."""
+    if resource == 'gui' and not _is_gui_available():
+        raise unittest.SkipTest("Cannot use the 'gui' resource")
     # see if the caller's module is __main__ - if so, treat as if
     # the resource was set
     if sys._getframe(1).f_globals.get("__name__") == "__main__":
@@ -1128,6 +1160,8 @@
     return obj
 
 def requires_resource(resource):
+    if resource == 'gui' and not _is_gui_available():
+        return unittest.skip("resource 'gui' is not available")
     if is_resource_enabled(resource):
         return _id
     else:
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index fbea655..fcca676 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -266,15 +266,16 @@
         #  still has 5 elements
         maj, min, buildno, plat, csd = sys.getwindowsversion()
 
+    @unittest.skipUnless(hasattr(sys, "setdlopenflags"),
+                         'test needs sys.setdlopenflags()')
     def test_dlopenflags(self):
-        if hasattr(sys, "setdlopenflags"):
-            self.assertTrue(hasattr(sys, "getdlopenflags"))
-            self.assertRaises(TypeError, sys.getdlopenflags, 42)
-            oldflags = sys.getdlopenflags()
-            self.assertRaises(TypeError, sys.setdlopenflags)
-            sys.setdlopenflags(oldflags+1)
-            self.assertEqual(sys.getdlopenflags(), oldflags+1)
-            sys.setdlopenflags(oldflags)
+        self.assertTrue(hasattr(sys, "getdlopenflags"))
+        self.assertRaises(TypeError, sys.getdlopenflags, 42)
+        oldflags = sys.getdlopenflags()
+        self.assertRaises(TypeError, sys.setdlopenflags)
+        sys.setdlopenflags(oldflags+1)
+        self.assertEqual(sys.getdlopenflags(), oldflags+1)
+        sys.setdlopenflags(oldflags)
 
     def test_refcount(self):
         # n here must be a global in order for this test to pass while
diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py
index 50e1ac4..0ccede1 100644
--- a/Lib/test/test_tcl.py
+++ b/Lib/test/test_tcl.py
@@ -138,18 +138,15 @@
         tcl = self.interp
         self.assertRaises(TclError,tcl.eval,'package require DNE')
 
+    @unittest.skipUnless(sys.platform == 'win32', "only applies to Windows")
     def testLoadWithUNC(self):
-        import sys
-        if sys.platform != 'win32':
-            return
-
         # Build a UNC path from the regular path.
         # Something like
         #   \\%COMPUTERNAME%\c$\python27\python.exe
 
         fullname = os.path.abspath(sys.executable)
         if fullname[1] != ':':
-            return
+            self.skipTest('unusable path: %r' % fullname)
         unc_name = r'\\%s\%s$\%s' % (os.environ['COMPUTERNAME'],
                                     fullname[0],
                                     fullname[3:])
@@ -158,7 +155,14 @@
             env.unset("TCL_LIBRARY")
             cmd = '%s -c "import Tkinter; print Tkinter"' % (unc_name,)
 
-            p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+            try:
+                p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+            except WindowsError as e:
+                if e.winerror == 5:
+                    self.skipTest('Not permitted to start the child process')
+                else:
+                    raise
+
             out_data, err_data = p.communicate()
 
             msg = '\n\n'.join(['"Tkinter.py" not in output',
diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py
index e502ed8..e4850a4 100644
--- a/Lib/test/test_warnings.py
+++ b/Lib/test/test_warnings.py
@@ -259,11 +259,10 @@
         finally:
             warning_tests.__file__ = filename
 
+    @unittest.skipUnless(hasattr(sys, 'argv'), 'test needs sys.argv')
     def test_missing_filename_main_with_argv(self):
         # If __file__ is not specified and the caller is __main__ and sys.argv
         # exists, then use sys.argv[0] as the file.
-        if not hasattr(sys, 'argv'):
-            return
         filename = warning_tests.__file__
         module_name = warning_tests.__name__
         try:
diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py
index f3dffd6..fb62081 100644
--- a/Lib/test/test_zlib.py
+++ b/Lib/test/test_zlib.py
@@ -12,6 +12,13 @@
 
 zlib = import_module('zlib')
 
+requires_Compress_copy = unittest.skipUnless(
+        hasattr(zlib.compressobj(), "copy"),
+        'requires Compress.copy()')
+requires_Decompress_copy = unittest.skipUnless(
+        hasattr(zlib.decompressobj(), "copy"),
+        'requires Decompress.copy()')
+
 
 class ChecksumTestCase(unittest.TestCase):
     # checksum test cases
@@ -339,39 +346,39 @@
                                         "mode=%i, level=%i") % (sync, level))
                 del obj
 
+    @unittest.skipUnless(hasattr(zlib, 'Z_SYNC_FLUSH'),
+                         'requires zlib.Z_SYNC_FLUSH')
     def test_odd_flush(self):
         # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
         import random
+        # Testing on 17K of "random" data
 
-        if hasattr(zlib, 'Z_SYNC_FLUSH'):
-            # Testing on 17K of "random" data
+        # Create compressor and decompressor objects
+        co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
+        dco = zlib.decompressobj()
 
-            # Create compressor and decompressor objects
-            co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
-            dco = zlib.decompressobj()
-
-            # Try 17K of data
-            # generate random data stream
+        # Try 17K of data
+        # generate random data stream
+        try:
+            # In 2.3 and later, WichmannHill is the RNG of the bug report
+            gen = random.WichmannHill()
+        except AttributeError:
             try:
-                # In 2.3 and later, WichmannHill is the RNG of the bug report
-                gen = random.WichmannHill()
+                # 2.2 called it Random
+                gen = random.Random()
             except AttributeError:
-                try:
-                    # 2.2 called it Random
-                    gen = random.Random()
-                except AttributeError:
-                    # others might simply have a single RNG
-                    gen = random
-            gen.seed(1)
-            data = genblock(1, 17 * 1024, generator=gen)
+                # others might simply have a single RNG
+                gen = random
+        gen.seed(1)
+        data = genblock(1, 17 * 1024, generator=gen)
 
-            # compress, sync-flush, and decompress
-            first = co.compress(data)
-            second = co.flush(zlib.Z_SYNC_FLUSH)
-            expanded = dco.decompress(first + second)
+        # compress, sync-flush, and decompress
+        first = co.compress(data)
+        second = co.flush(zlib.Z_SYNC_FLUSH)
+        expanded = dco.decompress(first + second)
 
-            # if decompressed data is different from the input data, choke.
-            self.assertEqual(expanded, data, "17K random source doesn't match")
+        # if decompressed data is different from the input data, choke.
+        self.assertEqual(expanded, data, "17K random source doesn't match")
 
     def test_empty_flush(self):
         # Test that calling .flush() on unused objects works.
@@ -408,35 +415,36 @@
         data = zlib.compress(input2)
         self.assertEqual(dco.flush(), input1[1:])
 
-    if hasattr(zlib.compressobj(), "copy"):
-        def test_compresscopy(self):
-            # Test copying a compression object
-            data0 = HAMLET_SCENE
-            data1 = HAMLET_SCENE.swapcase()
-            c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
-            bufs0 = []
-            bufs0.append(c0.compress(data0))
+    @requires_Compress_copy
+    def test_compresscopy(self):
+        # Test copying a compression object
+        data0 = HAMLET_SCENE
+        data1 = HAMLET_SCENE.swapcase()
+        c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
+        bufs0 = []
+        bufs0.append(c0.compress(data0))
 
-            c1 = c0.copy()
-            bufs1 = bufs0[:]
+        c1 = c0.copy()
+        bufs1 = bufs0[:]
 
-            bufs0.append(c0.compress(data0))
-            bufs0.append(c0.flush())
-            s0 = ''.join(bufs0)
+        bufs0.append(c0.compress(data0))
+        bufs0.append(c0.flush())
+        s0 = ''.join(bufs0)
 
-            bufs1.append(c1.compress(data1))
-            bufs1.append(c1.flush())
-            s1 = ''.join(bufs1)
+        bufs1.append(c1.compress(data1))
+        bufs1.append(c1.flush())
+        s1 = ''.join(bufs1)
 
-            self.assertEqual(zlib.decompress(s0),data0+data0)
-            self.assertEqual(zlib.decompress(s1),data0+data1)
+        self.assertEqual(zlib.decompress(s0),data0+data0)
+        self.assertEqual(zlib.decompress(s1),data0+data1)
 
-        def test_badcompresscopy(self):
-            # Test copying a compression object in an inconsistent state
-            c = zlib.compressobj()
-            c.compress(HAMLET_SCENE)
-            c.flush()
-            self.assertRaises(ValueError, c.copy)
+    @requires_Compress_copy
+    def test_badcompresscopy(self):
+        # Test copying a compression object in an inconsistent state
+        c = zlib.compressobj()
+        c.compress(HAMLET_SCENE)
+        c.flush()
+        self.assertRaises(ValueError, c.copy)
 
     def test_decompress_unused_data(self):
         # Repeated calls to decompress() after EOF should accumulate data in
@@ -463,35 +471,36 @@
                 self.assertEqual(dco.unconsumed_tail, b'')
                 self.assertEqual(dco.unused_data, remainder)
 
-    if hasattr(zlib.decompressobj(), "copy"):
-        def test_decompresscopy(self):
-            # Test copying a decompression object
-            data = HAMLET_SCENE
-            comp = zlib.compress(data)
+    @requires_Decompress_copy
+    def test_decompresscopy(self):
+        # Test copying a decompression object
+        data = HAMLET_SCENE
+        comp = zlib.compress(data)
 
-            d0 = zlib.decompressobj()
-            bufs0 = []
-            bufs0.append(d0.decompress(comp[:32]))
+        d0 = zlib.decompressobj()
+        bufs0 = []
+        bufs0.append(d0.decompress(comp[:32]))
 
-            d1 = d0.copy()
-            bufs1 = bufs0[:]
+        d1 = d0.copy()
+        bufs1 = bufs0[:]
 
-            bufs0.append(d0.decompress(comp[32:]))
-            s0 = ''.join(bufs0)
+        bufs0.append(d0.decompress(comp[32:]))
+        s0 = ''.join(bufs0)
 
-            bufs1.append(d1.decompress(comp[32:]))
-            s1 = ''.join(bufs1)
+        bufs1.append(d1.decompress(comp[32:]))
+        s1 = ''.join(bufs1)
 
-            self.assertEqual(s0,s1)
-            self.assertEqual(s0,data)
+        self.assertEqual(s0,s1)
+        self.assertEqual(s0,data)
 
-        def test_baddecompresscopy(self):
-            # Test copying a compression object in an inconsistent state
-            data = zlib.compress(HAMLET_SCENE)
-            d = zlib.decompressobj()
-            d.decompress(data)
-            d.flush()
-            self.assertRaises(ValueError, d.copy)
+    @requires_Decompress_copy
+    def test_baddecompresscopy(self):
+        # Test copying a compression object in an inconsistent state
+        data = zlib.compress(HAMLET_SCENE)
+        d = zlib.decompressobj()
+        d.decompress(data)
+        d.flush()
+        self.assertRaises(ValueError, d.copy)
 
     # Memory use of the following functions takes into account overallocation
 
diff --git a/Makefile.pre.in b/Makefile.pre.in
index cf75650..0439193 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -939,7 +939,8 @@
 		logging bsddb bsddb/test csv importlib wsgiref \
 		lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \
 		lib2to3/tests/data lib2to3/tests/data/fixers lib2to3/tests/data/fixers/myfixes \
-		ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \
+		ctypes ctypes/test ctypes/macholib \
+		idlelib idlelib/Icons idlelib/idle_test \
 		distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \
 		multiprocessing multiprocessing/dummy \
 		unittest unittest/test \
diff --git a/Misc/NEWS b/Misc/NEWS
index c353571..07d1ea4 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1,6 +1,43 @@
 Python News
 +++++++++++
 
+What's New in Python 2.7.7?
+===========================
+
+*Release date: XXXX-XX-XX*
+
+Core and Builtins
+-----------------
+
+Library
+-------
+
+- Issue #17827: Add the missing documentation for ``codecs.encode`` and
+    ``codecs.decode``.
+
+- Issue #6157: Fixed Tkinter.Text.debug().  Original patch by Guilherme Polo.
+
+- Issue #6160: The bbox() method of tkinter.Spinbox now returns a tuple of
+  integers instead of a string.  Based on patch by Guilherme Polo.
+
+- Issue #19286: Directories in ``package_data`` are no longer added to
+  the filelist, preventing failure outlined in the ticket.
+
+Tests
+-----
+
+- Issue #17883: Tweak test_tcl testLoadWithUNC to skip the test in the
+  event of a permission error on Windows and to properly report other
+  skip conditions.
+
+- Issue #17883: Backported _is_gui_available() in test.test_support to
+  avoid hanging Windows buildbots on test_ttk_guionly.
+
+- Issue #18702: All skipped tests now reported as skipped.
+
+- Issue #19085: Added basic tests for all tkinter widget options.
+
+
 Whats' New in Python 2.7.6?
 ===========================
 
diff --git a/Modules/_sre.c b/Modules/_sre.c
index a7103cc..bf802a6 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -2753,8 +2753,7 @@
     \_________\_____/        /
                \____________/
 
-   It also helps that SRE_CODE is always an unsigned type, either 2 bytes or 4
-   bytes wide (the latter if Python is compiled for "wide" unicode support).
+   It also helps that SRE_CODE is always an unsigned type.
 */
 
 /* Defining this one enables tracing of the validator */
diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt
index 00b50ec..b96fef2 100644
--- a/PCbuild/readme.txt
+++ b/PCbuild/readme.txt
@@ -1,7 +1,7 @@
 Building Python using VC++ 9.0
 ------------------------------
 
-This directory is used to build Python for Win32 and x64 platforms, e.g. 
+This directory is used to build Python for Win32 and x64 platforms, e.g.
 Windows 2000, XP, Vista and Windows Server 2008.  In order to build 32-bit
 debug and release executables, Microsoft Visual C++ 2008 Express Edition is
 required at the very least.  In order to build 64-bit debug and release
@@ -27,7 +27,7 @@
 
 The solution is configured to build the projects in the correct order. "Build
 Solution" or F7 takes care of dependencies except for x64 builds. To make
-cross compiling x64 builds on a 32bit OS possible the x64 builds require a 
+cross compiling x64 builds on a 32bit OS possible the x64 builds require a
 32bit version of Python.
 
 NOTE:
@@ -37,7 +37,7 @@
    running a Python core buildbot test slave; see SUBPROJECTS below)
 
 When using the Debug setting, the output files have a _d added to
-their name:  python30_d.dll, python_d.exe, parser_d.pyd, and so on. Both
+their name:  python27_d.dll, python_d.exe, parser_d.pyd, and so on. Both
 the build and rt batch files accept a -d option for debug builds.
 
 The 32bit builds end up in the solution folder PCbuild while the x64 builds
@@ -47,7 +47,7 @@
 Legacy support
 --------------
 
-You can find build directories for older versions of Visual Studio and 
+You can find build directories for older versions of Visual Studio and
 Visual C++ in the PC directory. The legacy build directories are no longer
 actively maintained and may not work out of the box.
 
@@ -64,7 +64,7 @@
 
 Visual Studio 2008 uses version 9 of the C runtime (MSVCRT9).  The executables
 are linked to a CRT "side by side" assembly which must be present on the target
-machine.  This is avalible under the VC/Redist folder of your visual studio
+machine.  This is available under the VC/Redist folder of your visual studio
 distribution. On XP and later operating systems that support
 side-by-side assemblies it is not enough to have the msvcrt90.dll present,
 it has to be there as a whole assembly, that is, a folder with the .dll
@@ -105,16 +105,16 @@
 Python-controlled subprojects that wrap external projects:
 _bsddb
     Wraps Berkeley DB 4.7.25, which is currently built by _bsddb.vcproj.
-    project (see below).
+    project.
 _sqlite3
-    Wraps SQLite 3.6.21, which is currently built by sqlite3.vcproj (see below).
+    Wraps SQLite 3.6.21, which is currently built by sqlite3.vcproj.
 _tkinter
     Wraps the Tk windowing system.  Unlike _bsddb and _sqlite3, there's no
     corresponding tcltk.vcproj-type project that builds Tcl/Tk from vcproj's
     within our pcbuild.sln, which means this module expects to find a
     pre-built Tcl/Tk in either ..\..\tcltk for 32-bit or ..\..\tcltk64 for
     64-bit (relative to this directory).  See below for instructions to build
-    Tcl/Tk. 
+    Tcl/Tk.
 bz2
     Python wrapper for the libbz2 compression library.  Homepage
         http://sources.redhat.com/bzip2/
@@ -127,16 +127,6 @@
     obtaining external sources then you don't need to manually get the source
     above via subversion. **
 
-    A custom pre-link step in the bz2 project settings should manage to
-    build bzip2-1.0.6\libbz2.lib by magic before bz2.pyd (or bz2_d.pyd) is
-    linked in PCbuild\.
-    However, the bz2 project is not smart enough to remove anything under
-    bzip2-1.0.6\ when you do a clean, so if you want to rebuild bzip2.lib
-    you need to clean up bzip2-1.0.6\ by hand.
-
-    All of this managed to build libbz2.lib in 
-    bzip2-1.0.6\$platform-$configuration\, which the Python project links in.
-
 _ssl
     Python wrapper for the secure sockets library.
 
@@ -154,18 +144,16 @@
 
     You must install the NASM assembler from
         http://nasm.sf.net
-    for x86 builds.  Put nasmw.exe anywhere in your PATH.
-    Note: recent releases of nasm only have nasm.exe. Just rename it to 
-    nasmw.exe.
+    for x86 builds.  Put nasm.exe anywhere in your PATH.
 
     You can also install ActivePerl from
         http://www.activestate.com/activeperl/
-    if you like to use the official sources instead of the files from 
+    if you like to use the official sources instead of the files from
     python's subversion repository. The svn version contains pre-build
     makefiles and assembly files.
 
     The build process makes sure that no patented algorithms are included.
-    For now RC5, MDC2 and IDEA are excluded from the build. You may have 
+    For now RC5, MDC2 and IDEA are excluded from the build. You may have
     to manually remove $(OBJ_D)\i_*.obj from ms\nt.mak if the build process
     complains about missing files or forbidden IDEA. Again the files provided
     in the subversion repository are already fixed.
@@ -186,16 +174,16 @@
     this by hand.
 
 The subprojects above wrap external projects Python doesn't control, and as
-such, a little more work is required in order to download the relevant source 
+such, a little more work is required in order to download the relevant source
 files for each project before they can be built.  The buildbots do this each
-time they're built, so the easiest approach is to run either external.bat or 
+time they're built, so the easiest approach is to run either external.bat or
 external-amd64.bat in the ..\Tools\buildbot directory from ..\, i.e.:
 
     C:\..\svn.python.org\projects\python\trunk\PCbuild>cd ..
     C:\..\svn.python.org\projects\python\trunk>Tools\buildbot\external.bat
 
 This extracts all the external subprojects from http://svn.python.org/external
-via Subversion (so you'll need an svn.exe on your PATH) and places them in 
+via Subversion (so you'll need an svn.exe on your PATH) and places them in
 ..\.. (relative to this directory).  The external(-amd64).bat scripts will
 also build a debug build of Tcl/Tk; there aren't any equivalent batch files
 for building release versions of Tcl/Tk lying around in the Tools\buildbot
@@ -238,7 +226,7 @@
     junction as follows (using the directory structure above as an example):
 
         C:\..\python\trunk\external <- already exists and has built versions
-                                       of the external subprojects 
+                                       of the external subprojects
 
         C:\..\python\branches\py3k>linkd.exe external ..\..\trunk\external
         Link created at: external
@@ -251,19 +239,9 @@
 Building for Itanium
 --------------------
 
-NOTE:
 Official support for Itanium builds have been dropped from the build. Please
 contact us and provide patches if you are interested in Itanium builds.
 
-The project files support a ReleaseItanium configuration which creates
-Win64/Itanium binaries. For this to work, you need to install the Platform
-SDK, in particular the 64-bit support. This includes an Itanium compiler
-(future releases of the SDK likely include an AMD64 compiler as well).
-In addition, you need the Visual Studio plugin for external C compilers,
-from http://sf.net/projects/vsextcomp. The plugin will wrap cl.exe, to
-locate the proper target compiler, and convert compiler options
-accordingly. The project files require at least version 0.9.
-
 Building for AMD64
 ------------------
 
@@ -283,7 +261,7 @@
 
 The solution has two configurations for PGO. The PGInstrument
 configuration must be build first. The PGInstrument binaries are
-lniked against a profiling library and contain extra debug
+linked against a profiling library and contain extra debug
 information. The PGUpdate configuration takes the profiling data and
 generates optimized binaries.
 
@@ -291,22 +269,22 @@
 creates the PGI files, runs the unit test suite or PyBench with the PGI
 python and finally creates the optimized files.
 
-http://msdn2.microsoft.com/en-us/library/e7k32f4k(VS.90).aspx
+http://msdn.microsoft.com/en-us/library/e7k32f4k(VS.90).aspx
 
 Static library
 --------------
 
 The solution has no configuration for static libraries. However it is easy
-it build a static library instead of a DLL. You simply have to set the 
+it build a static library instead of a DLL. You simply have to set the
 "Configuration Type" to "Static Library (.lib)" and alter the preprocessor
 macro "Py_ENABLE_SHARED" to "Py_NO_ENABLE_SHARED". You may also have to
-change the "Runtime Library" from "Multi-threaded DLL (/MD)" to 
+change the "Runtime Library" from "Multi-threaded DLL (/MD)" to
 "Multi-threaded (/MT)".
 
 Visual Studio properties
 ------------------------
 
-The PCbuild solution makes heavy use of Visual Studio property files 
+The PCbuild solution makes heavy use of Visual Studio property files
 (*.vsprops). The properties can be viewed and altered in the Property
 Manager (View -> Other Windows -> Property Manager).