Issue #5761: Add the name of the underlying file to the repr() of various IO objects.
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index c9a7c5e..c1cdf43 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -736,6 +736,15 @@
     def mode(self):
         return self.raw.mode
 
+    def __repr__(self):
+        clsname = self.__class__.__name__
+        try:
+            name = self.name
+        except AttributeError:
+            return "<_pyio.{0}>".format(clsname)
+        else:
+            return "<_pyio.{0} name={1!r}>".format(clsname, name)
+
     ### Lower-level APIs ###
 
     def fileno(self):
@@ -1455,7 +1464,13 @@
     #   - "chars_..." for integer variables that count decoded characters
 
     def __repr__(self):
-        return "<TextIOWrapper encoding={0}>".format(self.encoding)
+        try:
+            name = self.name
+        except AttributeError:
+            return "<_pyio.TextIOWrapper encoding={0!r}>".format(self.encoding)
+        else:
+            return "<_pyio.TextIOWrapper name={0!r} encoding={1!r}>".format(
+                name, self.encoding)
 
     @property
     def encoding(self):
diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py
index 9188e70..657401e 100644
--- a/Lib/test/test_fileio.py
+++ b/Lib/test/test_fileio.py
@@ -70,9 +70,13 @@
         self.assertEquals(array('b', [1, 2]), a[:n])
 
     def testRepr(self):
-        self.assertEquals(repr(self.f),
-                          "io.FileIO(%d, %s)" % (self.f.fileno(),
-                                                       repr(self.f.mode)))
+        self.assertEquals(repr(self.f), "<_io.FileIO name=%r mode=%r>"
+                                        % (self.f.name, self.f.mode))
+        del self.f.name
+        self.assertEquals(repr(self.f), "<_io.FileIO fd=%r mode=%r>"
+                                        % (self.f.fileno(), self.f.mode))
+        self.f.close()
+        self.assertEquals(repr(self.f), "<_io.FileIO [closed]>")
 
     def testErrors(self):
         f = self.f
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 08e0f13..1337b7c 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -618,6 +618,16 @@
             self.assert_(s.startswith("Exception IOError: "), s)
             self.assert_(s.endswith(" ignored"), s)
 
+    def test_repr(self):
+        raw = self.MockRawIO()
+        b = self.tp(raw)
+        clsname = "%s.%s" % (self.tp.__module__, self.tp.__name__)
+        self.assertEqual(repr(b), "<%s>" % clsname)
+        raw.name = "dummy"
+        self.assertEqual(repr(b), "<%s name='dummy'>" % clsname)
+        raw.name = b"dummy"
+        self.assertEqual(repr(b), "<%s name=b'dummy'>" % clsname)
+
 
 class BufferedReaderTest(unittest.TestCase, CommonBufferedTests):
     read_mode = "rb"
@@ -1528,7 +1538,15 @@
         raw = self.BytesIO("hello".encode("utf-8"))
         b = self.BufferedReader(raw)
         t = self.TextIOWrapper(b, encoding="utf-8")
-        self.assertEqual(repr(t), "<TextIOWrapper encoding=utf-8>")
+        modname = self.TextIOWrapper.__module__
+        self.assertEqual(repr(t),
+                         "<%s.TextIOWrapper encoding='utf-8'>" % modname)
+        raw.name = "dummy"
+        self.assertEqual(repr(t),
+                         "<%s.TextIOWrapper name='dummy' encoding='utf-8'>" % modname)
+        raw.name = b"dummy"
+        self.assertEqual(repr(t),
+                         "<%s.TextIOWrapper name=b'dummy' encoding='utf-8'>" % modname)
 
     def test_line_buffering(self):
         r = self.BytesIO()