From: Ben Keene <seraphire@xxxxxxxxx> This is a preparatory commit that does not change current behavior. It adds a new class Py23File. Following the Python recommendation of keeping text as unicode internally and only converting to and from bytes on input and output, this class provides an interface for the methods used for reading and writing files and file like streams. A new class was implemented to avoid requiring additional dependencies. Create a class that wraps the input and output functions used by the git-p4.py code for reading and writing to standard file handles. The methods of this class should take a Unicode string for writing and return unicode strings in reads. This class should be a drop-in for existing file like streams The following methods should be coded for supporting existing read/write calls: * write - this should write a Unicode string to the underlying stream * read - this should read from the underlying stream and cast the bytes as a unicode string * readline - this should read one line of text from the underlying stream and cast it as a unicode string * readline - this should read a number of lines, optionally hinted, and cast each line as a unicode string The expression "cast as a unicode string" is used because the code should use the as_bytes() and as_string() functions instead of cohercing the data to actual unicode strings or bytes. This allows Python 2 code to continue to use the internal "str" data type instead of converting the data back and forth to actual unicode strings. This retains current Python 2 support while Python 3 support may be incomplete. Signed-off-by: Ben Keene <seraphire@xxxxxxxxx> --- git-p4.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/git-p4.py b/git-p4.py index 1838045078..03829f796d 100755 --- a/git-p4.py +++ b/git-p4.py @@ -4187,6 +4187,72 @@ def run(self, args): print("%s <= %s (%s)" % (branch, ",".join(settings["depot-paths"]), settings["change"])) return True +class Py23File(): + """ Python2/3 Unicode File Wrapper + """ + + stream_handle = None + verbose = False + debug_handle = None + + def __init__(self, stream_handle, verbose = False): + """ Create a Python3 compliant Unicode to Byte String + Windows compatible wrapper + + stream_handle = the underlying file-like handle + verbose = Boolean if content should be echoed + """ + self.stream_handle = stream_handle + self.verbose = verbose + + def write(self, utf8string): + """ Writes the utf8 encoded string to the underlying + file stream + """ + self.stream_handle.write(as_bytes(utf8string)) + if self.verbose: + sys.stderr.write("Stream Output: %s" % utf8string) + sys.stderr.flush() + + def read(self, size = None): + """ Reads int charcters from the underlying stream + and converts it to utf8. + + Be aware, the size value is for reading the underlying + bytes so the value may be incorrect. Usage of the size + value is discouraged. + """ + if size == None: + return as_string(self.stream_handle.read()) + else: + return as_string(self.stream_handle.read(size)) + + def readline(self): + """ Reads a line from the underlying byte stream + and converts it to utf8 + """ + return as_string(self.stream_handle.readline()) + + def readlines(self, sizeHint = None): + """ Returns a list containing lines from the file converted to unicode. + + sizehint - Optional. If the optional sizehint argument is + present, instead of reading up to EOF, whole lines totalling + approximately sizehint bytes are read. + """ + lines = self.stream_handle.readlines(sizeHint) + for i in range(0, len(lines)): + lines[i] = as_string(lines[i]) + return lines + + def close(self): + """ Closes the underlying byte stream """ + self.stream_handle.close() + + def flush(self): + """ Flushes the underlying byte stream """ + self.stream_handle.flush() + class HelpFormatter(optparse.IndentedHelpFormatter): def __init__(self): optparse.IndentedHelpFormatter.__init__(self) -- gitgitgadget