Made test_file pass.  This meant adding support for read(-1) and read()
to even the most basic file object (I also added readall() which may
be a better API).  Also, not all the tests requiring specific failure
modes could be saved.  And there were the usual str/bytes issues.
I made sure test_io.py still passes (io.py is now most thoroughly
tested by combining test_file.py and test_io.py).
diff --git a/Lib/io.py b/Lib/io.py
index 4c9ddbb..a7cdd1f 100644
--- a/Lib/io.py
+++ b/Lib/io.py
@@ -101,7 +101,9 @@
     updating = "+" in modes
     text = "t" in modes
     binary = "b" in modes
-    if "U" in modes and not (reading or writing or appending):
+    if "U" in modes:
+        if writing or appending:
+            raise ValueError("can't use U and writing mode at once")
         reading = True
     if text and binary:
         raise ValueError("can't have text and binary mode at once")
@@ -296,7 +298,7 @@
         """
         return False
 
-    ### Readline ###
+    ### Readline[s] and writelines ###
 
     def readline(self, limit: int = -1) -> bytes:
         """For backwards compatibility, a (slowish) readline()."""
@@ -324,6 +326,31 @@
                 break
         return res
 
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        line = self.readline()
+        if not line:
+            raise StopIteration
+        return line
+
+    def readlines(self, hint=None):
+        if hint is None:
+            return list(self)
+        n = 0
+        lines = []
+        for line in self:
+            lines.append(line)
+            n += len(line)
+            if n >= hint:
+                break
+        return lines
+
+    def writelines(self, lines):
+        for line in lines:
+            self.write(line)
+
 
 class RawIOBase(IOBase):
 
@@ -340,17 +367,31 @@
     recursion in case a subclass doesn't implement either.)
     """
 
-    def read(self, n: int) -> bytes:
+    def read(self, n: int = -1) -> bytes:
         """read(n: int) -> bytes.  Read and return up to n bytes.
 
         Returns an empty bytes array on EOF, or None if the object is
         set not to block and has no data to read.
         """
+        if n is None:
+            n = -1
+        if n < 0:
+            return self.readall()
         b = bytes(n.__index__())
         n = self.readinto(b)
         del b[n:]
         return b
 
+    def readall(self):
+        """readall() -> bytes.  Read until EOF, using multiple read() call."""
+        res = bytes()
+        while True:
+            data = self.read(DEFAULT_BUFFER_SIZE)
+            if not data:
+                break
+            res += data
+        return res
+
     def readinto(self, b: bytes) -> int:
         """readinto(b: bytes) -> int.  Read up to len(b) bytes into b.
 
@@ -494,7 +535,13 @@
         # XXX This ought to work with anything that supports the buffer API
         data = self.read(len(b))
         n = len(data)
-        b[:n] = data
+        try:
+            b[:n] = data
+        except TypeError as err:
+            import array
+            if not isinstance(b, array.array):
+                raise err
+            b[:n] = array.array('b', data)
         return n
 
     def write(self, b: bytes) -> int:
@@ -530,6 +577,8 @@
         return self.raw.tell()
 
     def truncate(self, pos=None):
+        if pos is None:
+            pos = self.tell()
         return self.raw.truncate(pos)
 
     ### Flush and close ###
@@ -731,6 +780,9 @@
 
     def write(self, b):
         if not isinstance(b, bytes):
+            if hasattr(b, "__index__"):
+                raise TypeError("Can't write object of type %s" %
+                                type(b).__name__)
             b = bytes(b)
         # XXX we can implement some more tricks to try and avoid partial writes
         if len(self._write_buf) > self.buffer_size:
@@ -924,42 +976,11 @@
         """
         self._unsupported("readline")
 
-    def __iter__(self) -> "TextIOBase":  # That's a forward reference
-        """__iter__() -> Iterator.  Return line iterator (actually just self).
-        """
-        return self
-
-    def __next__(self) -> str:
-        """Same as readline() except raises StopIteration on immediate EOF."""
-        line = self.readline()
-        if not line:
-            raise StopIteration
-        return line
-
     @property
     def encoding(self):
         """Subclasses should override."""
         return None
 
-    # The following are provided for backwards compatibility
-
-    def readlines(self, hint=None):
-        if hint is None:
-            return list(self)
-        n = 0
-        lines = []
-        while not lines or n < hint:
-            line = self.readline()
-            if not line:
-                break
-            lines.append(line)
-            n += len(line)
-        return lines
-
-    def writelines(self, lines):
-        for line in lines:
-            self.write(line)
-
 
 class TextIOWrapper(TextIOBase):