diff options
author | Chris Liechti <cliechti@gmx.net> | 2015-08-04 03:00:52 +0200 |
---|---|---|
committer | Chris Liechti <cliechti@gmx.net> | 2015-08-04 03:00:52 +0200 |
commit | 70b892395deeaf3dc4967bd808101e61e4e1a53f (patch) | |
tree | bea1f899a276dc72bece03e1c0da7167c69aa0c9 | |
parent | 80e2ae2349b2ec6cc8125d6a1378297d0f4f3720 (diff) | |
download | pyserial-git-70b892395deeaf3dc4967bd808101e61e4e1a53f.tar.gz |
remove FileLike class, add read_until, remove compatibility hacks
-rw-r--r-- | serial/serialutil.py | 206 |
1 files changed, 33 insertions, 173 deletions
diff --git a/serial/serialutil.py b/serial/serialutil.py index 165f3fd..5ed354f 100644 --- a/serial/serialutil.py +++ b/serial/serialutil.py @@ -5,46 +5,6 @@ # (C) 2001-2015 Chris Liechti <cliechti@gmx.net> # this is distributed under a free software license, see license.txt -# compatibility for older Python < 2.6 -try: - bytes - bytearray -except (NameError, AttributeError): - # Python older than 2.6 do not have these types. Like for Python 2.6 they - # should behave like str. For Python older than 3.0 we want to work with - # strings anyway, only later versions have a true bytes type. - bytes = str - # bytearray is a mutable type that is easily turned into an instance of - # bytes - class bytearray(list): - # for bytes(bytearray()) usage - def __str__(self): return ''.join(self) - def __repr__(self): return 'bytearray(%r)' % ''.join(self) - # append automatically converts integers to characters - def append(self, item): - if isinstance(item, str): - list.append(self, item) - else: - list.append(self, chr(item)) - # += - def __iadd__(self, other): - for byte in other: - self.append(byte) - return self - - def __getslice__(self, i, j): - return bytearray(list.__getslice__(self, i, j)) - - def __getitem__(self, item): - if isinstance(item, slice): - return bytearray(list.__getitem__(self, item)) - else: - return ord(list.__getitem__(self, item)) - - def __eq__(self, other): - if isinstance(other, basestring): - other = bytearray(other) - return list.__eq__(self, other) # ``memoryview`` was introduced in Python 2.7 and ``bytes(some_memoryview)`` # isn't returning the contents (very unfortunate). Therefore we need special @@ -56,7 +16,7 @@ try: except (NameError, AttributeError): # implementation does not matter as we do not realy use it. # it just must not inherit from something else we might care for. - class memoryview: + class memoryview(object): pass @@ -109,122 +69,6 @@ writeTimeoutError = SerialTimeoutException('Write timeout') portNotOpenError = SerialException('Attempting to use a port that is not open') -class FileLike(object): - """\ - An abstract file like class. - - This class implements readline and readlines based on read and - writelines based on write. - This class is used to provide the above functions for to Serial - port objects. - - Note that when the serial port was opened with _NO_ timeout that - readline blocks until it sees a newline (or the specified size is - reached) and that readlines would never return and therefore - refuses to work (it raises an exception in this case)! - """ - - def __init__(self): - self.closed = True - - def close(self): - self.closed = True - - # so that ports are closed when objects are discarded - def __del__(self): - """Destructor. Calls close().""" - # The try/except block is in case this is called at program - # exit time, when it's possible that globals have already been - # deleted, and then the close() call might fail. Since - # there's nothing we can do about such failures and they annoy - # the end users, we suppress the traceback. - try: - self.close() - except: - pass - - def writelines(self, sequence): - for line in sequence: - self.write(line) - - def flush(self): - """flush of file like objects""" - pass - - # iterator for e.g. "for line in Serial(0): ..." usage - def next(self): - line = self.readline() - if not line: raise StopIteration - return line - - def __iter__(self): - return self - - def readline(self, size=None, eol=LF): - """\ - Read a line which is terminated with end-of-line (eol) character - ('\n' by default) or until timeout. - """ - leneol = len(eol) - line = bytearray() - while True: - c = self.read(1) - if c: - line += c - if line[-leneol:] == eol: - break - if size is not None and len(line) >= size: - break - else: - break - return bytes(line) - - def readlines(self, sizehint=None, eol=LF): - """\ - Read a list of lines, until timeout. - sizehint is ignored. - """ - if self.timeout is None: - raise ValueError("Serial port MUST have enabled timeout for this function!") - leneol = len(eol) - lines = [] - while True: - line = self.readline(eol=eol) - if line: - lines.append(line) - if line[-leneol:] != eol: # was the line received with a timeout? - break - else: - break - return lines - - def xreadlines(self, sizehint=None): - """\ - Read lines, implemented as generator. It will raise StopIteration on - timeout (empty read). sizehint is ignored. - """ - while True: - line = self.readline() - if not line: break - yield line - - # other functions of file-likes - not used by pySerial - - #~ readinto(b) - - def seek(self, pos, whence=0): - raise IOError("file is not seekable") - - def tell(self): - raise IOError("file is not seekable") - - def truncate(self, n=None): - raise IOError("file is not seekable") - - def isatty(self): - return False - - class SerialBase(object): """\ Serial port base class. Provides __init__ function and properties to @@ -296,22 +140,6 @@ class SerialBase(object): """Check if the port is opened.""" return self._isOpen - # - - - - - - - - - - - - - - - - - - - - - - - - - - # TODO: these are not really needed as the is the BAUDRATES etc. attribute... - # maybe i remove them before the final release... - - def getSupportedBaudrates(self): - return [(str(b), b) for b in self.BAUDRATES] - - def getSupportedByteSizes(self): - return [(str(b), b) for b in self.BYTESIZES] - - def getSupportedStopbits(self): - return [(str(b), b) for b in self.STOPBITS] - - def getSupportedParities(self): - return [(PARITY_NAMES[b], b) for b in self.PARITIES] # - - - - - - - - - - - - - - - - - - - - - - - - @@ -554,6 +382,38 @@ class SerialBase(object): b[:n] = array.array('b', data) return n + # - - - - - - - - - - - - - - - - - - - - - - - - + # additional functionality + + def read_until(self, terminator=LF, size=None): + """\ + Read until a termination sequence is found ('\n' by default), the size + is exceeded or until timeout occurs. + """ + lenterm = len(terminator) + line = bytearray() + while True: + c = self.read(1) + if c: + line += c + if line[-lenterm:] == terminator: + break + if size is not None and len(line) >= size: + break + else: + break + return bytes(line) + + + def iread_until(self, *args, **kwargs): + """\ + Read lines, implemented as generator. It will raise StopIteration on + timeout (empty read). + """ + while True: + line = self.read_until(*args, **kwargs) + if not line: break + yield line if __name__ == '__main__': import sys |