| 150 | |
| 151 | |
| 152 | class OutputStream(object): |
| 153 | def __init__(self, formatter, filename=None): |
| 154 | """Helper class for writing query output. |
| 155 | |
| 156 | User should invoke the `write(data)` method of this object. |
| 157 | `data` is a list of lists. |
| 158 | """ |
| 159 | self.formatter = formatter |
| 160 | self.filename = filename |
| 161 | |
| 162 | def write(self, data): |
| 163 | formatted_data = self.formatter.format(data) |
| 164 | if self.filename is not None: |
| 165 | try: |
| 166 | with open(self.filename, 'ab') as out_file: |
| 167 | # Note that instances of this class do not persist, so it's fine to |
| 168 | # close the we close the file handle after each write. |
| 169 | # The file is opened in binary mode. Python 2 returns Unicode bytes |
| 170 | # that can be written directly. Python 3 returns a string, which |
| 171 | # we need to encode before writing. |
| 172 | # TODO: Reexamine the contract of the format() function and see if |
| 173 | # we can remove this. |
| 174 | if sys.version_info.major == 2 and isinstance(formatted_data, str): |
| 175 | out_file.write(formatted_data) |
| 176 | else: |
| 177 | out_file.write(formatted_data.encode('utf-8')) |
| 178 | out_file.write(b'\n') |
| 179 | except IOError as err: |
| 180 | file_err_msg = "Error opening file %s: %s" % (self.filename, str(err)) |
| 181 | print('{0} (falling back to stderr)'.format(file_err_msg), file=sys.stderr) |
| 182 | print(formatted_data, file=sys.stderr) |
| 183 | else: |
| 184 | # If filename is None, then just print to stdout |
| 185 | print(formatted_data) |
| 186 | |
| 187 | def flush(self): |
| 188 | # When outputing to a file, the file is currently closed with each write, |
| 189 | # so the flush doesn't need to do anything. |
| 190 | if self.filename is None: |
| 191 | sys.stdout.flush() |
| 192 | |
| 193 | |
| 194 | class OverwritingStdErrOutputStream(object): |
no outgoing calls
no test coverage detected