summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVilobh Meshram <vilobhmm@yahoo-inc.com>2015-02-03 01:53:32 +0000
committerVilobh Meshram <vilobhmm@yahoo-inc.com>2015-02-11 07:03:34 +0000
commitb7d59ec7484f159db2cce3dc89ae3f784e821bb2 (patch)
treecc36028dcb9f7115059055e515681abf74671777
parent19f9674877902e7e67b6c48df04571b040fdef50 (diff)
downloadtaskflow-b7d59ec7484f159db2cce3dc89ae3f784e821bb2.tar.gz
Docstrings should document parameters return values
Partial-Bug: #1374202 Documents what the function parameters are, what is the type of the parameters passed what return values are, how it is used and what they should provide for it when using a method/class or deriving from an existing class. Change-Id: Ie81b3a446c9fee2dad9411efa28dad8d455b06ba
-rw-r--r--taskflow/types/failure.py6
-rw-r--r--taskflow/types/fsm.py84
-rw-r--r--taskflow/types/futures.py46
-rw-r--r--taskflow/types/latch.py9
-rw-r--r--taskflow/types/notifier.py65
-rw-r--r--taskflow/types/periodic.py7
-rw-r--r--taskflow/types/table.py11
-rw-r--r--taskflow/types/timing.py10
-rw-r--r--taskflow/types/tree.py10
9 files changed, 200 insertions, 48 deletions
diff --git a/taskflow/types/failure.py b/taskflow/types/failure.py
index 0f45bc3..7df0f68 100644
--- a/taskflow/types/failure.py
+++ b/taskflow/types/failure.py
@@ -175,7 +175,11 @@ class Failure(object):
and self.traceback_str == other.traceback_str)
def matches(self, other):
- """Checks if another object is equivalent to this object."""
+ """Checks if another object is equivalent to this object.
+
+ :returns: checks if another object is equivalent to this object
+ :rtype: boolean
+ """
if not isinstance(other, Failure):
return False
if self.exc_info is None or other.exc_info is None:
diff --git a/taskflow/types/fsm.py b/taskflow/types/fsm.py
index 6ca2290..df61476 100644
--- a/taskflow/types/fsm.py
+++ b/taskflow/types/fsm.py
@@ -76,13 +76,23 @@ class FSM(object):
@property
def current_state(self):
+ """Return the current state name.
+
+ :returns: current state name
+ :rtype: string
+ """
if self._current is not None:
return self._current.name
return None
@property
def terminated(self):
- """Returns whether the state machine is in a terminal state."""
+ """Returns whether the state machine is in a terminal state.
+
+ :returns: whether the state machine is in
+ terminal state or not
+ :rtype: boolean
+ """
if self._current is None:
return False
return self._states[self._current.name]['terminal']
@@ -90,11 +100,16 @@ class FSM(object):
def add_state(self, state, terminal=False, on_enter=None, on_exit=None):
"""Adds a given state to the state machine.
- The on_enter and on_exit callbacks, if provided will be expected to
- take two positional parameters, these being the state being exited (for
- on_exit) or the state being entered (for on_enter) and a second
- parameter which is the event that is being processed that caused the
- state transition.
+ :param on_enter: callback, if provided will be expected to take
+ two positional parameters, these being state being
+ entered and the second parameter is the event that is
+ being processed that caused the state transition
+ :param on_exit: callback, if provided will be expected to take
+ two positional parameters, these being state being
+ entered and the second parameter is the event that is
+ being processed that caused the state transition
+ :param state: state being entered or exited
+ :type state: string
"""
if self.frozen:
raise FrozenMachine()
@@ -117,22 +132,22 @@ class FSM(object):
def add_reaction(self, state, event, reaction, *args, **kwargs):
"""Adds a reaction that may get triggered by the given event & state.
+ :param state: the last stable state expressed
+ :type state: string
+ :param event: event that caused the transition
+ :param args: non-keyworded arguments
+ :type args: list
+ :param kwargs: key-value pair arguments
+ :type kwargs: dictionary
+
Reaction callbacks may (depending on how the state machine is ran) be
- used after an event is processed (and a transition occurs) to cause the
- machine to react to the newly arrived at stable state.
-
- These callbacks are expected to accept three default positional
- parameters (although more can be passed in via *args and **kwargs,
- these will automatically get provided to the callback when it is
- activated *ontop* of the three default). The three default parameters
- are the last stable state, the new stable state and the event that
- caused the transition to this new stable state to be arrived at.
-
- The expected result of a callback is expected to be a new event that
- the callback wants the state machine to react to. This new event
- may (depending on how the state machine is ran) get processed (and
- this process typically repeats) until the state machine reaches a
- terminal state.
+ used after an event is processed (and a transition occurs) to cause
+ the machine to react to the newly arrived at stable state. The
+ expected result of a callback is expected to be a
+ new event that the callback wants the state machine to react to.
+ This new event may (depending on how the state machine is ran) get
+ processed (and this process typically repeats) until the state
+ machine reaches a terminal state.
"""
if self.frozen:
raise FrozenMachine()
@@ -148,7 +163,12 @@ class FSM(object):
" already defined" % (state, event))
def add_transition(self, start, end, event):
- """Adds an allowed transition from start -> end for the given event."""
+ """Adds an allowed transition from start -> end for the given event.
+
+ :param start: start of the transition
+ :param end: end of the transition
+ :param event: event that caused the transition
+ """
if self.frozen:
raise FrozenMachine()
if start not in self._states:
@@ -164,7 +184,10 @@ class FSM(object):
self._states[start]['on_exit'])
def process_event(self, event):
- """Trigger a state change in response to the provided event."""
+ """Trigger a state change in response to the provided event.
+
+ :param event: event to be processed to cause a potential transition
+ """
current = self._current
if current is None:
raise NotInitialized("Can only process events after"
@@ -256,7 +279,14 @@ class FSM(object):
event = cb(old_state, new_state, event, *args, **kwargs)
def __contains__(self, state):
- """Returns if this state exists in the machines known states."""
+ """Returns if this state exists in the machines known states.
+
+ :param state: input state
+ :type state: string
+ :returns: checks whether the state exists in the machine
+ known states
+ :rtype: boolean
+ """
return state in self._states
def freeze(self):
@@ -270,7 +300,11 @@ class FSM(object):
@property
def events(self):
- """Returns how many events exist."""
+ """Returns how many events exist.
+
+ :returns: how many events exist
+ :rtype: number
+ """
c = 0
for state in six.iterkeys(self._states):
c += len(self._transitions[state])
diff --git a/taskflow/types/futures.py b/taskflow/types/futures.py
index 1d847dd..2a6f7b6 100644
--- a/taskflow/types/futures.py
+++ b/taskflow/types/futures.py
@@ -54,6 +54,11 @@ class _Gatherer(object):
self._stats = ExecutorStatistics()
def _capture_stats(self, watch, fut):
+ """Capture statistics
+
+ :param watch: stopwatch object
+ :param fut: future object
+ """
watch.stop()
with self._stats_lock:
# Use a new collection and lock so that all mutations are seen as
@@ -79,6 +84,7 @@ class _Gatherer(object):
cancelled=cancelled)
def submit(self, fn, *args, **kwargs):
+ """Submit work to be executed and capture statistics."""
watch = timing.StopWatch()
if self._start_before_submit:
watch.start()
@@ -301,7 +307,13 @@ class GreenThreadPoolExecutor(_futures.Executor):
return self._gatherer.statistics
def submit(self, fn, *args, **kwargs):
- """Submit some work to be executed (and gather statistics)."""
+ """Submit some work to be executed (and gather statistics).
+
+ :param args: non-keyworded arguments
+ :type args: list
+ :param kwargs: key-value arguments
+ :type kwargs: dictionary
+ """
with self._shutdown_lock:
if self._shutdown:
raise RuntimeError('Can not schedule new futures'
@@ -316,6 +328,12 @@ class GreenThreadPoolExecutor(_futures.Executor):
return f
def _spin_up(self, work):
+ """Spin up a greenworker if less than max_workers.
+
+ :param work: work to be given to the greenworker
+ :returns: whether a green worker was spun up or not
+ :rtype: boolean
+ """
alive = self._pool.running() + self._pool.waiting()
if alive < self._max_workers:
self._pool.spawn_n(_GreenWorker(self, work, self._delayed_work))
@@ -350,28 +368,46 @@ class ExecutorStatistics(object):
@property
def failures(self):
- """How many submissions ended up raising exceptions."""
+ """How many submissions ended up raising exceptions.
+
+ :returns: how many submissions ended up raising exceptions
+ :rtype: number
+ """
return self._failures
@property
def executed(self):
- """How many submissions were executed (failed or not)."""
+ """How many submissions were executed (failed or not).
+
+ :returns: how many submissions were executed
+ :rtype: number
+ """
return self._executed
@property
def runtime(self):
- """Total runtime of all submissions executed (failed or not)."""
+ """Total runtime of all submissions executed (failed or not).
+
+ :returns: total runtime of all submissions executed
+ :rtype: number
+ """
return self._runtime
@property
def cancelled(self):
- """How many submissions were cancelled before executing."""
+ """How many submissions were cancelled before executing.
+
+ :returns: how many submissions were cancelled before executing
+ :rtype: number
+ """
return self._cancelled
@property
def average_runtime(self):
"""The average runtime of all submissions executed.
+ :returns: average runtime of all submissions executed
+ :rtype: number
:raises: ZeroDivisionError when no executions have occurred.
"""
return self._runtime / self._executed
diff --git a/taskflow/types/latch.py b/taskflow/types/latch.py
index 3e27978..0778330 100644
--- a/taskflow/types/latch.py
+++ b/taskflow/types/latch.py
@@ -49,10 +49,11 @@ class Latch(object):
def wait(self, timeout=None):
"""Waits until the latch is released.
- NOTE(harlowja): if a timeout is provided this function will wait
- until that timeout expires, if the latch has been released before the
- timeout expires then this will return True, otherwise it will
- return False.
+ :param timeout: wait until the timeout expires
+ :type timeout: number
+ :returns: true if the latch has been released before the
+ timeout expires otherwise false
+ :rtype: boolean
"""
watch = tt.StopWatch(duration=timeout)
watch.start()
diff --git a/taskflow/types/notifier.py b/taskflow/types/notifier.py
index 9f4df80..77dbbc0 100644
--- a/taskflow/types/notifier.py
+++ b/taskflow/types/notifier.py
@@ -29,6 +29,18 @@ class _Listener(object):
"""Internal helper that represents a notification listener/target."""
def __init__(self, callback, args=None, kwargs=None, details_filter=None):
+ """Initialize members
+
+ :param callback: callback function
+ :param details_filter: a callback that will be called before the
+ actual callback that can be used to discard
+ the event (thus avoiding the invocation of
+ the actual callback)
+ :param args: non-keyworded arguments
+ :type args: list
+ :param kwargs: key-value pair arguments
+ :type kwargs: dictionary
+ """
self._callback = callback
self._details_filter = details_filter
if not args:
@@ -64,6 +76,13 @@ class _Listener(object):
return "<%s>" % repr_msg
def is_equivalent(self, callback, details_filter=None):
+ """Check if the callback is same
+
+ :param callback: callback used for comparison
+ :param details_filter: callback used for comparison
+ :returns: false if not the same callback, otherwise true
+ :rtype: boolean
+ """
if not reflection.is_same_callback(self._callback, callback):
return False
if details_filter is not None:
@@ -105,14 +124,22 @@ class Notifier(object):
self._listeners = collections.defaultdict(list)
def __len__(self):
- """Returns how many callbacks are registered."""
+ """Returns how many callbacks are registered.
+
+ :returns: count of how many callbacks are registered
+ :rtype: number
+ """
count = 0
for (_event_type, listeners) in six.iteritems(self._listeners):
count += len(listeners)
return count
def is_registered(self, event_type, callback, details_filter=None):
- """Check if a callback is registered."""
+ """Check if a callback is registered.
+
+ :returns: checks if the callback is registered
+ :rtype: boolean
+ """
for listener in self._listeners.get(event_type, []):
if listener.is_equivalent(callback, details_filter=details_filter):
return True
@@ -134,7 +161,8 @@ class Notifier(object):
:param event_type: event type that occurred
:param details: additional event details *dictionary* passed to
- callback keyword argument with the same name.
+ callback keyword argument with the same name
+ :type details: dictionary
"""
if not self.can_trigger_notification(event_type):
LOG.debug("Event type '%s' is not allowed to trigger"
@@ -165,6 +193,13 @@ class Notifier(object):
:meth:`.notify` method (if a details filter callback is provided then
the target callback will *only* be triggered if the details filter
callback returns a truthy value).
+
+ :param event_type: event type input
+ :param callback: function callback to be registered.
+ :param args: non-keyworded arguments
+ :type args: list
+ :param kwargs: key-value pair arguments
+ :type kwargs: dictionary
"""
if not six.callable(callback):
raise ValueError("Event callback must be callable")
@@ -189,7 +224,10 @@ class Notifier(object):
details_filter=details_filter))
def deregister(self, event_type, callback, details_filter=None):
- """Remove a single listener bound to event ``event_type``."""
+ """Remove a single listener bound to event ``event_type``.
+
+ :param event_type: deregister listener bound to event_type
+ """
if event_type not in self._listeners:
return False
for i, listener in enumerate(self._listeners.get(event_type, [])):
@@ -199,7 +237,10 @@ class Notifier(object):
return False
def deregister_event(self, event_type):
- """Remove a group of listeners bound to event ``event_type``."""
+ """Remove a group of listeners bound to event ``event_type``.
+
+ :param event_type: deregister listeners bound to event_type
+ """
return len(self._listeners.pop(event_type, []))
def copy(self):
@@ -220,7 +261,12 @@ class Notifier(object):
return True
def can_trigger_notification(self, event_type):
- """Checks if the event can trigger a notification."""
+ """Checks if the event can trigger a notification.
+
+ :param event_type: event that needs to be verified
+ :returns: whether the event can trigger a notification
+ :rtype: boolean
+ """
if event_type in self._DISALLOWED_NOTIFICATION_EVENTS:
return False
else:
@@ -251,7 +297,12 @@ class RestrictedNotifier(Notifier):
yield event_type
def can_be_registered(self, event_type):
- """Checks if the event can be registered/subscribed to."""
+ """Checks if the event can be registered/subscribed to.
+
+ :param event_type: event that needs to be verified
+ :returns: whether the event can be registered/subscribed to
+ :rtype: boolean
+ """
return (event_type in self._watchable_events or
(event_type == self.ANY and self._allow_any))
diff --git a/taskflow/types/periodic.py b/taskflow/types/periodic.py
index bbb494d..79821c4 100644
--- a/taskflow/types/periodic.py
+++ b/taskflow/types/periodic.py
@@ -39,7 +39,12 @@ _PERIODIC_ATTRS = tuple([
def periodic(spacing, run_immediately=True):
- """Tags a method/function as wanting/able to execute periodically."""
+ """Tags a method/function as wanting/able to execute periodically.
+
+ :param run_immediately: option to specify whether to run
+ immediately or not
+ :type run_immediately: boolean
+ """
if spacing <= 0:
raise ValueError("Periodicity/spacing must be greater than"
diff --git a/taskflow/types/table.py b/taskflow/types/table.py
index 6813fab..76016dc 100644
--- a/taskflow/types/table.py
+++ b/taskflow/types/table.py
@@ -49,8 +49,15 @@ class PleasantTable(object):
@classmethod
def _size_selector(cls, possible_sizes):
- # The number two is used so that the edges of a column have spaces
- # around them (instead of being right next to a column separator).
+ """Select the maximum size, utility function for adding borders.
+
+ The number two is used so that the edges of a column have spaces
+ around them (instead of being right next to a column separator).
+
+ :param possible_sizes: possible sizes available
+ :returns: maximum size
+ :rtype: number
+ """
try:
return max(x + 2 for x in possible_sizes)
except ValueError:
diff --git a/taskflow/types/timing.py b/taskflow/types/timing.py
index da3938d..e22b2da 100644
--- a/taskflow/types/timing.py
+++ b/taskflow/types/timing.py
@@ -250,8 +250,10 @@ class StopWatch(object):
:param return_none: when ``True`` instead of raising a ``RuntimeError``
when no duration has been set this call will
- return ``None`` instead.
+ return ``None`` instead
:type return_none: boolean
+ :returns: how many seconds left until the watch expires
+ :rtype: number
"""
if self._state != self._STARTED:
raise RuntimeError("Can not get the leftover time of a stopwatch"
@@ -265,7 +267,11 @@ class StopWatch(object):
return max(0.0, self._duration - self.elapsed())
def expired(self):
- """Returns if the watch has expired (ie, duration provided elapsed)."""
+ """Returns if the watch has expired (ie, duration provided elapsed).
+
+ :returns: if the watch has expired
+ :rtype: boolean
+ """
if self._state is None:
raise RuntimeError("Can not check if a stopwatch has expired"
" if it has not been started/stopped")
diff --git a/taskflow/types/tree.py b/taskflow/types/tree.py
index e6fad20..87fae4e 100644
--- a/taskflow/types/tree.py
+++ b/taskflow/types/tree.py
@@ -96,6 +96,9 @@ class Node(object):
This will search not only this node but also any children nodes and
finally if nothing is found then None is returned instead of a node
object.
+
+ :param item: item to lookup.
+ :returns: the node for an item if it exists in this node
"""
for n in self.dfs_iter(include_self=True):
if n.item == item:
@@ -103,7 +106,12 @@ class Node(object):
return None
def __contains__(self, item):
- """Returns if this item exists in this node or this nodes children."""
+ """Returns whether item exists in this node or this nodes children.
+
+ :returns: if the item exists in this node or nodes children,
+ true if the item exists, false otherwise
+ :rtype: boolean
+ """
return self.find(item) is not None
def __getitem__(self, index):