From b15568452a6e25f054a49e6562ea17e105ca2c91 Mon Sep 17 00:00:00 2001 From: Chris Meyers Date: Sun, 17 Feb 2019 19:06:55 -0700 Subject: [PATCH] added docstrings. --- pleasehold/core.py | 72 ++++++++++++++++++++++++++++++++++++++++ pleasehold/stream_tee.py | 21 ++++++++---- pleasehold/terminal.py | 5 +++ 3 files changed, 91 insertions(+), 7 deletions(-) diff --git a/pleasehold/core.py b/pleasehold/core.py index 8fdf9e1..5327d62 100644 --- a/pleasehold/core.py +++ b/pleasehold/core.py @@ -7,6 +7,18 @@ class PleaseHold(): + '''Manages the loading thread and handles pushing notifications. + + This class supports the use of a context manager: + with pleasehold.hold() as holding: + ... + + Args: + begin_msg (str, optional): The message to the left of the loading bar + end_msg (str, optional): The message to the right of the loading bar + delay (float, optional): The delay between printing loading symbols + symbol (str, optional): The symbol to be used in the loading bar + ''' def __init__(self, begin_msg='begin', end_msg='end', delay=1.0, symbol='.'): self._begin_msg = begin_msg self._end_msg = end_msg @@ -19,14 +31,21 @@ def __init__(self, begin_msg='begin', end_msg='end', delay=1.0, symbol='.'): self._loading_event = threading.Event() def __enter__(self): + '''Starts the loading thread if this class is initialized via a context + manager + ''' self.start() return self def __exit__(self, type, value, traceback): + '''Joins the loading thread if this class is initialized via a context + manager + ''' self.end() @property def begin_msg(self): + '''str: gets or sets the message to the left of the loading bar''' return self._begin_msg @begin_msg.setter @@ -35,6 +54,7 @@ def begin_msg(self, value): @property def end_msg(self): + '''str: gets or sets the message to the right of the loading bar''' return self._end_msg @end_msg.setter @@ -43,6 +63,7 @@ def end_msg(self, value): @property def delay(self): + '''float: gets or sets the delay between printing loading symbols''' return self._delay @delay.setter @@ -51,6 +72,7 @@ def delay(self, value): @property def symbol(self): + '''str: gets or sets the symbol that's used in the loading bar''' return self._symbol @symbol.setter @@ -59,9 +81,17 @@ def symbol(self, value): @property def loading_event(self): + '''str: gets the threading.Event() instance used to interact with the + loading thread + ''' return self._loading_event def start(self, msg=None): + '''Starts the loading thread and prints the begin message. + + Args: + msg (str, optional): Used to override self._begin_msg + ''' self._begin_msg = msg if msg is not None else self._begin_msg print(f'{self._begin_msg}{self._loading_ticks}', end='', flush=True) @@ -77,6 +107,11 @@ def start(self, msg=None): self._loading_thread.start() def end(self, msg=None): + '''Joins the loading thread and prints the end message. + + Args: + msg (str, optional): Used to override self._end_msg + ''' self._end_msg = msg if msg is not None else self._end_msg self._loading_event.clear() @@ -85,6 +120,11 @@ def end(self, msg=None): print(self._end_msg, flush=True) def push(self, msg): + '''Pushes a message above the loading bar. + + Args: + msg (str): The message to push + ''' with self._loading_lock: term.clear_line() term.move_line_up() @@ -101,6 +141,15 @@ def _loading(self): class Transfer(): + '''Pauses the loading thread to allow for user input + + This class supports the use of a context manager: + with pleasehold.transfer(holding) as t: + ... + + Args: + holding (PleaseHold): The instance of PleaseHold that should be paused + ''' def __init__(self, holding): self._holding = holding self._output_stream = io.StringIO() @@ -108,12 +157,18 @@ def __init__(self, holding): sys.stdout, self._output_stream, holding.symbol) def __enter__(self): + '''Pauses the PleaseHold loading thread and prepares for input if this + class is initialized via a context manager + ''' sys.stdout = self._stream_tee term.move_line_down() self._holding.loading_event.clear() return self def __exit__(self, type, value, traceback): + '''Cleans up input prompts and resumes the PleaseHold loading thread if + this class is initialized via a context manager + ''' sys.stdout = sys.__stdout__ for _ in range(self._stream_tee.num_inputs + 1): term.clear_line() @@ -122,8 +177,25 @@ def __exit__(self, type, value, traceback): def hold(begin_msg='begin', end_msg='end', delay=1.0, symbol='.'): + '''Instantiates an instance of PleaseHold. + + The arguments are passed through to the PleaseHold constructor. + + Args: + begin_msg (str, optional): The message to the left of the loading bar + end_msg (str, optional): The message to the right of the loading bar + delay (float, optional): The delay between printing loading symbols + symbol (str, optional): The symbol to be used in the loading bar + ''' return PleaseHold(begin_msg, end_msg, delay, symbol) def transfer(holding): + '''Instantiates an instance of Transfer. + + The arguments are passed through to the Transfer constructor. + + Args: + holding (PleaseHold): The instance of PleaseHold that should be paused + ''' return Transfer(holding) diff --git a/pleasehold/stream_tee.py b/pleasehold/stream_tee.py index 0275b93..47ae404 100644 --- a/pleasehold/stream_tee.py +++ b/pleasehold/stream_tee.py @@ -1,11 +1,15 @@ -''' -This class forks a stream, allowing you to capture output while still displaying -output in the terminal. - -See: http://www.tentech.ca/2011/05/stream-tee-in-python-saving-stdout-to-file-while-keeping-the-console-alive/ -''' class StreamTee(object): - # Based on https://gist.github.com/327585 by Anand Kunal + '''Forks a stream, allowing you to capture output while still displaying + output in the terminal. + + See: http://www.tentech.ca/2011/05/stream-tee-in-python-saving-stdout-to-file-while-keeping-the-console-alive/ + + Args: + stream1 (:obj:`TextIOWrapper`): The original stream (ex: stdin, stdout) + stream2 (:obj:`StringIO`): A fork of the original stream + symbol (str, optional): The loading symbol set in the current instance + of PleaseHold + ''' def __init__(self, stream1, stream2, symbol='.'): self._stream1 = stream1 self._stream2 = stream2 @@ -21,6 +25,7 @@ def __getattr__(self, name): return getattr(self, '__methodmissing__') def __methodmissing__(self, *args, **kwargs): + '''Callback for events coming from the original stream''' if len(args) > 0 and args[0] != '\n' and args[0] != self._loading_symbol: self._num_inputs += 1 @@ -34,4 +39,6 @@ def __methodmissing__(self, *args, **kwargs): @property def num_inputs(self): + '''Gets the number of inputs that have occurred during the Transfer + context''' return self._num_inputs diff --git a/pleasehold/terminal.py b/pleasehold/terminal.py index e6b5ef4..742d43b 100644 --- a/pleasehold/terminal.py +++ b/pleasehold/terminal.py @@ -1,13 +1,18 @@ +'''A utility module that helps with terminal manipulation''' + import sys def clear_line(): + '''Clears all the text on the current line''' sys.stdout.write('\x1b[2K\r') def move_line_up(): + '''Moves the terminal cursor up one line''' sys.stdout.write('\033[F') def move_line_down(): + '''Moves the terminal cursor down one line''' sys.stdout.write('\n')