|
99 | 99 | - Skipper Seabold, refactoring, cleanups, pure python addition |
100 | 100 | """ |
101 | 101 | from __future__ import print_function |
| 102 | +from __future__ import unicode_literals |
102 | 103 |
|
103 | 104 | #----------------------------------------------------------------------------- |
104 | 105 | # Imports |
@@ -245,12 +246,35 @@ def block_parser(part, rgxin, rgxout, fmtin, fmtout): |
245 | 246 | return block |
246 | 247 |
|
247 | 248 |
|
| 249 | +class DecodingStringIO(StringIO, object): |
| 250 | + def __init__(self,buf='',encodings=('utf8',), *args, **kwds): |
| 251 | + super(DecodingStringIO, self).__init__(buf, *args, **kwds) |
| 252 | + self.set_encodings(encodings) |
| 253 | + |
| 254 | + def set_encodings(self, encodings): |
| 255 | + self.encodings = encodings |
| 256 | + |
| 257 | + def write(self,data): |
| 258 | + #py 3 compat here |
| 259 | + if isinstance(data,unicode): |
| 260 | + return super(DecodingStringIO, self).write(data) |
| 261 | + else: |
| 262 | + for enc in self.encodings: |
| 263 | + try: |
| 264 | + data = data.decode(enc) |
| 265 | + return super(DecodingStringIO, self).write(data) |
| 266 | + except : |
| 267 | + pass |
| 268 | + # default to brute utf8 if no encoding succeded |
| 269 | + return super(DecodingStringIO, self).write(data.decode('utf8', 'replace')) |
| 270 | + |
| 271 | + |
248 | 272 | class EmbeddedSphinxShell(object): |
249 | 273 | """An embedded IPython instance to run inside Sphinx""" |
250 | 274 |
|
251 | 275 | def __init__(self, exec_lines=None,state=None): |
252 | 276 |
|
253 | | - self.cout = StringIO() |
| 277 | + self.cout = DecodingStringIO(u'') |
254 | 278 |
|
255 | 279 | if exec_lines is None: |
256 | 280 | exec_lines = [] |
@@ -323,14 +347,6 @@ def process_input_line(self, line, store_history=True): |
323 | 347 | self.IP.run_cell(source_raw, store_history=store_history) |
324 | 348 | finally: |
325 | 349 | sys.stdout = stdout |
326 | | - buflist = self.cout.buflist |
327 | | - for i in range(len(buflist)): |
328 | | - try: |
329 | | - # print(buflist[i]) |
330 | | - if not isinstance(buflist[i], unicode): |
331 | | - buflist[i] = buflist[i].decode('utf8','replace') |
332 | | - except: |
333 | | - pass |
334 | 350 |
|
335 | 351 | def process_image(self, decorator): |
336 | 352 | """ |
@@ -380,11 +396,12 @@ def process_input(self, data, input_prompt, lineno): |
380 | 396 | is_savefig = decorator is not None and \ |
381 | 397 | decorator.startswith('@savefig') |
382 | 398 |
|
383 | | - # #>>> required for cython magic to work |
384 | | - # def _remove_first_space_if_any(line): |
385 | | - # return line[1:] if line.startswith(' ') else line |
| 399 | + # set the encodings to be used by DecodingStringIO |
| 400 | + # to convert the execution output into unicode if |
| 401 | + # needed. this attrib is set by IpythonDirective.run() |
| 402 | + # based on the specified block options, defaulting to ['ut |
| 403 | + self.cout.set_encodings(self.output_encoding) |
386 | 404 |
|
387 | | - # input_lines = lmap(_remove_first_space_if_any, input.split('\n')) |
388 | 405 | input_lines = input.split('\n') |
389 | 406 |
|
390 | 407 | if len(input_lines) > 1: |
@@ -716,7 +733,8 @@ class IPythonDirective(Directive): |
716 | 733 | 'verbatim' : directives.flag, |
717 | 734 | 'doctest' : directives.flag, |
718 | 735 | 'okexcept': directives.flag, |
719 | | - 'okwarning': directives.flag |
| 736 | + 'okwarning': directives.flag, |
| 737 | + 'output_encoding': directives.unchanged_required |
720 | 738 | } |
721 | 739 |
|
722 | 740 | shell = None |
@@ -817,6 +835,8 @@ def run(self): |
817 | 835 | self.shell.is_okexcept = 'okexcept' in options |
818 | 836 | self.shell.is_okwarning = 'okwarning' in options |
819 | 837 |
|
| 838 | + self.shell.output_encoding = [options.get('output_encoding', 'utf8')] |
| 839 | + |
820 | 840 | # handle pure python code |
821 | 841 | if 'python' in self.arguments: |
822 | 842 | content = self.content |
|
0 commit comments