Skip to content

Commit

Permalink
making sure output capturing is only enabled when we have a running p…
Browse files Browse the repository at this point in the history
…rogress bar
  • Loading branch information
wolph committed Jul 28, 2017
1 parent bbba9f4 commit 4eb44b2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 11 deletions.
8 changes: 8 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ environment variable, on Linux/Unix systems this can be done through:
# WRAP_STDERR=true python your_script.py
If you need to flush manually while wrapping, you can do so using:

.. code:: python
import progressbar
progressbar.streams.flush()
In most cases the following will work as well, as long as you initialize the
`StreamHandler` after the wrapping has taken place.

Expand Down
3 changes: 2 additions & 1 deletion progressbar/bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def start(self, *args, **kwargs):
self.stdout = utils.streams.stdout
self.stderr = utils.streams.stderr

utils.streams.start_capturing()
DefaultFdMixin.start(self, *args, **kwargs)

def update(self, value=None):
Expand All @@ -132,7 +133,7 @@ def update(self, value=None):

def finish(self, end='\n'):
DefaultFdMixin.finish(self, end=end)
utils.streams.flush()
utils.streams.stop_capturing()
if self.redirect_stdout:
utils.streams.unwrap_stdout()

Expand Down
54 changes: 44 additions & 10 deletions progressbar/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@
epoch = datetime.datetime(year=1970, month=1, day=1)


class WrappingIO:

def __init__(self, target, capturing=False):
self.buffer = six.StringIO()
self.target = target
self.capturing = capturing

def write(self, value):
if self.capturing:
self.buffer.write(value)
else:
self.target.write(value)

def flush(self):
self.target.write(self.buffer.getvalue())
self.buffer.seek(0)
self.buffer.truncate(0)


class StreamWrapper(object):
'''Wrap stdout and stderr globally'''

Expand All @@ -23,13 +42,32 @@ def __init__(self):
self.wrapped_stdout = 0
self.wrapped_stderr = 0
self.wrapped_excepthook = 0
self.capturing = 0

if os.environ.get('WRAP_STDOUT'): # pragma: no cover
self.wrap_stdout()

if os.environ.get('WRAP_STDERR'): # pragma: no cover
self.wrap_stderr()

def start_capturing(self):
self.capturing += 1
self.update_capturing()

def stop_capturing(self):
self.capturing -= 1
self.update_capturing()

def update_capturing(self): # pragma: no cover
if isinstance(self.stdout, WrappingIO):
self.stdout.capturing = self.capturing > 0

if isinstance(self.stderr, WrappingIO):
self.stderr.capturing = self.capturing > 0

if self.capturing <= 0:
self.flush()

def wrap(self, stdout=False, stderr=False):
if stdout:
self.wrap_stdout()
Expand All @@ -41,7 +79,7 @@ def wrap_stdout(self):
self.wrap_excepthook()

if not self.wrapped_stdout:
self.stdout = sys.stdout = six.StringIO()
self.stdout = sys.stdout = WrappingIO(self.original_stdout)
self.wrapped_stdout += 1

return sys.stdout
Expand All @@ -50,7 +88,7 @@ def wrap_stderr(self):
self.wrap_excepthook()

if not self.wrapped_stderr:
self.stderr = sys.stderr = six.StringIO()
self.stderr = sys.stderr = WrappingIO(self.original_stderr)
self.wrapped_stderr += 1

return sys.stderr
Expand Down Expand Up @@ -88,22 +126,18 @@ def unwrap_stderr(self):
self.wrapped_stderr = 0

def flush(self):
if self.wrapped_stdout:
if self.wrapped_stdout: # pragma: no branch
try:
self.original_stdout.write(self.stdout.getvalue())
self.stdout.seek(0)
self.stdout.truncate(0)
self.stdout.flush()
except (io.UnsupportedOperation,
AttributeError): # pragma: no cover
self.wrapped_stdout = False
logger.warn('Disabling stdout redirection, %r is not seekable',
sys.stdout)

if self.wrapped_stderr:
if self.wrapped_stderr: # pragma: no branch
try:
self.original_stderr.write(self.stderr.getvalue())
self.stderr.seek(0)
self.stderr.truncate(0)
self.stderr.flush()
except (io.UnsupportedOperation,
AttributeError): # pragma: no cover
self.wrapped_stderr = False
Expand Down

0 comments on commit 4eb44b2

Please sign in to comment.