]> granicus.if.org Git - python/commitdiff
Issue #5761: Add the name of the underlying file to the repr() of various IO objects.
authorAntoine Pitrou <solipsis@pitrou.net>
Sat, 23 May 2009 19:04:03 +0000 (19:04 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Sat, 23 May 2009 19:04:03 +0000 (19:04 +0000)
Lib/_pyio.py
Lib/test/test_fileio.py
Lib/test/test_io.py
Misc/NEWS
Modules/_io/bufferedio.c
Modules/_io/fileio.c
Modules/_io/textio.c

index c9a7c5e3153fcf539804c5745c6ba51f32dc1bd2..c1cdf439e1282a552a9ed2c9c478ecebd0c3d70a 100644 (file)
@@ -736,6 +736,15 @@ class _BufferedIOMixin(BufferedIOBase):
     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 @@ class TextIOWrapper(TextIOBase):
     #   - "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):
index 9188e70e30af5900b4b00747d706b5d2e2475634..657401e8edd08617f65a54d664dd165606db6631 100644 (file)
@@ -70,9 +70,13 @@ class AutoFileTests(unittest.TestCase):
         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
index 08e0f1396f4edacdb4360ccc40249e9ef1965607..1337b7c096b5dbd4731eb86d5db3a095a3d844e2 100644 (file)
@@ -618,6 +618,16 @@ class CommonBufferedTests:
             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 @@ class TextIOWrapperTest(unittest.TestCase):
         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()
index d5345789463705308d57a651c43d0014b7e758b2..dc9fe457064e241a1d680e840b3c7410067d8a9a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -32,6 +32,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #5761: Add the name of the underlying file to the repr() of various
+  IO objects.
+
 - Issue #5259: smtplib plain auth login no longer gives a traceback.  Fix
   by Musashi Tamura, tests by Marcin Bachry.
 
index 2c652078ee671ad94d6538feab0b9681687a6b3c..034fe51f3a5f310d43594a038fbccda4e569bb79 100644 (file)
@@ -1123,6 +1123,27 @@ Buffered_iternext(BufferedObject *self)
     return line;
 }
 
+static PyObject *
+Buffered_repr(BufferedObject *self)
+{
+    PyObject *nameobj, *res;
+
+    nameobj = PyObject_GetAttrString((PyObject *) self, "name");
+    if (nameobj == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_AttributeError))
+            PyErr_Clear();
+        else
+            return NULL;
+        res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
+    }
+    else {
+        res = PyUnicode_FromFormat("<%s name=%R>",
+                                   Py_TYPE(self)->tp_name, nameobj);
+        Py_DECREF(nameobj);
+    }
+    return res;
+}
+
 /*
  * class BufferedReader
  */
@@ -1472,7 +1493,7 @@ PyTypeObject PyBufferedReader_Type = {
     0,                          /*tp_getattr*/
     0,                          /*tp_setattr*/
     0,                          /*tp_compare */
-    0,                          /*tp_repr*/
+    (reprfunc)Buffered_repr,    /*tp_repr*/
     0,                          /*tp_as_number*/
     0,                          /*tp_as_sequence*/
     0,                          /*tp_as_mapping*/
@@ -1828,7 +1849,7 @@ PyTypeObject PyBufferedWriter_Type = {
     0,                          /*tp_getattr*/
     0,                          /*tp_setattr*/
     0,                          /*tp_compare */
-    0,                          /*tp_repr*/
+    (reprfunc)Buffered_repr,    /*tp_repr*/
     0,                          /*tp_as_number*/
     0,                          /*tp_as_sequence*/
     0,                          /*tp_as_mapping*/
@@ -2219,7 +2240,7 @@ PyTypeObject PyBufferedRandom_Type = {
     0,                          /*tp_getattr*/
     0,                          /*tp_setattr*/
     0,                          /*tp_compare */
-    0,                          /*tp_repr*/
+    (reprfunc)Buffered_repr,    /*tp_repr*/
     0,                          /*tp_as_number*/
     0,                          /*tp_as_sequence*/
     0,                          /*tp_as_mapping*/
index 9400c91ab16abba6fa36f43ecd4bf4430b78a40f..d063fbf2b996b15121b83af65a5bd8b98f95fe4a 100644 (file)
@@ -846,11 +846,26 @@ mode_string(PyFileIOObject *self)
 static PyObject *
 fileio_repr(PyFileIOObject *self)
 {
+       PyObject *nameobj, *res;
+
         if (self->fd < 0)
-               return PyUnicode_FromFormat("io.FileIO(-1)");
+               return PyUnicode_FromFormat("<_io.FileIO [closed]>");
 
-       return PyUnicode_FromFormat("io.FileIO(%d, '%s')",
-                                  self->fd, mode_string(self));
+       nameobj = PyObject_GetAttrString((PyObject *) self, "name");
+       if (nameobj == NULL) {
+               if (PyErr_ExceptionMatches(PyExc_AttributeError))
+                       PyErr_Clear();
+               else
+                       return NULL;
+               res = PyUnicode_FromFormat("<_io.FileIO fd=%d mode='%s'>",
+                                          self->fd, mode_string(self));
+       }
+       else {
+               res = PyUnicode_FromFormat("<_io.FileIO name=%R mode='%s'>",
+                                          nameobj, mode_string(self));
+               Py_DECREF(nameobj);
+       }
+       return res;
 }
 
 static PyObject *
index b78256e2ed69053e27bf8601f93a2ac773ba7273..c8d28334c1456c7cfdc6f0fa328585bb03c4e49d 100644 (file)
@@ -2308,8 +2308,25 @@ TextIOWrapper_truncate(PyTextIOWrapperObject *self, PyObject *args)
 static PyObject *
 TextIOWrapper_repr(PyTextIOWrapperObject *self)
 {
-  CHECK_INITIALIZED(self);
-  return PyUnicode_FromFormat("<TextIOWrapper encoding=%S>", self->encoding);
+    PyObject *nameobj, *res;
+
+    CHECK_INITIALIZED(self);
+
+    nameobj = PyObject_GetAttrString((PyObject *) self, "name");
+    if (nameobj == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_AttributeError))
+            PyErr_Clear();
+        else
+            return NULL;
+        res = PyUnicode_FromFormat("<_io.TextIOWrapper encoding=%R>",
+                                   self->encoding);
+    }
+    else {
+        res = PyUnicode_FromFormat("<_io.TextIOWrapper name=%R encoding=%R>",
+                                   nameobj, self->encoding);
+        Py_DECREF(nameobj);
+    }
+    return res;
 }