##// END OF EJS Templates
Doc tweaks and updates
Doc tweaks and updates

File last commit:

r3660:35ad8289
r3663:11592a75
Show More
dependency.py
159 lines | 4.8 KiB | text/x-python | PythonLexer
MinRK
added dependency decorator
r3546 """Dependency utilities"""
MinRK
copyright statements
r3660 #-----------------------------------------------------------------------------
# Copyright (C) 2010-2011 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
MinRK
added dependency decorator
r3546
from IPython.external.decorator import decorator
MinRK
resort imports in a cleaner order
r3631
MinRK
eliminate relative imports
r3642 from .asyncresult import AsyncResult
from .error import UnmetDependency
MinRK
added dependency decorator
r3546
MinRK
added basic tunneling with ssh or paramiko
r3571
MinRK
added dependency decorator
r3546 class depend(object):
MinRK
cleanup pass
r3644 """Dependency decorator, for use with tasks.
`@depend` lets you define a function for engine dependencies
just like you use `apply` for tasks.
Examples
--------
::
@depend(df, a,b, c=5)
def f(m,n,p)
view.apply(f, 1,2,3)
will call df(a,b,c=5) on the engine, and if it returns False or
raises an UnmetDependency error, then the task will not be run
and another engine will be tried.
"""
MinRK
added dependency decorator
r3546 def __init__(self, f, *args, **kwargs):
self.f = f
self.args = args
self.kwargs = kwargs
def __call__(self, f):
return dependent(f, self.f, *self.args, **self.kwargs)
class dependent(object):
"""A function that depends on another function.
This is an object to prevent the closure used
in traditional decorators, which are not picklable.
"""
def __init__(self, f, df, *dargs, **dkwargs):
self.f = f
MinRK
Improvements to dependency handling...
r3607 self.func_name = getattr(f, '__name__', 'f')
MinRK
added dependency decorator
r3546 self.df = df
self.dargs = dargs
self.dkwargs = dkwargs
def __call__(self, *args, **kwargs):
if self.df(*self.dargs, **self.dkwargs) is False:
raise UnmetDependency()
return self.f(*args, **kwargs)
MinRK
Improvements to dependency handling...
r3607
@property
def __name__(self):
return self.func_name
MinRK
added dependency decorator
r3546
MinRK
added dependencies & Python scheduler
r3548 def _require(*names):
MinRK
cleanup pass
r3644 """Helper for @require decorator."""
MinRK
added dependencies & Python scheduler
r3548 for name in names:
try:
__import__(name)
except ImportError:
return False
return True
MinRK
added dependency decorator
r3546
MinRK
added dependencies & Python scheduler
r3548 def require(*names):
MinRK
cleanup pass
r3644 """Simple decorator for requiring names to be importable.
Examples
--------
In [1]: @require('numpy')
...: def norm(a):
...: import numpy
...: return numpy.linalg.norm(a,2)
"""
MinRK
added dependencies & Python scheduler
r3548 return depend(_require, *names)
class Dependency(set):
MinRK
add timeout for unmet dependencies in task scheduler
r3611 """An object for representing a set of msg_id dependencies.
MinRK
added dependencies & Python scheduler
r3548
MinRK
cleanup pass
r3644 Subclassed from set().
Parameters
----------
dependencies: list/set of msg_ids or AsyncResult objects or output of Dependency.as_dict()
The msg_ids to depend on
all : bool [default True]
Whether the dependency should be considered met when *all* depending tasks have completed
or only when *any* have been completed.
success_only : bool [default True]
Whether to consider only successes for Dependencies, or consider failures as well.
If `all=success_only=True`, then this task will fail with an ImpossibleDependency
as soon as the first depended-upon task fails.
"""
MinRK
added dependencies & Python scheduler
r3548
MinRK
dependency tweaks + dependency/scheduler docs
r3624 all=True
MinRK
Improvements to dependency handling...
r3607 success_only=True
MinRK
added dependencies & Python scheduler
r3548
MinRK
dependency tweaks + dependency/scheduler docs
r3624 def __init__(self, dependencies=[], all=True, success_only=True):
MinRK
added dependencies & Python scheduler
r3548 if isinstance(dependencies, dict):
# load from dict
MinRK
dependency tweaks + dependency/scheduler docs
r3624 all = dependencies.get('all', True)
MinRK
Improvements to dependency handling...
r3607 success_only = dependencies.get('success_only', success_only)
dependencies = dependencies.get('dependencies', [])
MinRK
dependency tweaks + dependency/scheduler docs
r3624 ids = []
if isinstance(dependencies, AsyncResult):
ids.extend(AsyncResult.msg_ids)
else:
for d in dependencies:
if isinstance(d, basestring):
ids.append(d)
elif isinstance(d, AsyncResult):
ids.extend(d.msg_ids)
else:
raise TypeError("invalid dependency type: %r"%type(d))
set.__init__(self, ids)
self.all = all
MinRK
Improvements to dependency handling...
r3607 self.success_only=success_only
MinRK
added dependencies & Python scheduler
r3548
MinRK
Improvements to dependency handling...
r3607 def check(self, completed, failed=None):
if failed is not None and not self.success_only:
completed = completed.union(failed)
MinRK
added dependencies & Python scheduler
r3548 if len(self) == 0:
return True
MinRK
dependency tweaks + dependency/scheduler docs
r3624 if self.all:
MinRK
add all completed task IDs to Scheduler.all_done
r3565 return self.issubset(completed)
else:
MinRK
dependency tweaks + dependency/scheduler docs
r3624 return not self.isdisjoint(completed)
MinRK
added dependencies & Python scheduler
r3548
MinRK
Improvements to dependency handling...
r3607 def unreachable(self, failed):
if len(self) == 0 or len(failed) == 0 or not self.success_only:
return False
MinRK
dependency tweaks + dependency/scheduler docs
r3624 # print self, self.success_only, self.all, failed
if self.all:
MinRK
Improvements to dependency handling...
r3607 return not self.isdisjoint(failed)
else:
MinRK
dependency tweaks + dependency/scheduler docs
r3624 return self.issubset(failed)
MinRK
Improvements to dependency handling...
r3607
MinRK
added dependencies & Python scheduler
r3548 def as_dict(self):
"""Represent this dependency as a dict. For json compatibility."""
return dict(
dependencies=list(self),
MinRK
dependency tweaks + dependency/scheduler docs
r3624 all=self.all,
MinRK
Improvements to dependency handling...
r3607 success_only=self.success_only,
MinRK
added dependencies & Python scheduler
r3548 )
MinRK
dependency tweaks + dependency/scheduler docs
r3624 __all__ = ['depend', 'require', 'dependent', 'Dependency']
MinRK
added dependency decorator
r3546