merge
diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst
index 66b2fb4..2054ce6 100644
--- a/Doc/library/csv.rst
+++ b/Doc/library/csv.rst
@@ -164,36 +164,43 @@
 The :mod:`csv` module defines the following classes:
 
 
-.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)
+.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, \
+                      dialect='excel', *args, **kwds)
 
-   Create an object which operates like a regular reader but maps the information
-   read into a dict whose keys are given by the optional  *fieldnames* parameter.
-   If the *fieldnames* parameter is omitted, the values in the first row of the
-   *csvfile* will be used as the fieldnames.  If the row read has more fields
-   than the fieldnames sequence, the remaining data is added as a sequence
-   keyed by the value of *restkey*.  If the row read has fewer fields than the
-   fieldnames sequence, the remaining keys take the value of the optional
-   *restval* parameter.  Any other optional or keyword arguments are passed to
-   the underlying :class:`reader` instance.
+   Create an object which operates like a regular reader but maps the
+   information read into a dict whose keys are given by the optional
+   *fieldnames* parameter.  The *fieldnames* parameter is a :ref:`sequence
+   <collections-abstract-base-classes>` whose elements are associated with the
+   fields of the input data in order. These elements become the keys of the
+   resulting dictionary.  If the *fieldnames* parameter is omitted, the values
+   in the first row of the *csvfile* will be used as the fieldnames.  If the
+   row read has more fields than the fieldnames sequence, the remaining data is
+   added as a sequence keyed by the value of *restkey*.  If the row read has
+   fewer fields than the fieldnames sequence, the remaining keys take the value
+   of the optional *restval* parameter.  Any other optional or keyword
+   arguments are passed to the underlying :class:`reader` instance.
 
 
-.. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)
+.. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', \
+                      dialect='excel', *args, **kwds)
 
-   Create an object which operates like a regular writer but maps dictionaries onto
-   output rows.  The *fieldnames* parameter identifies the order in which values in
-   the dictionary passed to the :meth:`writerow` method are written to the
-   *csvfile*.  The optional *restval* parameter specifies the value to be written
-   if the dictionary is missing a key in *fieldnames*.  If the dictionary passed to
-   the :meth:`writerow` method contains a key not found in *fieldnames*, the
-   optional *extrasaction* parameter indicates what action to take.  If it is set
-   to ``'raise'`` a :exc:`ValueError` is raised.  If it is set to ``'ignore'``,
-   extra values in the dictionary are ignored.  Any other optional or keyword
-   arguments are passed to the underlying :class:`writer` instance.
+   Create an object which operates like a regular writer but maps dictionaries
+   onto output rows.  The *fieldnames* parameter is a :ref:`sequence
+   <collections-abstract-base-classes>` of keys that identify the order in
+   which values in the dictionary passed to the :meth:`writerow` method are
+   written to the *csvfile*.  The optional *restval* parameter specifies the
+   value to be written if the dictionary is missing a key in *fieldnames*.  If
+   the dictionary passed to the :meth:`writerow` method contains a key not
+   found in *fieldnames*, the optional *extrasaction* parameter indicates what
+   action to take.  If it is set to ``'raise'`` a :exc:`ValueError` is raised.
+   If it is set to ``'ignore'``, extra values in the dictionary are ignored.
+   Any other optional or keyword arguments are passed to the underlying
+   :class:`writer` instance.
 
-   Note that unlike the :class:`DictReader` class, the *fieldnames* parameter of
-   the :class:`DictWriter` is not optional.  Since Python's :class:`dict` objects
-   are not ordered, there is not enough information available to deduce the order
-   in which the row should be written to the *csvfile*.
+   Note that unlike the :class:`DictReader` class, the *fieldnames* parameter
+   of the :class:`DictWriter` is not optional.  Since Python's :class:`dict`
+   objects are not ordered, there is not enough information available to deduce
+   the order in which the row should be written to the *csvfile*.
 
 
 .. class:: Dialect
diff --git a/Lib/fileinput.py b/Lib/fileinput.py
index 04e97bd..21c2d1f 100644
--- a/Lib/fileinput.py
+++ b/Lib/fileinput.py
@@ -387,9 +387,10 @@
 
 
 def hook_encoded(encoding):
-    import codecs
+    import io
     def openhook(filename, mode):
-        return codecs.open(filename, mode, encoding)
+        mode = mode.replace('U', '').replace('b', '') or 'r'
+        return io.open(filename, mode, encoding=encoding, newline='')
     return openhook
 
 
diff --git a/Lib/idlelib/idle_test/README.txt b/Lib/idlelib/idle_test/README.txt
index d0dde25..6b92483 100644
--- a/Lib/idlelib/idle_test/README.txt
+++ b/Lib/idlelib/idle_test/README.txt
@@ -41,9 +41,10 @@
 screen, gui tests must be 'guarded' by "requires('gui')" in a setUp
 function or method. This will typically be setUpClass.
 
-All gui objects must be destroyed by the end of the test, perhaps in a tearDown
-function. Creating the Tk root directly in a setUp allows a reference to be saved
-so it can be properly destroyed in the corresponding tearDown. 
+To avoid interfering with other gui tests, all gui objects must be destroyed
+and deleted by the end of the test.  If a widget, such as a Tk root, is created
+in a setUpX function, destroy it in the corresponding tearDownX.  For module
+and class attributes, also delete the widget.
 ---
     @classmethod
     def setUpClass(cls):
@@ -53,6 +54,7 @@
     @classmethod
     def tearDownClass(cls):
         cls.root.destroy()
+        del cls.root
 ---
 
 Support.requires('gui') returns true if it is either called in a main module
diff --git a/Lib/idlelib/idle_test/test_formatparagraph.py b/Lib/idlelib/idle_test/test_formatparagraph.py
index 7d7affc..eed2286 100644
--- a/Lib/idlelib/idle_test/test_formatparagraph.py
+++ b/Lib/idlelib/idle_test/test_formatparagraph.py
@@ -277,6 +277,9 @@
     @classmethod
     def tearDownClass(cls):
         cls.root.destroy()
+        del cls.root
+        del cls.text
+        del cls.formatter
 
     def test_short_line(self):
         self.text.insert('1.0', "Short line\n")
diff --git a/Lib/idlelib/idle_test/test_idlehistory.py b/Lib/idlelib/idle_test/test_idlehistory.py
index c15a926..dc6bb32 100644
--- a/Lib/idlelib/idle_test/test_idlehistory.py
+++ b/Lib/idlelib/idle_test/test_idlehistory.py
@@ -80,6 +80,7 @@
     @classmethod
     def tearDownClass(cls):
         cls.root.destroy()
+        del cls.root
 
     def fetch_test(self, reverse, line, prefix, index, bell=False):
         # Perform one fetch as invoked by Alt-N or Alt-P
diff --git a/Lib/idlelib/idle_test/test_searchengine.py b/Lib/idlelib/idle_test/test_searchengine.py
index e5e720d..2525a13 100644
--- a/Lib/idlelib/idle_test/test_searchengine.py
+++ b/Lib/idlelib/idle_test/test_searchengine.py
@@ -64,6 +64,7 @@
 ##    @classmethod
 ##    def tearDownClass(cls):
 ##        cls.root.destroy()
+##        del cls.root
 
     def test_get_selection(self):
         # text = Text(master=self.root)
@@ -219,6 +220,7 @@
 ##    @classmethod
 ##    def tearDownClass(cls):
 ##        cls.root.destroy()
+##        del cls.root
 
     def test_search(self):
         Equal = self.assertEqual
@@ -261,6 +263,7 @@
 ##    @classmethod
 ##    def tearDownClass(cls):
 ##        cls.root.destroy()
+##        del cls.root
 
     @classmethod
     def setUpClass(cls):
diff --git a/Lib/idlelib/idle_test/test_text.py b/Lib/idlelib/idle_test/test_text.py
index 3a0705b..f0b9b76 100644
--- a/Lib/idlelib/idle_test/test_text.py
+++ b/Lib/idlelib/idle_test/test_text.py
@@ -221,6 +221,7 @@
     @classmethod
     def tearDownClass(cls):
         cls.root.destroy()
+        del cls.root
 
 
 if __name__ == '__main__':
diff --git a/Lib/lib-tk/turtle.py b/Lib/lib-tk/turtle.py
index f8188e1..8d7cdc0 100644
--- a/Lib/lib-tk/turtle.py
+++ b/Lib/lib-tk/turtle.py
@@ -835,7 +835,7 @@
             if isinstance(data, list):
                 data = tuple(data)
         elif type_ == "image":
-            if isinstance(data, str):
+            if isinstance(data, basestring):
                 if data.lower().endswith(".gif") and isfile(data):
                     data = TurtleScreen._image(data)
                 # else data assumed to be Photoimage
@@ -1098,7 +1098,7 @@
         """
         if len(color) == 1:
             color = color[0]
-        if isinstance(color, str):
+        if isinstance(color, basestring):
             if self._iscolorstring(color) or color == "":
                 return color
             else:
@@ -2602,7 +2602,7 @@
     def _cc(self, args):
         """Convert colortriples to hexstrings.
         """
-        if isinstance(args, str):
+        if isinstance(args, basestring):
             return args
         try:
             r, g, b = args
@@ -3228,7 +3228,7 @@
         """
         #print "dot-1:", size, color
         if not color:
-            if isinstance(size, (str, tuple)):
+            if isinstance(size, (basestring, tuple)):
                 color = self._colorstr(size)
                 size = self._pensize + max(self._pensize, 4)
             else:
@@ -3913,7 +3913,7 @@
         down()
         # some text
         write("startstart", 1)
-        write("start", 1)
+        write(u"start", 1)
         color("red")
         # staircase
         for i in range(5):
@@ -3988,7 +3988,7 @@
         tri = getturtle()
         tri.resizemode("auto")
         turtle = Turtle()
-        turtle.resizemode("auto")
+        turtle.resizemode(u"auto")
         turtle.shape("turtle")
         turtle.reset()
         turtle.left(90)
@@ -3998,7 +3998,7 @@
         turtle.lt(30)
         turtle.down()
         turtle.speed(6)
-        turtle.color("blue","orange")
+        turtle.color("blue",u"orange")
         turtle.pensize(2)
         tri.speed(6)
         setheading(towards(turtle))
@@ -4013,9 +4013,9 @@
                 tri.stamp()
                 switchpen()
             count += 1
-        tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align="right")
+        tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align=u"right")
         tri.pencolor("black")
-        tri.pencolor("red")
+        tri.pencolor(u"red")
 
         def baba(xdummy, ydummy):
             clearscreen()
diff --git a/Lib/random.py b/Lib/random.py
index 1a3a13e..2f2f091 100644
--- a/Lib/random.py
+++ b/Lib/random.py
@@ -108,7 +108,7 @@
 
         if a is None:
             try:
-                a = long(_hexlify(_urandom(16)), 16)
+                a = long(_hexlify(_urandom(32)), 16)
             except NotImplementedError:
                 import time
                 a = long(time.time() * 256) # use fractional seconds
diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py
index 84aed1a..c15ad84 100644
--- a/Lib/test/test_fileinput.py
+++ b/Lib/test/test_fileinput.py
@@ -218,8 +218,49 @@
         finally:
             remove_tempfiles(t1)
 
+    def test_readline(self):
+        with open(TESTFN, 'wb') as f:
+            f.write('A\nB\r\nC\r')
+            # Fill TextIOWrapper buffer.
+            f.write('123456789\n' * 1000)
+            # Issue #20501: readline() shouldn't read whole file.
+            f.write('\x80')
+        self.addCleanup(safe_unlink, TESTFN)
+
+        fi = FileInput(files=TESTFN, openhook=hook_encoded('ascii'), bufsize=8)
+        # The most likely failure is a UnicodeDecodeError due to the entire
+        # file being read when it shouldn't have been.
+        self.assertEqual(fi.readline(), u'A\n')
+        self.assertEqual(fi.readline(), u'B\r\n')
+        self.assertEqual(fi.readline(), u'C\r')
+        with self.assertRaises(UnicodeDecodeError):
+            # Read to the end of file.
+            list(fi)
+        fi.close()
+
+class Test_hook_encoded(unittest.TestCase):
+    """Unit tests for fileinput.hook_encoded()"""
+
+    def test_modes(self):
+        with open(TESTFN, 'wb') as f:
+            # UTF-7 is a convenient, seldom used encoding
+            f.write('A\nB\r\nC\rD+IKw-')
+        self.addCleanup(safe_unlink, TESTFN)
+
+        def check(mode, expected_lines):
+            fi = FileInput(files=TESTFN, mode=mode,
+                           openhook=hook_encoded('utf-7'))
+            lines = list(fi)
+            fi.close()
+            self.assertEqual(lines, expected_lines)
+
+        check('r', [u'A\n', u'B\r\n', u'C\r', u'D\u20ac'])
+        check('rU', [u'A\n', u'B\r\n', u'C\r', u'D\u20ac'])
+        check('U', [u'A\n', u'B\r\n', u'C\r', u'D\u20ac'])
+        check('rb', [u'A\n', u'B\r\n', u'C\r', u'D\u20ac'])
+
 def test_main():
-    run_unittest(BufferSizesTests, FileInputTests)
+    run_unittest(BufferSizesTests, FileInputTests, Test_hook_encoded)
 
 if __name__ == "__main__":
     test_main()
diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py
index 07f45c6..495b416 100644
--- a/Lib/test/test_idle.py
+++ b/Lib/test/test_idle.py
@@ -14,6 +14,7 @@
     try:
         root = tk.Tk()
         root.destroy()
+        del root
     except tk.TclError:
         while 'gui' in use_resources:
             use_resources.remove('gui')
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index a6d47af..76a74fb 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -546,7 +546,7 @@
     def test_initgroups(self):
         # find missing group
 
-        g = max(self.saved_groups) + 1
+        g = max(self.saved_groups or [0]) + 1
         name = pwd.getpwuid(posix.getuid()).pw_name
         posix.initgroups(name, g)
         self.assertIn(g, posix.getgroups())
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index fe71c84..d769288 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -933,6 +933,19 @@
         self.assertEqual(out.getvalue().splitlines(),
                          ['literal 102', 'literal 111', 'literal 111'])
 
+    def test_keyword_parameters(self):
+        # Issue #20283: Accepting the string keyword parameter.
+        pat = re.compile(r'(ab)')
+        self.assertEqual(
+            pat.match(string='abracadabra', pos=7, endpos=10).span(), (7, 9))
+        self.assertEqual(
+            pat.search(string='abracadabra', pos=3, endpos=10).span(), (7, 9))
+        self.assertEqual(
+            pat.findall(string='abracadabra', pos=3, endpos=10), ['ab'])
+        self.assertEqual(
+            pat.split(string='abracadabra', maxsplit=1),
+            ['', 'ab', 'racadabra'])
+
 
 def run_re_tests():
     from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR
diff --git a/Misc/ACKS b/Misc/ACKS
index 28d6f15..ad47f9c 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -33,6 +33,8 @@
 Erik Andersén
 Oliver Andrich
 Ross Andrus
+Juancarlo Añez
+Chris Angelico
 Ankur Ankan
 Heidi Annexstad
 Éric Araujo
diff --git a/Misc/NEWS b/Misc/NEWS
index 49d1630..e974ee4 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -40,6 +40,20 @@
 Library
 -------
 
+- Issue #20283: RE pattern methods now accept the string keyword parameters
+  as documented.  The pattern and source keyword parameters are left as
+  deprecated aliases.
+
+- Improve the random module's default seeding to use 256 bits of entropy
+  from os.urandom().  This was already done for Python 3, mildly improving
+  security with a bigger seed space.
+
+- Issue #15618: Make turtle.py compatible with 'from __future__ import
+  unicode_literals'.  Initial patch by Juancarlo Añez.
+
+- Issue #20501: fileinput module no longer reads whole file into memory when using
+  fileinput.hook_encoded.
+
 - Issue #6815: os.path.expandvars() now supports non-ASCII Unicode environment
   variables names and values.
 
@@ -50,7 +64,7 @@
   Based on patch by Stephen Tu.
 
 - Issue #8478: Untokenizer.compat processes first token from iterator input.
-  Patch based on lines from Georg Brandl, Eric Snow, and Gareth Rees.  
+  Patch based on lines from Georg Brandl, Eric Snow, and Gareth Rees.
 
 - Issue #20594: Avoid name clash with the libc function posix_close.
 
diff --git a/Modules/_sre.c b/Modules/_sre.c
index bf802a6..d88c13f 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -1875,18 +1875,62 @@
     PyObject_DEL(self);
 }
 
+static int
+check_args_size(const char *name, PyObject* args, PyObject* kw, int n)
+{
+    Py_ssize_t m = PyTuple_GET_SIZE(args) + (kw ? PyDict_Size(kw) : 0);
+    if (m <= n)
+        return 1;
+    PyErr_Format(PyExc_TypeError,
+                 "%s() takes at most %d positional arguments (%zd given)",
+                 name, n, m);
+    return 0;
+}
+
+static PyObject*
+fix_string_param(PyObject *string, PyObject *string2, const char *oldname)
+{
+    if (string2 != NULL) {
+        char buf[100];
+        if (string != NULL) {
+            PyErr_Format(PyExc_TypeError,
+                         "Argument given by name ('%s') and position (1)",
+                         oldname);
+            return NULL;
+        }
+        sprintf(buf, "The '%s' keyword parameter name is deprecated.  "
+                     "Use 'string' instead.", oldname);
+        if (PyErr_Warn(PyExc_DeprecationWarning, buf) < 0)
+            return NULL;
+        return string2;
+    }
+    if (string == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "Required argument 'string' (pos 1) not found");
+        return NULL;
+    }
+    return string;
+}
+
 static PyObject*
 pattern_match(PatternObject* self, PyObject* args, PyObject* kw)
 {
     SRE_STATE state;
     int status;
 
-    PyObject* string;
+    PyObject *string = NULL, *string2 = NULL;
     Py_ssize_t start = 0;
     Py_ssize_t end = PY_SSIZE_T_MAX;
-    static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:match", kwlist,
-                                     &string, &start, &end))
+    static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
+    if (!check_args_size("match", args, kw, 3))
+        return NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnnO:match", kwlist,
+                                     &string, &start, &end, &string2))
+        return NULL;
+
+    string = fix_string_param(string, string2, "pattern");
+    if (!string)
         return NULL;
 
     string = state_init(&state, self, string, start, end);
@@ -1920,12 +1964,19 @@
     SRE_STATE state;
     int status;
 
-    PyObject* string;
+    PyObject *string = NULL, *string2 = NULL;
     Py_ssize_t start = 0;
     Py_ssize_t end = PY_SSIZE_T_MAX;
-    static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist,
-                                     &string, &start, &end))
+    static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
+    if (!check_args_size("search", args, kw, 3))
+        return NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnnO:search", kwlist,
+                                     &string, &start, &end, &string2))
+        return NULL;
+
+    string = fix_string_param(string, string2, "pattern");
+    if (!string)
         return NULL;
 
     string = state_init(&state, self, string, start, end);
@@ -2055,12 +2106,19 @@
     int status;
     Py_ssize_t i, b, e;
 
-    PyObject* string;
+    PyObject *string = NULL, *string2 = NULL;
     Py_ssize_t start = 0;
     Py_ssize_t end = PY_SSIZE_T_MAX;
-    static char* kwlist[] = { "source", "pos", "endpos", NULL };
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist,
-                                     &string, &start, &end))
+    static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
+    if (!check_args_size("findall", args, kw, 3))
+        return NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnnO:findall", kwlist,
+                                     &string, &start, &end, &string2))
+        return NULL;
+
+    string = fix_string_param(string, string2, "source");
+    if (!string)
         return NULL;
 
     string = state_init(&state, self, string, start, end);
@@ -2185,11 +2243,18 @@
     Py_ssize_t i;
     void* last;
 
-    PyObject* string;
+    PyObject *string = NULL, *string2 = NULL;
     Py_ssize_t maxsplit = 0;
-    static char* kwlist[] = { "source", "maxsplit", NULL };
-    if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist,
-                                     &string, &maxsplit))
+    static char* kwlist[] = { "string", "maxsplit", "source", NULL };
+    if (!check_args_size("split", args, kw, 2))
+        return NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnO:split", kwlist,
+                                     &string, &maxsplit, &string2))
+        return NULL;
+
+    string = fix_string_param(string, string2, "source");
+    if (!string)
         return NULL;
 
     string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);