Branch merge
diff --git a/Doc/library/random.rst b/Doc/library/random.rst
index f0c4add..3040411 100644
--- a/Doc/library/random.rst
+++ b/Doc/library/random.rst
@@ -43,6 +43,12 @@
 uses the system function :func:`os.urandom` to generate random numbers
 from sources provided by the operating system.
 
+.. warning::
+
+   The generators of the :mod:`random` module should not be used for security
+   purposes. Use :func:`ssl.RAND_bytes` if you require a cryptographically
+   secure pseudorandom number generator.
+
 
 Bookkeeping functions:
 
diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst
index ed547f5e..a4c9b63 100644
--- a/Doc/library/socketserver.rst
+++ b/Doc/library/socketserver.rst
@@ -153,8 +153,21 @@
 .. method:: BaseServer.serve_forever(poll_interval=0.5)
 
    Handle requests until an explicit :meth:`shutdown` request.  Polls for
-   shutdown every *poll_interval* seconds.
+   shutdown every *poll_interval* seconds. It also calls
+   :meth:`service_actions` which may be used by a subclass or Mixin to provide
+   various cleanup actions. For e.g. ForkingMixin class uses
+   :meth:`service_actions` to cleanup the zombie child processes.
 
+   .. versionchanged:: 3.3
+       Added service_actions call to the serve_forever method.
+
+
+.. method:: BaseServer.service_actions()
+
+   This is called by the serve_forever loop. This method is can be overridden
+   by Mixin's to add cleanup or service specific actions.
+
+   .. versionadded:: 3.3
 
 .. method:: BaseServer.shutdown()
 
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
index a528a03..ca71d20 100644
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -164,7 +164,16 @@
 
 .. function:: RAND_bytes(num)
 
-   Returns *num* cryptographically strong pseudo-random bytes.
+   Returns *num* cryptographically strong pseudo-random bytes. Raises an
+   :class:`SSLError` if the PRNG has not been seeded with enough data or if the
+   operation is not supported by the current RAND method. :func:`RAND_status`
+   can be used to check the status of the PRNG and :func:`RAND_add` can be used
+   to seed the PRNG.
+
+   Read the Wikipedia article, `Cryptographically secure pseudorandom number
+   generator (CSPRNG)
+   <http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator>`_,
+   to get the requirements of a cryptographically generator.
 
    .. versionadded:: 3.3
 
@@ -172,7 +181,13 @@
 
    Returns (bytes, is_cryptographic): bytes are *num* pseudo-random bytes,
    is_cryptographic is True if the bytes generated are cryptographically
-   strong.
+   strong. Raises an :class:`SSLError` if the operation is not supported by the
+   current RAND method.
+
+   Generated pseudo-random byte sequences will be unique if they are of
+   sufficient length, but are not necessarily unpredictable. They can be used
+   for non-cryptographic purposes and for certain purposes in cryptographic
+   protocols, but usually not for key generation etc.
 
    .. versionadded:: 3.3
 
diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst
index 529665f..2b9bd11 100644
--- a/Doc/whatsnew/3.3.rst
+++ b/Doc/whatsnew/3.3.rst
@@ -124,6 +124,14 @@
   (Patch submitted by Giampaolo Rodolà in :issue:`10784`.)
 
 
+pydoc
+-----
+
+The Tk GUI and the :func:`~pydoc.serve` function have been removed from the
+:mod:`pydoc` module: ``pydoc -g`` and :func:`~pydoc.serve` have been deprecated
+in Python 3.2.
+
+
 sys
 ---
 
diff --git a/Include/import.h b/Include/import.h
index 6331edf..45544111 100644
--- a/Include/import.h
+++ b/Include/import.h
@@ -44,7 +44,7 @@
     const char *name            /* UTF-8 encoded string */
     );
 PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(
-    char *name,                 /* UTF-8 encoded string */
+    const char *name,           /* UTF-8 encoded string */
     PyObject *globals,
     PyObject *locals,
     PyObject *fromlist,
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index a3b89e7..265edab 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -558,7 +558,11 @@
             if not data:
                 break
             res += data
-        return bytes(res)
+        if res:
+            return bytes(res)
+        else:
+            # b'' or None
+            return data
 
     def readinto(self, b):
         """Read up to len(b) bytes into bytearray b.
@@ -940,6 +944,12 @@
         # Special case for when the number of bytes to read is unspecified.
         if n is None or n == -1:
             self._reset_read_buf()
+            if hasattr(self.raw, 'readall'):
+                chunk = self.raw.readall()
+                if chunk is None:
+                    return buf[pos:] or None
+                else:
+                    return buf[pos:] + chunk
             chunks = [buf[pos:]]  # Strip the consumed bytes.
             current_size = 0
             while True:
diff --git a/Lib/bz2.py b/Lib/bz2.py
index 9506b4a..8ffeaac 100644
--- a/Lib/bz2.py
+++ b/Lib/bz2.py
@@ -155,7 +155,7 @@
         if not self.seekable():
             self._check_not_closed()
             raise io.UnsupportedOperation("Seeking is only supported "
-                                          "on files opening for reading")
+                                          "on files open for reading")
 
     # Fill the readahead buffer if it is empty. Returns False on EOF.
     def _fill_buffer(self):
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index e4c204d..6815f94 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -137,9 +137,7 @@
             rv = f.close()
             if rv == 10:
                 raise OSError('objdump command not found')
-            with contextlib.closing(os.popen(cmd)) as f:
-                data = f.read()
-            res = re.search(r'\sSONAME\s+([^\s]+)', data)
+            res = re.search(r'\sSONAME\s+([^\s]+)', dump)
             if not res:
                 return None
             return res.group(1)
diff --git a/Lib/imaplib.py b/Lib/imaplib.py
index 142e27b..1b54065 100644
--- a/Lib/imaplib.py
+++ b/Lib/imaplib.py
@@ -249,15 +249,7 @@
 
     def read(self, size):
         """Read 'size' bytes from remote."""
-        chunks = []
-        read = 0
-        while read < size:
-            data = self.file.read(min(size-read, 4096))
-            if not data:
-                break
-            read += len(data)
-            chunks.append(data)
-        return b''.join(chunks)
+        return self.file.read(size)
 
 
     def readline(self):
diff --git a/Lib/packaging/tests/support.py b/Lib/packaging/tests/support.py
index 6d60b9e..66b5583 100644
--- a/Lib/packaging/tests/support.py
+++ b/Lib/packaging/tests/support.py
@@ -253,6 +253,15 @@
     return d
 
 
+def fake_dec(*args, **kw):
+    """Fake decorator"""
+    def _wrap(func):
+        def __wrap(*args, **kw):
+            return func(*args, **kw)
+        return __wrap
+    return _wrap
+
+
 try:
     from test.support import skip_unless_symlink
 except ImportError:
diff --git a/Lib/packaging/tests/test_install.py b/Lib/packaging/tests/test_install.py
index 01c3dcf..c0924bf 100644
--- a/Lib/packaging/tests/test_install.py
+++ b/Lib/packaging/tests/test_install.py
@@ -6,13 +6,14 @@
 from packaging.pypi.xmlrpc import Client
 from packaging.metadata import Metadata
 
-from packaging.tests.support import LoggingCatcher, TempdirManager, unittest
+from packaging.tests.support import (LoggingCatcher, TempdirManager, unittest,
+                                     fake_dec)
 try:
     import threading
     from packaging.tests.pypi_server import use_xmlrpc_server
 except ImportError:
     threading = None
-    use_xmlrpc_server = None
+    use_xmlrpc_server = fake_dec
 
 
 class InstalledDist:
diff --git a/Lib/packaging/tests/test_pypi_dist.py b/Lib/packaging/tests/test_pypi_dist.py
index b7f4e98..0c88c9b 100644
--- a/Lib/packaging/tests/test_pypi_dist.py
+++ b/Lib/packaging/tests/test_pypi_dist.py
@@ -7,12 +7,13 @@
 from packaging.pypi.errors import HashDoesNotMatch, UnsupportedHashName
 
 from packaging.tests import unittest
-from packaging.tests.support import TempdirManager, requires_zlib
+from packaging.tests.support import TempdirManager, requires_zlib, fake_dec
 try:
     import threading
     from packaging.tests.pypi_server import use_pypi_server
 except ImportError:
-    threading = use_pypi_server = None
+    threading = None
+    use_pypi_server = fake_dec
 
 
 def Dist(*args, **kwargs):
diff --git a/Lib/packaging/tests/test_pypi_simple.py b/Lib/packaging/tests/test_pypi_simple.py
index d50e3f4..bd50d01 100644
--- a/Lib/packaging/tests/test_pypi_simple.py
+++ b/Lib/packaging/tests/test_pypi_simple.py
@@ -10,9 +10,19 @@
 from packaging.pypi.simple import Crawler
 
 from packaging.tests import unittest
-from packaging.tests.support import TempdirManager, LoggingCatcher
-from packaging.tests.pypi_server import (use_pypi_server, PyPIServer,
-                                         PYPI_DEFAULT_STATIC_PATH)
+from packaging.tests.support import (TempdirManager, LoggingCatcher,
+                                     fake_dec)
+
+try:
+    import _thread
+    from packaging.tests.pypi_server import (use_pypi_server, PyPIServer,
+                                             PYPI_DEFAULT_STATIC_PATH)
+except ImportError:
+    _thread = None
+    use_pypi_server = fake_dec
+    PYPI_DEFAULT_STATIC_PATH = os.path.join(
+        os.path.dirname(os.path.abspath(__file__)), 'pypiserver')
+
 
 
 class SimpleCrawlerTestCase(TempdirManager,
@@ -28,6 +38,7 @@
         return Crawler(server.full_address + base_url, *args,
                        **kwargs)
 
+    @unittest.skipIf(_thread is None, 'needs threads')
     @use_pypi_server()
     def test_bad_urls(self, server):
         crawler = Crawler()
@@ -84,6 +95,7 @@
                 'http://www.famfamfam.com/">')
         crawler._process_url(url, page)
 
+    @unittest.skipIf(_thread is None, 'needs threads')
     @use_pypi_server("test_found_links")
     def test_found_links(self, server):
         # Browse the index, asking for a specified release version
@@ -139,6 +151,7 @@
         self.assertTrue(
             crawler._is_browsable("http://pypi.example.org/a/path"))
 
+    @unittest.skipIf(_thread is None, 'needs threads')
     @use_pypi_server("with_externals")
     def test_follow_externals(self, server):
         # Include external pages
@@ -149,6 +162,7 @@
         self.assertIn(server.full_address + "/external/external.html",
             crawler._processed_urls)
 
+    @unittest.skipIf(_thread is None, 'needs threads')
     @use_pypi_server("with_real_externals")
     def test_restrict_hosts(self, server):
         # Only use a list of allowed hosts is possible
@@ -159,6 +173,7 @@
         self.assertNotIn(server.full_address + "/external/external.html",
             crawler._processed_urls)
 
+    @unittest.skipIf(_thread is None, 'needs threads')
     @use_pypi_server(static_filesystem_paths=["with_externals"],
         static_uri_paths=["simple", "external"])
     def test_links_priority(self, server):
@@ -192,6 +207,7 @@
                          releases[0].dists['sdist'].url['hashval'])
         self.assertEqual('md5', releases[0].dists['sdist'].url['hashname'])
 
+    @unittest.skipIf(_thread is None, 'needs threads')
     @use_pypi_server(static_filesystem_paths=["with_norel_links"],
         static_uri_paths=["simple", "external"])
     def test_not_scan_all_links(self, server):
@@ -217,6 +233,7 @@
         self.assertIn("%s/foobar-2.0.tar.gz" % server.full_address,
             crawler._processed_urls)  # linked from external homepage (rel)
 
+    @unittest.skipIf(_thread is None, 'needs threads')
     def test_uses_mirrors(self):
         # When the main repository seems down, try using the given mirrors"""
         server = PyPIServer("foo_bar_baz")
@@ -314,6 +331,7 @@
         self.assertIn('http://example.org/some/simpleurl', found_links)
         self.assertIn('http://example.org/some/download', found_links)
 
+    @unittest.skipIf(_thread is None, 'needs threads')
     @use_pypi_server("project_list")
     def test_search_projects(self, server):
         # we can search the index for some projects, on their names
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 8581d63..548e71c 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -22,11 +22,6 @@
 open a Web browser to interactively browse documentation.  The -p option
 can be used with the -b option to explicitly specify the server port.
 
-For platforms without a command line, "pydoc -g" starts the HTTP server
-and also pops up a little window for controlling it.  This option is
-deprecated, since the server can now be controlled directly from HTTP
-clients.
-
 Run "pydoc -w <name>" to write out the HTML documentation for a module
 to a file named "<name>.html".
 
@@ -2056,272 +2051,6 @@
         warnings.filterwarnings('ignore') # ignore problems during import
         ModuleScanner().run(callback, key, onerror=onerror)
 
-# --------------------------------------------------- Web browser interface
-
-def serve(port, callback=None, completer=None):
-    import http.server, email.message, select
-
-    msg = 'the pydoc.serve() function is deprecated'
-    warnings.warn(msg, DeprecationWarning, stacklevel=2)
-
-    class DocHandler(http.server.BaseHTTPRequestHandler):
-        def send_document(self, title, contents):
-            try:
-                self.send_response(200)
-                self.send_header('Content-Type', 'text/html; charset=UTF-8')
-                self.end_headers()
-                self.wfile.write(html.page(title, contents).encode('utf-8'))
-            except IOError: pass
-
-        def do_GET(self):
-            path = self.path
-            if path[-5:] == '.html': path = path[:-5]
-            if path[:1] == '/': path = path[1:]
-            if path and path != '.':
-                try:
-                    obj = locate(path, forceload=1)
-                except ErrorDuringImport as value:
-                    self.send_document(path, html.escape(str(value)))
-                    return
-                if obj:
-                    self.send_document(describe(obj), html.document(obj, path))
-                else:
-                    self.send_document(path,
-'no Python documentation found for %s' % repr(path))
-            else:
-                heading = html.heading(
-'<big><big><strong>Python: Index of Modules</strong></big></big>',
-'#ffffff', '#7799ee')
-                def bltinlink(name):
-                    return '<a href="%s.html">%s</a>' % (name, name)
-                names = [x for x in sys.builtin_module_names if x != '__main__']
-                contents = html.multicolumn(names, bltinlink)
-                indices = ['<p>' + html.bigsection(
-                    'Built-in Modules', '#ffffff', '#ee77aa', contents)]
-
-                seen = {}
-                for dir in sys.path:
-                    indices.append(html.index(dir, seen))
-                contents = heading + ' '.join(indices) + '''<p align=right>
-<font color="#909090" face="helvetica, arial"><strong>
-pydoc</strong> by Ka-Ping Yee &lt;ping@lfw.org&gt;</font>'''
-                self.send_document('Index of Modules', contents)
-
-        def log_message(self, *args): pass
-
-    class DocServer(http.server.HTTPServer):
-        def __init__(self, port, callback):
-            host = 'localhost'
-            self.address = (host, port)
-            self.url = 'http://%s:%d/' % (host, port)
-            self.callback = callback
-            self.base.__init__(self, self.address, self.handler)
-
-        def serve_until_quit(self):
-            import select
-            self.quit = False
-            while not self.quit:
-                rd, wr, ex = select.select([self.socket.fileno()], [], [], 1)
-                if rd: self.handle_request()
-            self.server_close()
-
-        def server_activate(self):
-            self.base.server_activate(self)
-            if self.callback: self.callback(self)
-
-    DocServer.base = http.server.HTTPServer
-    DocServer.handler = DocHandler
-    DocHandler.MessageClass = email.message.Message
-    try:
-        try:
-            DocServer(port, callback).serve_until_quit()
-        except (KeyboardInterrupt, select.error):
-            pass
-    finally:
-        if completer: completer()
-
-# ----------------------------------------------------- graphical interface
-
-def gui():
-    """Graphical interface (starts Web server and pops up a control window)."""
-
-    msg = ('the pydoc.gui() function and "pydoc -g" option are deprecated\n',
-           'use "pydoc.browse() function and "pydoc -b" option instead.')
-    warnings.warn(msg, DeprecationWarning, stacklevel=2)
-
-    class GUI:
-        def __init__(self, window, port=7464):
-            self.window = window
-            self.server = None
-            self.scanner = None
-
-            import tkinter
-            self.server_frm = tkinter.Frame(window)
-            self.title_lbl = tkinter.Label(self.server_frm,
-                text='Starting server...\n ')
-            self.open_btn = tkinter.Button(self.server_frm,
-                text='open browser', command=self.open, state='disabled')
-            self.quit_btn = tkinter.Button(self.server_frm,
-                text='quit serving', command=self.quit, state='disabled')
-
-            self.search_frm = tkinter.Frame(window)
-            self.search_lbl = tkinter.Label(self.search_frm, text='Search for')
-            self.search_ent = tkinter.Entry(self.search_frm)
-            self.search_ent.bind('<Return>', self.search)
-            self.stop_btn = tkinter.Button(self.search_frm,
-                text='stop', pady=0, command=self.stop, state='disabled')
-            if sys.platform == 'win32':
-                # Trying to hide and show this button crashes under Windows.
-                self.stop_btn.pack(side='right')
-
-            self.window.title('pydoc')
-            self.window.protocol('WM_DELETE_WINDOW', self.quit)
-            self.title_lbl.pack(side='top', fill='x')
-            self.open_btn.pack(side='left', fill='x', expand=1)
-            self.quit_btn.pack(side='right', fill='x', expand=1)
-            self.server_frm.pack(side='top', fill='x')
-
-            self.search_lbl.pack(side='left')
-            self.search_ent.pack(side='right', fill='x', expand=1)
-            self.search_frm.pack(side='top', fill='x')
-            self.search_ent.focus_set()
-
-            font = ('helvetica', sys.platform == 'win32' and 8 or 10)
-            self.result_lst = tkinter.Listbox(window, font=font, height=6)
-            self.result_lst.bind('<Button-1>', self.select)
-            self.result_lst.bind('<Double-Button-1>', self.goto)
-            self.result_scr = tkinter.Scrollbar(window,
-                orient='vertical', command=self.result_lst.yview)
-            self.result_lst.config(yscrollcommand=self.result_scr.set)
-
-            self.result_frm = tkinter.Frame(window)
-            self.goto_btn = tkinter.Button(self.result_frm,
-                text='go to selected', command=self.goto)
-            self.hide_btn = tkinter.Button(self.result_frm,
-                text='hide results', command=self.hide)
-            self.goto_btn.pack(side='left', fill='x', expand=1)
-            self.hide_btn.pack(side='right', fill='x', expand=1)
-
-            self.window.update()
-            self.minwidth = self.window.winfo_width()
-            self.minheight = self.window.winfo_height()
-            self.bigminheight = (self.server_frm.winfo_reqheight() +
-                                 self.search_frm.winfo_reqheight() +
-                                 self.result_lst.winfo_reqheight() +
-                                 self.result_frm.winfo_reqheight())
-            self.bigwidth, self.bigheight = self.minwidth, self.bigminheight
-            self.expanded = 0
-            self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))
-            self.window.wm_minsize(self.minwidth, self.minheight)
-            self.window.tk.willdispatch()
-
-            import threading
-            threading.Thread(
-                target=serve, args=(port, self.ready, self.quit)).start()
-
-        def ready(self, server):
-            self.server = server
-            self.title_lbl.config(
-                text='Python documentation server at\n' + server.url)
-            self.open_btn.config(state='normal')
-            self.quit_btn.config(state='normal')
-
-        def open(self, event=None, url=None):
-            url = url or self.server.url
-            import webbrowser
-            webbrowser.open(url)
-
-        def quit(self, event=None):
-            if self.server:
-                self.server.quit = 1
-            self.window.quit()
-
-        def search(self, event=None):
-            key = self.search_ent.get()
-            self.stop_btn.pack(side='right')
-            self.stop_btn.config(state='normal')
-            self.search_lbl.config(text='Searching for "%s"...' % key)
-            self.search_ent.forget()
-            self.search_lbl.pack(side='left')
-            self.result_lst.delete(0, 'end')
-            self.goto_btn.config(state='disabled')
-            self.expand()
-
-            import threading
-            if self.scanner:
-                self.scanner.quit = 1
-            self.scanner = ModuleScanner()
-            threading.Thread(target=self.scanner.run,
-                             args=(self.update, key, self.done)).start()
-
-        def update(self, path, modname, desc):
-            if modname[-9:] == '.__init__':
-                modname = modname[:-9] + ' (package)'
-            self.result_lst.insert('end',
-                modname + ' - ' + (desc or '(no description)'))
-
-        def stop(self, event=None):
-            if self.scanner:
-                self.scanner.quit = 1
-                self.scanner = None
-
-        def done(self):
-            self.scanner = None
-            self.search_lbl.config(text='Search for')
-            self.search_lbl.pack(side='left')
-            self.search_ent.pack(side='right', fill='x', expand=1)
-            if sys.platform != 'win32': self.stop_btn.forget()
-            self.stop_btn.config(state='disabled')
-
-        def select(self, event=None):
-            self.goto_btn.config(state='normal')
-
-        def goto(self, event=None):
-            selection = self.result_lst.curselection()
-            if selection:
-                modname = self.result_lst.get(selection[0]).split()[0]
-                self.open(url=self.server.url + modname + '.html')
-
-        def collapse(self):
-            if not self.expanded: return
-            self.result_frm.forget()
-            self.result_scr.forget()
-            self.result_lst.forget()
-            self.bigwidth = self.window.winfo_width()
-            self.bigheight = self.window.winfo_height()
-            self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))
-            self.window.wm_minsize(self.minwidth, self.minheight)
-            self.expanded = 0
-
-        def expand(self):
-            if self.expanded: return
-            self.result_frm.pack(side='bottom', fill='x')
-            self.result_scr.pack(side='right', fill='y')
-            self.result_lst.pack(side='top', fill='both', expand=1)
-            self.window.wm_geometry('%dx%d' % (self.bigwidth, self.bigheight))
-            self.window.wm_minsize(self.minwidth, self.bigminheight)
-            self.expanded = 1
-
-        def hide(self, event=None):
-            self.stop()
-            self.collapse()
-
-    import tkinter
-    try:
-        root = tkinter.Tk()
-        # Tk will crash if pythonw.exe has an XP .manifest
-        # file and the root has is not destroyed explicitly.
-        # If the problem is ever fixed in Tk, the explicit
-        # destroy can go.
-        try:
-            gui = GUI(root)
-            root.mainloop()
-        finally:
-            root.destroy()
-    except KeyboardInterrupt:
-        pass
-
-
 # --------------------------------------- enhanced Web browser interface
 
 def _start_server(urlhandler, port):
@@ -2778,15 +2507,12 @@
         sys.path.insert(0, '.')
 
     try:
-        opts, args = getopt.getopt(sys.argv[1:], 'bgk:p:w')
+        opts, args = getopt.getopt(sys.argv[1:], 'bk:p:w')
         writing = False
         start_server = False
         open_browser = False
         port = None
         for opt, val in opts:
-            if opt == '-g':
-                gui()
-                return
             if opt == '-b':
                 start_server = True
                 open_browser = True
@@ -2847,9 +2573,6 @@
     to interactively browse documentation.  The -p option can be used with
     the -b option to explicitly specify the server port.
 
-{cmd} -g
-    Deprecated.
-
 {cmd} -w <name> ...
     Write out the HTML documentation for a module to a file in the current
     directory.  If <name> contains a '{sep}', it is treated as a filename; if
diff --git a/Lib/socketserver.py b/Lib/socketserver.py
index 089b3ba..a2f0f39 100644
--- a/Lib/socketserver.py
+++ b/Lib/socketserver.py
@@ -82,7 +82,7 @@
 data is stored externally (e.g. in the file system), a synchronous
 class will essentially render the service "deaf" while one request is
 being handled -- which may be for a very long time if a client is slow
-to reqd all the data it has requested.  Here a threading or forking
+to recv all the data it has requested.  Here a threading or forking
 server is appropriate.
 
 In some cases, it may be appropriate to process part of a request
@@ -170,6 +170,7 @@
     - process_request(request, client_address)
     - shutdown_request(request)
     - close_request(request)
+    - service_actions()
     - handle_error()
 
     Methods for derived classes:
@@ -225,6 +226,8 @@
                 r, w, e = select.select([self], [], [], poll_interval)
                 if self in r:
                     self._handle_request_noblock()
+
+                self.service_actions()
         finally:
             self.__shutdown_request = False
             self.__is_shut_down.set()
@@ -239,6 +242,14 @@
         self.__shutdown_request = True
         self.__is_shut_down.wait()
 
+    def service_actions(self):
+        """Called by the serve_forever() loop.
+
+        May be overridden by a subclass / Mixin to implement any code that
+        needs to be run during the loop.
+        """
+        pass
+
     # The distinction between handling, getting, processing and
     # finishing a request is fairly arbitrary.  Remember:
     #
@@ -539,9 +550,15 @@
         """
         self.collect_children()
 
+    def service_actions(self):
+        """Collect the zombie child processes regularly in the ForkingMixin.
+
+        service_actions is called in the BaseServer's serve_forver loop.
+        """
+        self.collect_children()
+
     def process_request(self, request, client_address):
         """Fork a new subprocess to process the request."""
-        self.collect_children()
         pid = os.fork()
         if pid:
             # Parent process
diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
index 59073f4..d07784d 100644
--- a/Lib/sysconfig.py
+++ b/Lib/sysconfig.py
@@ -287,14 +287,16 @@
                         variables.remove(name)
 
                         if name.startswith('PY_') \
-                                and name[3:] in renamed_variables:
+                        and name[3:] in renamed_variables:
 
                             name = name[3:]
                             if name not in done:
                                 done[name] = value
 
             else:
-                # bogus variable reference; just drop it since we can't deal
+                # bogus variable reference (e.g. "prefix=$/opt/python");
+                # just drop it since we can't deal
+                done[name] = value
                 variables.remove(name)
 
     # strip spurious spaces
diff --git a/Lib/test/cjkencodings/hz-utf8.txt b/Lib/test/cjkencodings/hz-utf8.txt
new file mode 100644
index 0000000..7c11735
--- /dev/null
+++ b/Lib/test/cjkencodings/hz-utf8.txt
@@ -0,0 +1,2 @@
+This sentence is in ASCII.
+The next sentence is in GB.己所不欲,勿施於人。Bye.
diff --git a/Lib/test/cjkencodings/hz.txt b/Lib/test/cjkencodings/hz.txt
new file mode 100644
index 0000000..f882d46
--- /dev/null
+++ b/Lib/test/cjkencodings/hz.txt
@@ -0,0 +1,2 @@
+This sentence is in ASCII.
+The next sentence is in GB.~{<:Ky2;S{#,NpJ)l6HK!#~}Bye.
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
index 04e87e3..b5e5127 100755
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -794,17 +794,14 @@
 def replace_stdout():
     """Set stdout encoder error handler to backslashreplace (as stderr error
     handler) to avoid UnicodeEncodeError when printing a traceback"""
-    if os.name == "nt":
-        # Replace sys.stdout breaks the stdout newlines on Windows: issue #8533
-        return
-
     import atexit
 
     stdout = sys.stdout
     sys.stdout = open(stdout.fileno(), 'w',
         encoding=stdout.encoding,
         errors="backslashreplace",
-        closefd=False)
+        closefd=False,
+        newline='\n')
 
     def restore_stdout():
         sys.stdout.close()
diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py
index b296870..4bab28b 100644
--- a/Lib/test/test_bool.py
+++ b/Lib/test/test_bool.py
@@ -330,6 +330,16 @@
                 except (Exception) as e_len:
                     self.assertEqual(str(e_bool), str(e_len))
 
+    def test_real_and_imag(self):
+        self.assertEqual(True.real, 1)
+        self.assertEqual(True.imag, 0)
+        self.assertIs(type(True.real), int)
+        self.assertIs(type(True.imag), int)
+        self.assertEqual(False.real, 0)
+        self.assertEqual(False.imag, 0)
+        self.assertIs(type(False.real), int)
+        self.assertIs(type(False.imag), int)
+
 def test_main():
     support.run_unittest(BoolTest)
 
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index b094a65..97619cf 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -385,6 +385,8 @@
         except:
             self.assertEqual(len(dir(sys.exc_info()[2])), 4)
 
+        # test that object has a __dir__()
+        self.assertEqual(sorted([].__dir__()), dir([]))
 
     def test_divmod(self):
         self.assertEqual(divmod(12, 7), (1, 5))
diff --git a/Lib/test/test_codecencodings_cn.py b/Lib/test/test_codecencodings_cn.py
index a2d9718..dca9f10 100644
--- a/Lib/test/test_codecencodings_cn.py
+++ b/Lib/test/test_codecencodings_cn.py
@@ -50,6 +50,35 @@
     )
     has_iso10646 = True
 
+class Test_HZ(test_multibytecodec_support.TestBase, unittest.TestCase):
+    encoding = 'hz'
+    tstring = test_multibytecodec_support.load_teststring('hz')
+    codectests = (
+        # test '~\n' (3 lines)
+        (b'This sentence is in ASCII.\n'
+         b'The next sentence is in GB.~{<:Ky2;S{#,~}~\n'
+         b'~{NpJ)l6HK!#~}Bye.\n',
+         'strict',
+         'This sentence is in ASCII.\n'
+         'The next sentence is in GB.'
+         '\u5df1\u6240\u4e0d\u6b32\uff0c\u52ff\u65bd\u65bc\u4eba\u3002'
+         'Bye.\n'),
+        # test '~\n' (4 lines)
+        (b'This sentence is in ASCII.\n'
+         b'The next sentence is in GB.~\n'
+         b'~{<:Ky2;S{#,NpJ)l6HK!#~}~\n'
+         b'Bye.\n',
+         'strict',
+         'This sentence is in ASCII.\n'
+         'The next sentence is in GB.'
+         '\u5df1\u6240\u4e0d\u6b32\uff0c\u52ff\u65bd\u65bc\u4eba\u3002'
+         'Bye.\n'),
+        # invalid bytes
+        (b'ab~cd', 'replace', 'ab\uFFFDd'),
+        (b'ab\xffcd', 'replace', 'ab\uFFFDcd'),
+        (b'ab~{\x81\x81\x41\x44~}cd', 'replace', 'ab\uFFFD\uFFFD\u804Acd'),
+    )
+
 def test_main():
     support.run_unittest(__name__)
 
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 31731d2..0fae2df 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -1631,12 +1631,7 @@
             for attr, obj in env.items():
                 setattr(X, attr, obj)
             setattr(X, name, ErrDescr())
-            try:
-                runner(X())
-            except MyException:
-                pass
-            else:
-                self.fail("{0!r} didn't raise".format(name))
+            self.assertRaises(MyException, runner, X())
 
     def test_specials(self):
         # Testing special operators...
diff --git a/Lib/test/test_descrtut.py b/Lib/test/test_descrtut.py
index c3355b9..f495e18 100644
--- a/Lib/test/test_descrtut.py
+++ b/Lib/test/test_descrtut.py
@@ -170,6 +170,7 @@
      '__contains__',
      '__delattr__',
      '__delitem__',
+     '__dir__',
      '__doc__',
      '__eq__',
      '__format__',
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 3724b5c..c0dc6ec 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -833,14 +833,17 @@
         # Inject some None's in there to simulate EWOULDBLOCK
         rawio = self.MockRawIO((b"abc", b"d", None, b"efg", None, None, None))
         bufio = self.tp(rawio)
-
         self.assertEqual(b"abcd", bufio.read(6))
         self.assertEqual(b"e", bufio.read(1))
         self.assertEqual(b"fg", bufio.read())
         self.assertEqual(b"", bufio.peek(1))
-        self.assertTrue(None is bufio.read())
+        self.assertIsNone(bufio.read())
         self.assertEqual(b"", bufio.read())
 
+        rawio = self.MockRawIO((b"a", None, None))
+        self.assertEqual(b"a", rawio.readall())
+        self.assertIsNone(rawio.readall())
+
     def test_read_past_eof(self):
         rawio = self.MockRawIO((b"abc", b"d", b"efg"))
         bufio = self.tp(rawio)
@@ -2512,6 +2515,8 @@
             self.assertRaises(ValueError, f.read)
             if hasattr(f, "read1"):
                 self.assertRaises(ValueError, f.read1, 1024)
+            if hasattr(f, "readall"):
+                self.assertRaises(ValueError, f.readall)
             if hasattr(f, "readinto"):
                 self.assertRaises(ValueError, f.readinto, bytearray(1024))
             self.assertRaises(ValueError, f.readline)
diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py
index fe772e1..86c68dc 100644
--- a/Lib/test/test_multibytecodec.py
+++ b/Lib/test/test_multibytecodec.py
@@ -256,6 +256,36 @@
             # Any ISO 2022 codec will cause the segfault
             myunichr(x).encode('iso_2022_jp', 'ignore')
 
+class TestStateful(unittest.TestCase):
+    text = '\u4E16\u4E16'
+    encoding = 'iso-2022-jp'
+    expected = b'\x1b$B@$@$'
+    expected_reset = b'\x1b$B@$@$\x1b(B'
+
+    def test_encode(self):
+        self.assertEqual(self.text.encode(self.encoding), self.expected_reset)
+
+    def test_incrementalencoder(self):
+        encoder = codecs.getincrementalencoder(self.encoding)()
+        output = b''.join(
+            encoder.encode(char)
+            for char in self.text)
+        self.assertEqual(output, self.expected)
+
+    def test_incrementalencoder_final(self):
+        encoder = codecs.getincrementalencoder(self.encoding)()
+        last_index = len(self.text) - 1
+        output = b''.join(
+            encoder.encode(char, index == last_index)
+            for index, char in enumerate(self.text))
+        self.assertEqual(output, self.expected_reset)
+
+class TestHZStateful(TestStateful):
+    text = '\u804a\u804a'
+    encoding = 'hz'
+    expected = b'~{ADAD'
+    expected_reset = b'~{ADAD~}'
+
 def test_main():
     support.run_unittest(__name__)
 
diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py
index 3134031..cdd3f3e 100644
--- a/Lib/test/test_signal.py
+++ b/Lib/test/test_signal.py
@@ -226,10 +226,16 @@
     TIMEOUT_FULL = 10
     TIMEOUT_HALF = 5
 
-    def check_signum(self, *signals):
+    def handler(self, signum, frame):
+        pass
+
+    def check_signum(self, *signals, **kw):
         data = os.read(self.read, len(signals)+1)
         raised = struct.unpack('%uB' % len(data), data)
-        self.assertSequenceEqual(raised, signals)
+        if kw.get('unordered', False):
+            raised = set(raised)
+            signals = set(signals)
+        self.assertEqual(raised, signals)
 
     def test_wakeup_fd_early(self):
         import select
@@ -259,16 +265,38 @@
         self.check_signum(signal.SIGALRM)
 
     def test_signum(self):
-        old_handler = signal.signal(signal.SIGUSR1, lambda x,y:None)
+        old_handler = signal.signal(signal.SIGUSR1, self.handler)
         self.addCleanup(signal.signal, signal.SIGUSR1, old_handler)
         os.kill(os.getpid(), signal.SIGUSR1)
         os.kill(os.getpid(), signal.SIGALRM)
         self.check_signum(signal.SIGUSR1, signal.SIGALRM)
 
+    @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
+                         'need signal.pthread_sigmask()')
+    @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
+                         'need signal.pthread_kill()')
+    def test_pending(self):
+        signum1 = signal.SIGUSR1
+        signum2 = signal.SIGUSR2
+        tid = threading.current_thread().ident
+
+        old_handler = signal.signal(signum1, self.handler)
+        self.addCleanup(signal.signal, signum1, old_handler)
+        old_handler = signal.signal(signum2, self.handler)
+        self.addCleanup(signal.signal, signum2, old_handler)
+
+        signal.pthread_sigmask(signal.SIG_BLOCK, (signum1, signum2))
+        signal.pthread_kill(tid, signum1)
+        signal.pthread_kill(tid, signum2)
+        # Unblocking the 2 signals calls the C signal handler twice
+        signal.pthread_sigmask(signal.SIG_UNBLOCK, (signum1, signum2))
+
+        self.check_signum(signum1, signum2, unordered=True)
+
     def setUp(self):
         import fcntl
 
-        self.alrm = signal.signal(signal.SIGALRM, lambda x,y:None)
+        self.alrm = signal.signal(signal.SIGALRM, self.handler)
         self.read, self.write = os.pipe()
         flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0)
         flags = flags | os.O_NONBLOCK
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 8c21975..5193c15 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -109,6 +109,8 @@
         if v:
             data = ssl.RAND_bytes(16)
             self.assertEqual(len(data), 16)
+        else:
+            self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16)
 
         try:
             ssl.RAND_egd(1)
diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py
index 77c2364..96f75f2 100644
--- a/Lib/test/test_sysconfig.py
+++ b/Lib/test/test_sysconfig.py
@@ -14,12 +14,12 @@
                        _get_default_scheme, _expand_vars,
                        get_scheme_names, get_config_var, _main)
 
+
 class TestSysConfig(unittest.TestCase):
 
     def setUp(self):
         super(TestSysConfig, self).setUp()
         self.sys_path = sys.path[:]
-        self.makefile = None
         # patching os.uname
         if hasattr(os, 'uname'):
             self.uname = os.uname
@@ -47,8 +47,6 @@
 
     def tearDown(self):
         sys.path[:] = self.sys_path
-        if self.makefile is not None:
-            os.unlink(self.makefile)
         self._cleanup_testfn()
         if self.uname is not None:
             os.uname = self.uname
@@ -208,9 +206,9 @@
             get_config_vars()['CFLAGS'] = ('-arch %s -isysroot '
                                            '/Developer/SDKs/MacOSX10.4u.sdk  '
                                            '-fno-strict-aliasing -fno-common '
-                                           '-dynamic -DNDEBUG -g -O3'%(arch,))
+                                           '-dynamic -DNDEBUG -g -O3' % arch)
 
-            self.assertEqual(get_platform(), 'macosx-10.4-%s'%(arch,))
+            self.assertEqual(get_platform(), 'macosx-10.4-%s' % arch)
 
         # linux debian sarge
         os.name = 'posix'
@@ -228,12 +226,6 @@
         config_h = sysconfig.get_config_h_filename()
         self.assertTrue(os.path.isfile(config_h), config_h)
 
-    @unittest.skipIf(sys.platform.startswith('win'),
-                     'Test is not Windows compatible')
-    def test_get_makefile_filename(self):
-        makefile = sysconfig.get_makefile_filename()
-        self.assertTrue(os.path.isfile(makefile), makefile)
-
     def test_get_scheme_names(self):
         wanted = ('nt', 'nt_user', 'os2', 'os2_home', 'osx_framework_user',
                   'posix_home', 'posix_prefix', 'posix_user')
@@ -329,8 +321,34 @@
         self.assertEqual(my_platform, test_platform)
 
 
+class MakefileTests(unittest.TestCase):
+
+    @unittest.skipIf(sys.platform.startswith('win'),
+                     'Test is not Windows compatible')
+    def test_get_makefile_filename(self):
+        makefile = sysconfig.get_makefile_filename()
+        self.assertTrue(os.path.isfile(makefile), makefile)
+
+    def test_parse_makefile(self):
+        self.addCleanup(unlink, TESTFN)
+        with open(TESTFN, "w") as makefile:
+            print("var1=a$(VAR2)", file=makefile)
+            print("VAR2=b$(var3)", file=makefile)
+            print("var3=42", file=makefile)
+            print("var4=$/invalid", file=makefile)
+            print("var5=dollar$$5", file=makefile)
+        vars = sysconfig._parse_makefile(TESTFN)
+        self.assertEqual(vars, {
+            'var1': 'ab42',
+            'VAR2': 'b42',
+            'var3': 42,
+            'var4': '$/invalid',
+            'var5': 'dollar$5',
+        })
+
+
 def test_main():
-    run_unittest(TestSysConfig)
+    run_unittest(TestSysConfig, MakefileTests)
 
 if __name__ == "__main__":
     test_main()
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 04d126f..dff1252 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -908,8 +908,8 @@
 MACHDEPS=	$(PLATDIR) $(EXTRAPLATDIR)
 XMLLIBSUBDIRS=  xml xml/dom xml/etree xml/parsers xml/sax
 LIBSUBDIRS=	tkinter tkinter/test tkinter/test/test_tkinter \
-                tkinter/test/test_ttk site-packages test \
-		test/decimaltestdata test/xmltestdata test/subprocessdata \
+		tkinter/test/test_ttk site-packages test \
+		test/cjkencodings test/decimaltestdata test/xmltestdata test/subprocessdata \
 		test/tracedmodules test/encoded_modules \
 		collections concurrent concurrent/futures encodings \
 		email email/mime email/test email/test/data \
diff --git a/Misc/NEWS b/Misc/NEWS
index 967e2ef..b7f3907 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,11 @@
 Core and Builtins
 -----------------
 
+- Issue #12166: Move implementations of dir() specialized for various types into
+  the __dir__() methods of those types.
+
+- Issue #5715: In socketserver, close the server socket in the child process.
+
 - Correct lookup of __dir__ on objects. Among other things, this causes errors
   besides AttributeError found on lookup to be propagated.
 
@@ -156,6 +161,39 @@
 Library
 -------
 
+- Issue #12175: BufferedReader.read(-1) now calls raw.readall() if available.
+
+- Issue #12175: FileIO.readall() now only reads the file position and size
+  once.
+
+- Issue #12180: Fixed a few remaining errors in test_packaging when no
+  threading.
+
+- Issue #12175: RawIOBase.readall() now returns None if read() returns None.
+
+- Issue #12175: FileIO.readall() now raises a ValueError instead of an IOError
+  if the file is closed.
+
+- Issue #11109: New service_action method for BaseServer, used by ForkingMixin
+  class for cleanup. Initial Patch by Justin Wark.
+
+- Issue #12045: Avoid duplicate execution of command in
+  ctypes.util._get_soname().  Patch by Sijin Joseph.
+
+- Issue #10818: Remove the Tk GUI and the serve() function of the pydoc module,
+  pydoc -g has been deprecated in Python 3.2 and it has a new enhanced web
+  server.
+
+- Issue #1441530: In imaplib, read the data in one chunk to speed up large
+  reads and simplify code.
+
+- Issue #12070: Fix the Makefile parser of the sysconfig module to handle
+  correctly references to "bogus variable" (e.g. "prefix=$/opt/python").
+
+- Issue #12100: Don't reset incremental encoders of CJK codecs at each call to
+  their encode() method anymore, but continue to call the reset() method if the
+  final argument is True.
+
 - Issue #12049: Add RAND_bytes() and RAND_pseudo_bytes() functions to the ssl
   module.
 
@@ -804,7 +842,11 @@
 C-API
 -----
 
-- PY_PATCHLEVEL_REVISION has been removed, since it's meaningless with Mercurial.
+- PY_PATCHLEVEL_REVISION has been removed, since it's meaningless with
+  Mercurial.
+
+- Issue #12173: The first argument of PyImport_ImportModuleLevel is now `const
+  char *` instead of `char *1`.
 
 Documentation
 -------------
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c
index 44bdac6..6f5bd48 100644
--- a/Modules/_io/_iomodule.c
+++ b/Modules/_io/_iomodule.c
@@ -36,6 +36,7 @@
 PyObject *_PyIO_str_read;
 PyObject *_PyIO_str_read1;
 PyObject *_PyIO_str_readable;
+PyObject *_PyIO_str_readall;
 PyObject *_PyIO_str_readinto;
 PyObject *_PyIO_str_readline;
 PyObject *_PyIO_str_reset;
@@ -767,6 +768,8 @@
         goto fail;
     if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable")))
         goto fail;
+    if (!(_PyIO_str_readall = PyUnicode_InternFromString("readall")))
+        goto fail;
     if (!(_PyIO_str_readinto = PyUnicode_InternFromString("readinto")))
         goto fail;
     if (!(_PyIO_str_readline = PyUnicode_InternFromString("readline")))
diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h
index 925e4f2..9174bdd 100644
--- a/Modules/_io/_iomodule.h
+++ b/Modules/_io/_iomodule.h
@@ -155,6 +155,7 @@
 extern PyObject *_PyIO_str_read;
 extern PyObject *_PyIO_str_read1;
 extern PyObject *_PyIO_str_readable;
+extern PyObject *_PyIO_str_readall;
 extern PyObject *_PyIO_str_readinto;
 extern PyObject *_PyIO_str_readline;
 extern PyObject *_PyIO_str_reset;
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index 3b8b7e9..63ae1cb 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -1407,32 +1407,57 @@
 _bufferedreader_read_all(buffered *self)
 {
     Py_ssize_t current_size;
-    PyObject *res, *data = NULL;
-    PyObject *chunks = PyList_New(0);
-
-    if (chunks == NULL)
-        return NULL;
+    PyObject *res, *data = NULL, *chunk, *chunks;
 
     /* First copy what we have in the current buffer. */
     current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
     if (current_size) {
         data = PyBytes_FromStringAndSize(
             self->buffer + self->pos, current_size);
-        if (data == NULL) {
-            Py_DECREF(chunks);
+        if (data == NULL)
             return NULL;
-        }
     }
     _bufferedreader_reset_buf(self);
     /* We're going past the buffer's bounds, flush it */
     if (self->writable) {
         res = _bufferedwriter_flush_unlocked(self, 1);
-        if (res == NULL) {
-            Py_DECREF(chunks);
+        if (res == NULL)
             return NULL;
-        }
         Py_CLEAR(res);
     }
+
+    if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
+        chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
+        if (chunk == NULL)
+            return NULL;
+        if (chunk != Py_None && !PyBytes_Check(chunk)) {
+            Py_XDECREF(data);
+            Py_DECREF(chunk);
+            PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
+            return NULL;
+        }
+        if (chunk == Py_None) {
+            if (current_size == 0)
+                return chunk;
+            else {
+                Py_DECREF(chunk);
+                return data;
+            }
+        }
+        else if (current_size) {
+            PyBytes_Concat(&data, chunk);
+            Py_DECREF(chunk);
+            if (data == NULL)
+                return NULL;
+            return data;
+        } else
+            return chunk;
+    }
+
+    chunks = PyList_New(0);
+    if (chunks == NULL)
+        return NULL;
+
     while (1) {
         if (data) {
             if (PyList_Append(chunks, data) < 0) {
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
index 1aa5ee9..b3b9e44 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -547,14 +547,14 @@
 }
 
 static size_t
-new_buffersize(fileio *self, size_t currentsize)
+new_buffersize(fileio *self, size_t currentsize
+#ifdef HAVE_FSTAT
+               , off_t pos, off_t end
+#endif
+               )
 {
 #ifdef HAVE_FSTAT
-    off_t pos, end;
-    struct stat st;
-    if (fstat(self->fd, &st) == 0) {
-        end = st.st_size;
-        pos = lseek(self->fd, 0L, SEEK_CUR);
+    if (end != (off_t)-1) {
         /* Files claiming a size smaller than SMALLCHUNK may
            actually be streaming pseudo-files. In this case, we
            apply the more aggressive algorithm below.
@@ -579,10 +579,17 @@
 static PyObject *
 fileio_readall(fileio *self)
 {
+#ifdef HAVE_FSTAT
+    struct stat st;
+    off_t pos, end;
+#endif
     PyObject *result;
     Py_ssize_t total = 0;
     int n;
+    size_t newsize;
 
+    if (self->fd < 0)
+        return err_closed();
     if (!_PyVerify_fd(self->fd))
         return PyErr_SetFromErrno(PyExc_IOError);
 
@@ -590,8 +597,23 @@
     if (result == NULL)
         return NULL;
 
+#ifdef HAVE_FSTAT
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+    pos = _lseeki64(self->fd, 0L, SEEK_CUR);
+#else
+    pos = lseek(self->fd, 0L, SEEK_CUR);
+#endif
+    if (fstat(self->fd, &st) == 0)
+        end = st.st_size;
+    else
+        end = (off_t)-1;
+#endif
     while (1) {
-        size_t newsize = new_buffersize(self, total);
+#ifdef HAVE_FSTAT
+        newsize = new_buffersize(self, total, pos, end);
+#else
+        newsize = new_buffersize(self, total);
+#endif
         if (newsize > PY_SSIZE_T_MAX || newsize <= 0) {
             PyErr_SetString(PyExc_OverflowError,
                 "unbounded read returned more bytes "
@@ -630,6 +652,9 @@
             return NULL;
         }
         total += n;
+#ifdef HAVE_FSTAT
+        pos += n;
+#endif
     }
 
     if (PyBytes_GET_SIZE(result) > total) {
diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c
index ec7a242..f06f562 100644
--- a/Modules/_io/iobase.c
+++ b/Modules/_io/iobase.c
@@ -815,6 +815,14 @@
             Py_DECREF(chunks);
             return NULL;
         }
+        if (data == Py_None) {
+            if (PyList_GET_SIZE(chunks) == 0) {
+                Py_DECREF(chunks);
+                return data;
+            }
+            Py_DECREF(data);
+            break;
+        }
         if (!PyBytes_Check(data)) {
             Py_DECREF(chunks);
             Py_DECREF(data);
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index 35bd922..70d062b 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -1513,8 +1513,13 @@
         PyObject *decoded;
         if (bytes == NULL)
             goto fail;
-        decoded = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode,
-                                             bytes, Py_True, NULL);
+
+        if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type)
+            decoded = _PyIncrementalNewlineDecoder_decode(self->decoder,
+                                                          bytes, 1);
+        else
+            decoded = PyObject_CallMethodObjArgs(
+                self->decoder, _PyIO_str_decode, bytes, Py_True, NULL);
         Py_DECREF(bytes);
         if (decoded == NULL)
             goto fail;
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index bf10cbb..af0d971 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -1,7 +1,7 @@
 /* Authors: Gregory P. Smith & Jeffrey Yasskin */
 #include "Python.h"
-#ifdef HAVE_PIPE2
-#define _GNU_SOURCE
+#if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE)
+# define _GNU_SOURCE
 #endif
 #include <unistd.h>
 #include <fcntl.h>
diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c
index e137ff6..bb8176f 100644
--- a/Modules/cjkcodecs/multibytecodec.c
+++ b/Modules/cjkcodecs/multibytecodec.c
@@ -479,7 +479,7 @@
     MultibyteEncodeBuffer buf;
     Py_ssize_t finalsize, r = 0;
 
-    if (datalen == 0)
+    if (datalen == 0 && !(flags & MBENC_RESET))
         return PyBytes_FromStringAndSize(NULL, 0);
 
     buf.excobj = NULL;
@@ -515,7 +515,7 @@
             break;
     }
 
-    if (codec->encreset != NULL)
+    if (codec->encreset != NULL && (flags & MBENC_RESET))
         for (;;) {
             Py_ssize_t outleft;
 
@@ -785,8 +785,8 @@
     inbuf_end = inbuf + datalen;
 
     r = multibytecodec_encode(ctx->codec, &ctx->state,
-                    (const Py_UNICODE **)&inbuf,
-                    datalen, ctx->errors, final ? MBENC_FLUSH : 0);
+                    (const Py_UNICODE **)&inbuf, datalen,
+                    ctx->errors, final ? MBENC_FLUSH | MBENC_RESET : 0);
     if (r == NULL) {
         /* recover the original pending buffer */
         if (origpending > 0)
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
index 83c47ce..46c2c42 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -1005,9 +1005,10 @@
 faulthandler_env_options(void)
 {
     PyObject *xoptions, *key, *module, *res;
-    int enable;
 
     if (!Py_GETENV("PYTHONFAULTHANDLER")) {
+        int has_key;
+
         xoptions = PySys_GetXOptions();
         if (xoptions == NULL)
             return -1;
@@ -1016,13 +1017,11 @@
         if (key == NULL)
             return -1;
 
-        enable = PyDict_Contains(xoptions, key);
+        has_key = PyDict_Contains(xoptions, key);
         Py_DECREF(key);
-        if (!enable)
+        if (!has_key)
             return 0;
     }
-    else
-        enable = 1;
 
     module = PyImport_ImportModule("faulthandler");
     if (module == NULL) {
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index ff65f04..6d27ab3 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -177,17 +177,18 @@
 trip_signal(int sig_num)
 {
     unsigned char byte;
+
     Handlers[sig_num].tripped = 1;
+    if (wakeup_fd != -1) {
+        byte = (unsigned char)sig_num;
+        write(wakeup_fd, &byte, 1);
+    }
     if (is_tripped)
         return;
     /* Set is_tripped after setting .tripped, as it gets
        cleared in PyErr_CheckSignals() before .tripped. */
     is_tripped = 1;
     Py_AddPendingCall(checksignals_witharg, NULL);
-    if (wakeup_fd != -1) {
-        byte = (unsigned char)sig_num;
-        write(wakeup_fd, &byte, 1);
-    }
 }
 
 static void
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 8107b98..d18b5b1 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -2782,6 +2782,7 @@
             PyErr_Format(PyExc_TypeError,
                          "sendto() takes 2 or 3 arguments (%d given)",
                          arglen);
+            return NULL;
     }
     if (PyErr_Occurred())
         return NULL;
@@ -3144,7 +3145,7 @@
         }
         return PyErr_SetExcFromWindowsErr(PyExc_WindowsError, GetLastError());
     }
-    return PyUnicode_FromUnicode(buf, size);            
+    return PyUnicode_FromUnicode(buf, size);
 #else
     char buf[1024];
     int res;
@@ -4038,7 +4039,7 @@
 static PyObject *
 socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs)
 {
-    static char* kwnames[] = {"host", "port", "family", "type", "proto", 
+    static char* kwnames[] = {"host", "port", "family", "type", "proto",
                               "flags", 0};
     struct addrinfo hints, *res;
     struct addrinfo *res0 = NULL;
@@ -4053,7 +4054,7 @@
 
     family = socktype = protocol = flags = 0;
     family = AF_UNSPEC;
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iiii:getaddrinfo", 
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iiii:getaddrinfo",
                           kwnames, &hobj, &pobj, &family, &socktype,
                           &protocol, &flags)) {
         return NULL;
@@ -4289,7 +4290,7 @@
     PyObject *list;
     int i;
     struct if_nameindex *ni;
-  
+
     ni = if_nameindex();
     if (ni == NULL) {
         PyErr_SetFromErrno(socket_error);
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
index de89a76..a83bf8b 100644
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -1196,7 +1196,7 @@
                 int *p_ispackage, PyObject **p_modpath)
 {
     PyObject *code = NULL, *toc_entry, *subname;
-    PyObject *path, *fullpath;
+    PyObject *path, *fullpath = NULL;
     struct st_zip_searchorder *zso;
 
     subname = get_subname(fullname);
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 0106ba3..fb7864f 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -499,7 +499,7 @@
     Py_CLEAR(self->code);
     if (size == 1)
         self->code = PyTuple_GET_ITEM(args, 0);
-    else if (size > 1)
+    else /* size > 1 */
         self->code = args;
     Py_INCREF(self->code);
     return 0;
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index 06f58d8..3817ef3 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -413,6 +413,34 @@
     return 0;
 }
 
+static PyObject *
+module_dir(PyObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    PyObject *dict = PyObject_GetAttrString(self, "__dict__");
+
+    if (dict != NULL) {
+        if (PyDict_Check(dict))
+            result = PyDict_Keys(dict);
+        else {
+            const char *name = PyModule_GetName(self);
+            if (name)
+                PyErr_Format(PyExc_TypeError,
+                             "%.200s.__dict__ is not a dictionary",
+                             name);
+        }
+    }
+
+    Py_XDECREF(dict);
+    return result;
+}
+
+static PyMethodDef module_methods[] = {
+    {"__dir__", module_dir, METH_NOARGS,
+     PyDoc_STR("__dir__() -> list\nspecialized dir() implementation")},
+    {0}
+};
+
 
 PyDoc_STRVAR(module_doc,
 "module(name[, doc])\n\
@@ -449,7 +477,7 @@
     0,                                          /* tp_weaklistoffset */
     0,                                          /* tp_iter */
     0,                                          /* tp_iternext */
-    0,                                          /* tp_methods */
+    module_methods,                             /* tp_methods */
     module_members,                             /* tp_members */
     0,                                          /* tp_getset */
     0,                                          /* tp_base */
diff --git a/Objects/object.c b/Objects/object.c
index d8e2ffb..e42c1d9 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -1182,66 +1182,6 @@
     return x->ob_type->tp_call != NULL;
 }
 
-/* ------------------------- PyObject_Dir() helpers ------------------------- */
-
-/* Helper for PyObject_Dir.
-   Merge the __dict__ of aclass into dict, and recursively also all
-   the __dict__s of aclass's base classes.  The order of merging isn't
-   defined, as it's expected that only the final set of dict keys is
-   interesting.
-   Return 0 on success, -1 on error.
-*/
-
-static int
-merge_class_dict(PyObject* dict, PyObject* aclass)
-{
-    PyObject *classdict;
-    PyObject *bases;
-
-    assert(PyDict_Check(dict));
-    assert(aclass);
-
-    /* Merge in the type's dict (if any). */
-    classdict = PyObject_GetAttrString(aclass, "__dict__");
-    if (classdict == NULL)
-        PyErr_Clear();
-    else {
-        int status = PyDict_Update(dict, classdict);
-        Py_DECREF(classdict);
-        if (status < 0)
-            return -1;
-    }
-
-    /* Recursively merge in the base types' (if any) dicts. */
-    bases = PyObject_GetAttrString(aclass, "__bases__");
-    if (bases == NULL)
-        PyErr_Clear();
-    else {
-        /* We have no guarantee that bases is a real tuple */
-        Py_ssize_t i, n;
-        n = PySequence_Size(bases); /* This better be right */
-        if (n < 0)
-            PyErr_Clear();
-        else {
-            for (i = 0; i < n; i++) {
-                int status;
-                PyObject *base = PySequence_GetItem(bases, i);
-                if (base == NULL) {
-                    Py_DECREF(bases);
-                    return -1;
-                }
-                status = merge_class_dict(dict, base);
-                Py_DECREF(base);
-                if (status < 0) {
-                    Py_DECREF(bases);
-                    return -1;
-                }
-            }
-        }
-        Py_DECREF(bases);
-    }
-    return 0;
-}
 
 /* Helper for PyObject_Dir without arguments: returns the local scope. */
 static PyObject *
@@ -1269,133 +1209,34 @@
     return names;
 }
 
-/* Helper for PyObject_Dir of type objects: returns __dict__ and __bases__.
-   We deliberately don't suck up its __class__, as methods belonging to the
-   metaclass would probably be more confusing than helpful.
-*/
-static PyObject *
-_specialized_dir_type(PyObject *obj)
-{
-    PyObject *result = NULL;
-    PyObject *dict = PyDict_New();
-
-    if (dict != NULL && merge_class_dict(dict, obj) == 0)
-        result = PyDict_Keys(dict);
-
-    Py_XDECREF(dict);
-    return result;
-}
-
-/* Helper for PyObject_Dir of module objects: returns the module's __dict__. */
-static PyObject *
-_specialized_dir_module(PyObject *obj)
-{
-    PyObject *result = NULL;
-    PyObject *dict = PyObject_GetAttrString(obj, "__dict__");
-
-    if (dict != NULL) {
-        if (PyDict_Check(dict))
-            result = PyDict_Keys(dict);
-        else {
-            const char *name = PyModule_GetName(obj);
-            if (name)
-                PyErr_Format(PyExc_TypeError,
-                             "%.200s.__dict__ is not a dictionary",
-                             name);
-        }
-    }
-
-    Py_XDECREF(dict);
-    return result;
-}
-
-/* Helper for PyObject_Dir of generic objects: returns __dict__, __class__,
-   and recursively up the __class__.__bases__ chain.
-*/
-static PyObject *
-_generic_dir(PyObject *obj)
-{
-    PyObject *result = NULL;
-    PyObject *dict = NULL;
-    PyObject *itsclass = NULL;
-
-    /* Get __dict__ (which may or may not be a real dict...) */
-    dict = PyObject_GetAttrString(obj, "__dict__");
-    if (dict == NULL) {
-        PyErr_Clear();
-        dict = PyDict_New();
-    }
-    else if (!PyDict_Check(dict)) {
-        Py_DECREF(dict);
-        dict = PyDict_New();
-    }
-    else {
-        /* Copy __dict__ to avoid mutating it. */
-        PyObject *temp = PyDict_Copy(dict);
-        Py_DECREF(dict);
-        dict = temp;
-    }
-
-    if (dict == NULL)
-        goto error;
-
-    /* Merge in attrs reachable from its class. */
-    itsclass = PyObject_GetAttrString(obj, "__class__");
-    if (itsclass == NULL)
-        /* XXX(tomer): Perhaps fall back to obj->ob_type if no
-                       __class__ exists? */
-        PyErr_Clear();
-    else {
-        if (merge_class_dict(dict, itsclass) != 0)
-            goto error;
-    }
-
-    result = PyDict_Keys(dict);
-    /* fall through */
-error:
-    Py_XDECREF(itsclass);
-    Py_XDECREF(dict);
-    return result;
-}
-
-/* Helper for PyObject_Dir: object introspection.
-   This calls one of the above specialized versions if no __dir__ method
-   exists. */
+/* Helper for PyObject_Dir: object introspection. */
 static PyObject *
 _dir_object(PyObject *obj)
 {
-    PyObject *result = NULL;
+    PyObject *result;
     static PyObject *dir_str = NULL;
     PyObject *dirfunc = _PyObject_LookupSpecial(obj, "__dir__", &dir_str);
 
     assert(obj);
     if (dirfunc == NULL) {
-        if (PyErr_Occurred())
-            return NULL;
-        /* use default implementation */
-        if (PyModule_Check(obj))
-            result = _specialized_dir_module(obj);
-        else if (PyType_Check(obj))
-            result = _specialized_dir_type(obj);
-        else
-            result = _generic_dir(obj);
+        if (!PyErr_Occurred())
+            PyErr_SetString(PyExc_TypeError, "object does not provide __dir__");
+        return NULL;
     }
-    else {
-        /* use __dir__ */
-        result = PyObject_CallFunctionObjArgs(dirfunc, NULL);
-        Py_DECREF(dirfunc);
-        if (result == NULL)
-            return NULL;
+    /* use __dir__ */
+    result = PyObject_CallFunctionObjArgs(dirfunc, NULL);
+    Py_DECREF(dirfunc);
+    if (result == NULL)
+        return NULL;
 
-        /* result must be a list */
-        /* XXX(gbrandl): could also check if all items are strings */
-        if (!PyList_Check(result)) {
-            PyErr_Format(PyExc_TypeError,
-                         "__dir__() must return a list, not %.200s",
-                         Py_TYPE(result)->tp_name);
-            Py_DECREF(result);
-            result = NULL;
-        }
+    /* result must be a list */
+    /* XXX(gbrandl): could also check if all items are strings */
+    if (!PyList_Check(result)) {
+        PyErr_Format(PyExc_TypeError,
+                     "__dir__() must return a list, not %.200s",
+                     Py_TYPE(result)->tp_name);
+        Py_DECREF(result);
+        result = NULL;
     }
 
     return result;
diff --git a/Objects/setobject.c b/Objects/setobject.c
index 48edad8..ebfddb3 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -607,16 +607,18 @@
         goto done;
     newsize = PyUnicode_GET_SIZE(listrepr);
     result = PyUnicode_FromUnicode(NULL, newsize);
-    if (result) {
-        u = PyUnicode_AS_UNICODE(result);
-        *u++ = '{';
-        /* Omit the brackets from the listrepr */
-        Py_UNICODE_COPY(u, PyUnicode_AS_UNICODE(listrepr)+1,
-                           PyUnicode_GET_SIZE(listrepr)-2);
-        u += newsize-2;
-        *u++ = '}';
-    }
+    if (result == NULL)
+        goto done;
+
+    u = PyUnicode_AS_UNICODE(result);
+    *u++ = '{';
+    /* Omit the brackets from the listrepr */
+    Py_UNICODE_COPY(u, PyUnicode_AS_UNICODE(listrepr)+1,
+                       newsize-2);
+    u += newsize-2;
+    *u = '}';
     Py_DECREF(listrepr);
+
     if (Py_TYPE(so) != &PySet_Type) {
         PyObject *tmp = PyUnicode_FromFormat("%s(%U)",
                                              Py_TYPE(so)->tp_name,
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 434608f..02f86ef 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2572,6 +2572,82 @@
     return PyDict_New();
 }
 
+/* 
+   Merge the __dict__ of aclass into dict, and recursively also all
+   the __dict__s of aclass's base classes.  The order of merging isn't
+   defined, as it's expected that only the final set of dict keys is
+   interesting.
+   Return 0 on success, -1 on error.
+*/
+
+static int
+merge_class_dict(PyObject *dict, PyObject *aclass)
+{
+    PyObject *classdict;
+    PyObject *bases;
+
+    assert(PyDict_Check(dict));
+    assert(aclass);
+
+    /* Merge in the type's dict (if any). */
+    classdict = PyObject_GetAttrString(aclass, "__dict__");
+    if (classdict == NULL)
+        PyErr_Clear();
+    else {
+        int status = PyDict_Update(dict, classdict);
+        Py_DECREF(classdict);
+        if (status < 0)
+            return -1;
+    }
+
+    /* Recursively merge in the base types' (if any) dicts. */
+    bases = PyObject_GetAttrString(aclass, "__bases__");
+    if (bases == NULL)
+        PyErr_Clear();
+    else {
+        /* We have no guarantee that bases is a real tuple */
+        Py_ssize_t i, n;
+        n = PySequence_Size(bases); /* This better be right */
+        if (n < 0)
+            PyErr_Clear();
+        else {
+            for (i = 0; i < n; i++) {
+                int status;
+                PyObject *base = PySequence_GetItem(bases, i);
+                if (base == NULL) {
+                    Py_DECREF(bases);
+                    return -1;
+                }
+                status = merge_class_dict(dict, base);
+                Py_DECREF(base);
+                if (status < 0) {
+                    Py_DECREF(bases);
+                    return -1;
+                }
+            }
+        }
+        Py_DECREF(bases);
+    }
+    return 0;
+}
+
+/* __dir__ for type objects: returns __dict__ and __bases__.
+   We deliberately don't suck up its __class__, as methods belonging to the
+   metaclass would probably be more confusing than helpful.
+*/
+static PyObject *
+type_dir(PyObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    PyObject *dict = PyDict_New();
+
+    if (dict != NULL && merge_class_dict(dict, self) == 0)
+        result = PyDict_Keys(dict);
+
+    Py_XDECREF(dict);
+    return result;
+}
+
 static PyMethodDef type_methods[] = {
     {"mro", (PyCFunction)mro_external, METH_NOARGS,
      PyDoc_STR("mro() -> list\nreturn a type's method resolution order")},
@@ -2582,9 +2658,11 @@
      PyDoc_STR("__prepare__() -> dict\n"
                "used to create the namespace for the class statement")},
     {"__instancecheck__", type___instancecheck__, METH_O,
-     PyDoc_STR("__instancecheck__() -> check if an object is an instance")},
+     PyDoc_STR("__instancecheck__() -> bool\ncheck if an object is an instance")},
     {"__subclasscheck__", type___subclasscheck__, METH_O,
-     PyDoc_STR("__subclasscheck__() -> check if a class is a subclass")},
+     PyDoc_STR("__subclasscheck__() -> bool\ncheck if a class is a subclass")},
+    {"__dir__", type_dir, METH_NOARGS,
+     PyDoc_STR("__dir__() -> list\nspecialized __dir__ implementation for types")},
     {0}
 };
 
@@ -3438,6 +3516,53 @@
     return PyLong_FromSsize_t(res);
 }
 
+/* __dir__ for generic objects: returns __dict__, __class__,
+   and recursively up the __class__.__bases__ chain.
+*/
+static PyObject *
+object_dir(PyObject *self, PyObject *args)
+{
+    PyObject *result = NULL;
+    PyObject *dict = NULL;
+    PyObject *itsclass = NULL;
+
+    /* Get __dict__ (which may or may not be a real dict...) */
+    dict = PyObject_GetAttrString(self, "__dict__");
+    if (dict == NULL) {
+        PyErr_Clear();
+        dict = PyDict_New();
+    }
+    else if (!PyDict_Check(dict)) {
+        Py_DECREF(dict);
+        dict = PyDict_New();
+    }
+    else {
+        /* Copy __dict__ to avoid mutating it. */
+        PyObject *temp = PyDict_Copy(dict);
+        Py_DECREF(dict);
+        dict = temp;
+    }
+
+    if (dict == NULL)
+        goto error;
+
+    /* Merge in attrs reachable from its class. */
+    itsclass = PyObject_GetAttrString(self, "__class__");
+    if (itsclass == NULL)
+        /* XXX(tomer): Perhaps fall back to obj->ob_type if no
+                       __class__ exists? */
+        PyErr_Clear();
+    else if (merge_class_dict(dict, itsclass) != 0)
+        goto error;
+
+    result = PyDict_Keys(dict);
+    /* fall through */
+error:
+    Py_XDECREF(itsclass);
+    Py_XDECREF(dict);
+    return result;
+}
+
 static PyMethodDef object_methods[] = {
     {"__reduce_ex__", object_reduce_ex, METH_VARARGS,
      PyDoc_STR("helper for pickle")},
@@ -3448,7 +3573,9 @@
     {"__format__", object_format, METH_VARARGS,
      PyDoc_STR("default object formatter")},
     {"__sizeof__", object_sizeof, METH_NOARGS,
-     PyDoc_STR("__sizeof__() -> size of object in memory, in bytes")},
+     PyDoc_STR("__sizeof__() -> int\nsize of object in memory, in bytes")},
+    {"__dir__", object_dir, METH_NOARGS,
+     PyDoc_STR("__dir__() -> list\ndefault dir() implementation")},
     {0}
 };
 
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 4361908..309159c 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -6474,7 +6474,7 @@
         }
     }
     /* 0-terminate the output string */
-    *output++ = '\0';
+    *output = '\0';
     Py_XDECREF(exc);
     Py_XDECREF(errorHandler);
     return 0;
diff --git a/Python/compile.c b/Python/compile.c
index 53f5a12..d195967 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -3747,11 +3747,11 @@
     a->a_lnotab_off += 2;
     if (d_bytecode) {
         *lnotab++ = d_bytecode;
-        *lnotab++ = d_lineno;
+        *lnotab = d_lineno;
     }
     else {      /* First line of a block; def stmt, etc. */
         *lnotab++ = 0;
-        *lnotab++ = d_lineno;
+        *lnotab = d_lineno;
     }
     a->a_lineno = i->i_lineno;
     a->a_lineno_off = a->a_offset;
@@ -3796,7 +3796,7 @@
     if (i->i_hasarg) {
         assert(size == 3 || size == 6);
         *code++ = arg & 0xff;
-        *code++ = arg >> 8;
+        *code = arg >> 8;
     }
     return 1;
 }
diff --git a/Python/import.c b/Python/import.c
index 5360d57..1f28d22 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1733,7 +1733,6 @@
     Py_UNICODE buf[MAXPATHLEN+1];
     Py_ssize_t buflen = MAXPATHLEN+1;
     PyObject *path_unicode, *filename;
-    const Py_UNICODE *base;
     Py_ssize_t len;
     struct stat statbuf;
     static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
@@ -1751,7 +1750,6 @@
     else
         return 0;
 
-    base = PyUnicode_AS_UNICODE(path_unicode);
     len = PyUnicode_GET_SIZE(path_unicode);
     if (len + 2 + PyUnicode_GET_SIZE(name) + MAXSUFFIXSIZE >= buflen) {
         Py_DECREF(path_unicode);
@@ -2275,12 +2273,10 @@
 static int
 find_init_module(PyObject *directory)
 {
-    size_t len;
     struct stat statbuf;
     PyObject *filename;
     int match;
 
-    len = PyUnicode_GET_SIZE(directory);
     filename = PyUnicode_FromFormat("%U%c__init__.py", directory, SEP);
     if (filename == NULL)
         return -1;
@@ -2818,7 +2814,7 @@
 }
 
 PyObject *
-PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
+PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals,
                            PyObject *fromlist, int level)
 {
     PyObject *nameobj, *mod;
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index b55dc5b..232d7be 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1593,7 +1593,7 @@
         moduleName = PyObject_GetAttrString(type, "__module__");
         if (moduleName == NULL || !PyUnicode_Check(moduleName))
         {
-            Py_DECREF(moduleName);
+            Py_XDECREF(moduleName);
             err = PyFile_WriteString("<unknown>", f);
         }
         else {
diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py
index 53e652d..5db62cd 100644
--- a/Tools/msi/msi.py
+++ b/Tools/msi/msi.py
@@ -1031,6 +1031,8 @@
             lib.glob("*.0")
         if dir=='tests' and parent.physical=='distutils':
             lib.add_file("Setup.sample")
+        if dir=='cjkencodings':
+            lib.glob("*.txt")
         if dir=='decimaltestdata':
             lib.glob("*.decTest")
         if dir=='xmltestdata':