Branch merge
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index 35dea41..b79d5fc 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.
diff --git a/Lib/socketserver.py b/Lib/socketserver.py
index 089b3ba..7389608 100644
--- a/Lib/socketserver.py
+++ b/Lib/socketserver.py
@@ -549,7 +549,6 @@
                 self.active_children = []
             self.active_children.append(pid)
             self.close_request(request)
-            return
         else:
             # Child process.
             # This must never return, hence os._exit()!
diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
index 41bccf3..2279a51 100644
--- a/Lib/sysconfig.py
+++ b/Lib/sysconfig.py
@@ -294,7 +294,7 @@
                         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:
@@ -302,7 +302,9 @@
 
 
             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/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_io.py b/Lib/test/test_io.py
index dac30cb..707b7cb 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -827,14 +827,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)
@@ -2505,6 +2508,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_sysconfig.py b/Lib/test/test_sysconfig.py
index a97b388..2ea8819 100644
--- a/Lib/test/test_sysconfig.py
+++ b/Lib/test/test_sysconfig.py
@@ -26,7 +26,6 @@
         """Make a copy of sys.path"""
         super(TestSysConfig, self).setUp()
         self.sys_path = sys.path[:]
-        self.makefile = None
         # patching os.uname
         if hasattr(os, 'uname'):
             self.uname = os.uname
@@ -49,8 +48,6 @@
     def tearDown(self):
         """Restore sys.path"""
         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
@@ -236,12 +233,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')
@@ -339,10 +330,33 @@
         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 db870a4..50ba086 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -909,8 +909,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 \
 		concurrent concurrent/futures encodings \
 		email email/mime email/test email/test/data \
diff --git a/Misc/NEWS b/Misc/NEWS
index fac8078..ce6c964 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,20 @@
 Library
 -------
 
+- 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 #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 #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.
 
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
index 1aa5ee9..141b6de 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -583,6 +583,8 @@
     Py_ssize_t total = 0;
     int n;
 
+    if (self->fd < 0)
+        return err_closed();
     if (!_PyVerify_fd(self->fd))
         return PyErr_SetFromErrno(PyExc_IOError);
 
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/_testembed.c b/Modules/_testembed.c
index 0df5ede..51b439f 100644
--- a/Modules/_testembed.c
+++ b/Modules/_testembed.c
@@ -17,7 +17,9 @@
 int main(int argc, char *argv[])
 {
     PyThreadState *mainstate, *substate;
+#ifdef WITH_THREAD
     PyGILState_STATE gilstate;
+#endif
     int i, j;
 
     for (i=0; i<3; i++) {
@@ -28,10 +30,12 @@
         Py_Initialize();
         mainstate = PyThreadState_Get();
 
+#ifdef WITH_THREAD
         PyEval_InitThreads();
         PyEval_ReleaseThread(mainstate);
 
         gilstate = PyGILState_Ensure();
+#endif
         print_subinterp();
         PyThreadState_Swap(NULL);
 
@@ -43,7 +47,9 @@
 
         PyThreadState_Swap(mainstate);
         print_subinterp();
+#ifdef WITH_THREAD
         PyGILState_Release(gilstate);
+#endif
 
         PyEval_RestoreThread(mainstate);
         Py_Finalize();
diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c
index af7ea5b..7b04f020 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;
@@ -514,7 +514,7 @@
             break;
     }
 
-    if (codec->encreset != NULL)
+    if (codec->encreset != NULL && (flags & MBENC_RESET))
         for (;;) {
             Py_ssize_t outleft;
 
@@ -784,8 +784,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/Objects/typeobject.c b/Objects/typeobject.c
index 8eaf51f..3c724fd 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2582,9 +2582,9 @@
      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")},
     {0}
 };
 
@@ -3430,7 +3430,7 @@
     {"__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")},
     {0}
 };
 
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':