Commit d6ffbaa57eec3203e4fd358e6b71a43190dc5b06
1 parent
6956fce2
unittest: fix bug with OutputCapture and old loggers
Showing
1 changed file
with
20 additions
and
0 deletions
tests/test_utils/output_capture.py
| ... | ... | @@ -2,13 +2,20 @@ |
| 2 | 2 | |
| 3 | 3 | from __future__ import print_function |
| 4 | 4 | import sys |
| 5 | +import logging | |
| 5 | 6 | |
| 6 | 7 | |
| 7 | 8 | # python 2/3 version conflict: |
| 8 | 9 | if sys.version_info.major <= 2: |
| 9 | 10 | from StringIO import StringIO |
| 11 | + # reload is a builtin | |
| 10 | 12 | else: |
| 11 | 13 | from io import StringIO |
| 14 | + if sys.version_info.minor < 4: | |
| 15 | + from imp import reload | |
| 16 | + else: | |
| 17 | + from importlib import reload | |
| 18 | + | |
| 12 | 19 | |
| 13 | 20 | class OutputCapture: |
| 14 | 21 | """ context manager that captures stdout |
| ... | ... | @@ -24,6 +31,10 @@ class OutputCapture: |
| 24 | 31 | # ...or test all output in one go |
| 25 | 32 | some_test(capturer.get_data()) |
| 26 | 33 | |
| 34 | + In order to solve issues with old logger instances still remembering closed | |
| 35 | + StringIO instances as "their" stdout, logging is shutdown and restarted | |
| 36 | + upon entering this Context Manager. This means that you may have to reload | |
| 37 | + your module, as well. | |
| 27 | 38 | """ |
| 28 | 39 | |
| 29 | 40 | def __init__(self): |
| ... | ... | @@ -32,6 +43,11 @@ class OutputCapture: |
| 32 | 43 | self.data = None |
| 33 | 44 | |
| 34 | 45 | def __enter__(self): |
| 46 | + # Avoid problems with old logger instances that still remember an old | |
| 47 | + # closed StringIO as their sys.stdout | |
| 48 | + logging.shutdown() | |
| 49 | + reload(logging) | |
| 50 | + | |
| 35 | 51 | # replace sys.stdout with own buffer. |
| 36 | 52 | self.orig_stdout = sys.stdout |
| 37 | 53 | sys.stdout = self.buffer |
| ... | ... | @@ -61,3 +77,7 @@ class OutputCapture: |
| 61 | 77 | def __iter__(self): |
| 62 | 78 | for line in self.get_data().splitlines(): |
| 63 | 79 | yield line |
| 80 | + | |
| 81 | + def reload_module(self, mod): | |
| 82 | + """ Wrapper around reload function for different python versions """ | |
| 83 | + return reload(mod) | ... | ... |