diff options
author | Guido van Rossum <guido@python.org> | 2007-07-10 06:54:34 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2007-07-10 06:54:34 (GMT) |
commit | 7165cb1a485b1b5574785eac6e2edc8787e43c38 (patch) | |
tree | 1b8edb82abcc8ef143923a43366b6a90842b5692 /Lib/io.py | |
parent | e8432ac42f9030bd75de03a07fd9059006292b7a (diff) | |
download | cpython-7165cb1a485b1b5574785eac6e2edc8787e43c38.zip cpython-7165cb1a485b1b5574785eac6e2edc8787e43c38.tar.gz cpython-7165cb1a485b1b5574785eac6e2edc8787e43c38.tar.bz2 |
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).
Diffstat (limited to 'Lib/io.py')
-rw-r--r-- | Lib/io.py | 91 |
1 files changed, 56 insertions, 35 deletions
@@ -101,7 +101,9 @@ def open(file, mode="r", buffering=None, encoding=None, newline=None): 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 @@ class IOBase: """ return False - ### Readline ### + ### Readline[s] and writelines ### def readline(self, limit: int = -1) -> bytes: """For backwards compatibility, a (slowish) readline().""" @@ -324,6 +326,31 @@ class IOBase: 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 @@ class RawIOBase(IOBase): 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 @@ class BufferedIOBase(IOBase): # 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 @@ class _BufferedIOMixin(BufferedIOBase): 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 @@ class BufferedWriter(_BufferedIOMixin): 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 @@ class TextIOBase(IOBase): """ 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): |