tskmgr module¶
Just-in-time task management.
Module author: Michael S. Chapman <chapmami@ohsu.edu>
Authors: | Michael S. Chapman <chapmami@ohsu.edu>, Oregon Health & Science University |
---|---|
Version: | 0.5, March 23, 2016 |
Changed in version Start: 06/01/13
Changed in version 0.4.1: 07/01/1
Changed in version 0.5.0: 05/16/15 ReStructuredText docs
To translate tasks from a command interpreter or GUI into functions or methods to be called, attempting to satisfy prerequisites before calling an exception if unable to do so.
An alternative to the use of Task and Prerequisite classes might be to build inter-dependent python properties where the getter method fills any unmet prerequisites.
-
class
tskmgr.
Prerequisite
¶ Bases:
object
Define/execute action needed to meet prerequisite of logical expression.
When an instance is evaluated within a logical expression, if not already True, the instance will try to make itself True by executing the defined prerequisite action, raising an exception if not successful.
-
quiet
= True¶ Var: below normal logging.
-
verbose
= False¶ Var: above normal logging.
-
-
class
tskmgr.
ReqExpr
(expr, *namespace, **kwargs)¶ Bases:
tskmgr.Prerequisite
Prerequisite implemented with great flexibility using exec & namespaces.
Prerequisite dependencies are defined on initiation, but must use values that are current when invoked. Dependencies must be defined indirectly, because Python’s call-by-value would fix them at their values on Prerequisite initiation. Call-by-reference must be emulated. ReqExpr does this with great flexibility by evaluating the condition as a string expression, after optionally defining global and local namespaces on initiation. ReqExpr similarly executes an action through exec of a string, using the same namespace(s).
Deprecated since version 0.4.0?: (mostly) in almost all circumstances can use safer ReqObj. ReqExpr was used successfully in stand-alone RSRef, but when when embedded for Fortran CNS, got an incomprehensible TypeError for a builtin when some namespaces were passed to eval/exec, perhaps resulting from a hidden conflict introduced in the wrapping. ReqObj avoids declarations of namespaces. Retrospectively (11/08/13) have had similar exceptions when the rsref shared object library used in the CNS-embedded version does not match the python source versions, so it is possible that rebuilding the library would solve the problem.
Define action that satisfies a prerequisite.
Example:
self.have_coordinates = tskmgr.ReqExpr("atoms is not None", globals(), self, doc="Coordinate input", action="atoms=A.Atoms(filename=Q.option.pdb_in)")
Parameters: - expr (str) – bool(expr) == True will be used in subsequent methods to determine whether a prerequisite is met or whether to call action
- action – string expression for
exec()
. Ideally, successful execution should lead to expr evaluating as True, but see also certify. The default (None) will raise an exception when the instance is later evaluated if expr then evaluates as False. This can be used to interrupt execution in cases when a prerequisite cannot be satisfied automatically. Note: Error messages will be more compact if use ”;” to delimit statements, but\n
is needed before “if” statements. - namespace – the namespace dict(s) for eval & exec, global [and
optionally local]. See python documentation for exec for details.
(Global can be set to [] to force use only of local.)
Note: global, but not local mappings are writable.
New bindings in local can be used within exec, but are lost after
the return.
Note also: If local is provided, new bindings are created in the
local namespace, and are lost after the return.
This behaviour can be changed by declaring the variable as global
within the exec expression (eg.
global x; x = 99
). Furthermore: As direct binding of local variables is unreliable (in exec), non-global values that need to be saved should be bound to a specified namespace dict such as self.__dict__ within a method or presumably a fully qualified name in the global namespace. - certify (bool) – successful execution of action will over-rule evaluation of expr until self.certified is reset to False. This is a way for the calling program to manage a prerequisite if action cannot change evaluation of expr. Use as a last resort.
- doc (str) – printed in error messages.
-
class
tskmgr.
ReqObj
(condition, obj, action=None, args=[], kwargs={}, bind_to=None, certify=False, doc='Required Object')¶ Bases:
tskmgr.Prerequisite
Prerequisite within a defined object.
Prerequisite dependencies are defined on initiation, but must use values that are current when invoked. Dependencies must be defined indirectly, because Python’s call-by-value would fix them at their values on Prerequisite initiation. Call-by-reference must be emulated. ReqObj does this by defining the condition and both the arguments and return binding for the action as strings that are interpreted first as attributes of an object defined on initiation, or (failing that) as expressions to be evaluated in the default (global) namespace.
There are a number of limitations that with substantial increase in complexity, could be removed:
- condition, action arguments and return-binding must be attributes of
the same object.
- other expressions are evaluated in the tskmgr namespace, not the
calling namespace.
- the only external module currently imported is argparser as Q, which
makes option opt accessible as expression Q.option.opt. There is no way to access directly objects in other modules.
These limitations can usually be circumvented using the following strategies to avoid using ReqExpr:
- Initialize with obj=self, so that references are call-back.
Then attributes local to the calling code can be bound to a wide selection of objects. Similarly local properties can be used to evaluate more complex conditions.
See also
ReqExpr (if desperate) for more flexible / more fickle implementation.
Examples:
self.have_coordinates = tskmgr.ReqObj('atoms', self, action=A.Atoms, bind_to='atoms', doc='Coordinate input', kwargs=dict(filename='Q.option.pdb_in'))
Parameters: - condition (str or list of str) – condition(s) to be met as attributes of obj or expressions, both evaluated as bool
- obj – object that will be searched first for condition attributes and action argument attributes, before they are evaluated as expressions. The return value of action will also be bound to the attribute of obj specified by bind_to.
- action (callable) – to be run to meet prerequisite.
- args (list of str) – arguments for action, as names of attributes in obj or expressions.
- kwargs (dict of str) – keyword arguments for action, as names of attributes in obj or expressions.
- certify (bool) – successful execution of action will over-rule evaluation of expr until self.certified is reset to False. This is a way for the calling program to manage a prerequisite if action does not automatically set condition. Use as a last resort.
- bind_to (str or NoneType) – name of obj’s attribute where return value of action is to be saved.
- doc (str) – printed in error messages.
-
getattr_or_eval
(name)¶
-
is_met
()¶
-
verbose
= False¶
-
class
tskmgr.
Task
(call, doc='', state=False, prerequisites=[], auto=False, args=[], kwargs={}, obj=None, bind_to=None)¶ Bases:
object
Wraps a callable with prerequisites, queries if run etc..
When the Task is called, previously defined prerequisites are checked / run before execution of the callable, thereby supporting the chaining of actions executed on an as-needed basis. Tasks may be tested, and if not current, will self-run with arguments defined at initialization if auto is set. Thus, a Task can sometimes substitute for a Prerequisite, although the latter provides finer control / more flexibility.
Variables: - verbose – log actions
- current – should be set to False by other tasks that make this task out of date.
Parameters: - call (callable) – function or method to be called
- doc (str) – user-friendly description of task for error messages.
- state (bool) – if True, Task() is a state, generally run only once, after which self.current is set to True, short-cutting future calls until self.current is reset to False. If state is False, multiple invocations expected, no short-cutting.
- prerequisites (list of bool or class instances with __nonzero__ method (eg. Task, Prerequisite)) – other tasks or manager attributes on which this action depends and the action to take if not True
- auto (bool) – if boolean evaluation of self (__nonzero__) is False, then try to make it True by running the task with default arguments, throwing an exception on failure.
- args (list of str) – default arguments for auto-running (__call__), as names of attributes in obj or expressions.
- kwargs (dict of str) – default keyword arguments for auto-running (__call__), as names of attributes in obj or expressions.
- obj – object that will be searched first for default argument attributes (before they are evaluated as expressions). On auto-run, the return value will be saved in the bind_to attribute of obj.
- bind_to (str or NoneType) – name of obj attribute where return value of an auto-run to be saved.
-
getattr_or_eval
(name)¶
-
verbose
= False¶
-
exception
tskmgr.
TaskError
(*args)¶ Bases:
exceptions.StandardError
Failure to execute user-requested task, or meet its pre-requisites.
-
exception
tskmgr.
UnMetPrerequisite
(*args)¶ Bases:
exceptions.ValueError
Prerequisite undefined, or exception when attempting to satisfy.
-
tskmgr.
errmsg
(doc)¶ Captures message printed on exception for wrapping in another.
-
tskmgr.
get_namespace
(namespace)¶ Polymorphic just-in-time generation of namespace.
Parameters: namespace (dict, callable or object) – namespace, or a function that generates one (globals, locals, vars), or an object whose namespace is to be used. Returns: namespace Return type: dict Raises TypeError: if cannot generate a namesapce dictionary.
-
tskmgr.
get_namespaces
(*namespaces)¶ Polymorphic just-in-time generation of namespaces.
Parameters: namespaces (sequence of dict, callable or object) – each is a namespace, function that generates one (globals, locals, vars), or object whose namespace is to be used. Returns: namespace(s) Return type: list of dict(s) Raises TypeError: if cannot generate a namespace dictionary.
-
tskmgr.
public
(*namespaces)¶ Dictionary(s) containing public objects in (namespace) dictionary(s).
Parameters: namespaces (dict(s)) – namespace dictionary(s). Returns: all objects not starting with “_”. Return type: dict or list(dicts)
-
tskmgr.
unexpected
(*namespaces, **kwargs)¶ Print list of unexpected private objects in (namespace) dictionary(s).
Diagnostic when debugging namespaces for ReqExpr().
Parameters: - namespaces (dict(s)) – namespace dictionary(s).
- allow (list) – classes or types in which objects with _* names are expected.