def get_callable_spec(self): if not self._callable_spec: try: self._callable_spec = build_callable_spec( class_or_func=self.original_class_or_func ) except Exception as ex: logger.error( "Failed to create task %s: %s\n%s\n", self.original_class_or_func.__name__, str(ex), user_side_code(context=5), exc_info=show_exc_info(ex), ) raise return self._callable_spec
def decorated(item): try: func_spec = build_task_decorator_spec( item=item, decorator_kwargs=decorator_kwargs, default_result=task_default_result, ) # we can't create class dynamically because of python2/3 # __name__ is not overridable task_cls = TaskMetaclass( str(item.__name__), (task_type, ), dict( _conf__decorator_spec=func_spec, _callable_item=None, __doc__=item.__doc__, __module__=item.__module__, defaults=task_defaults, ), ) except Exception as ex: logger.error( "Failed to create task %s: %s\n%s\n", item.__name__, str(ex), user_side_code(context=5), exc_info=show_exc_info(ex), ) raise if func_spec.is_class: callable_item = six.add_metaclass(_DecoratedUserClassMeta)(item) else: callable_item = DbndFuncProxy(task_cls=task_cls) task_cls._callable_item = callable_item callable_item.func = item callable_item.task_cls = task_cls callable_item.task = task_cls callable_item.t = task_cls return task_cls._callable_item
def decorated(class_or_func): try: func_spec = build_task_decorator_spec( class_or_func=class_or_func, decorator_kwargs=decorator_kwargs, default_result=task_default_result, ) except Exception as ex: logger.error( "Failed to create task %s: %s\n%s\n", class_or_func.__name__, str(ex), user_side_code(context=5), exc_info=show_exc_info(ex), ) raise fp = TaskClsBuilder(func_spec, task_type, task_defaults) if func_spec.is_class: wrapper = six.add_metaclass(_DecoratedUserClassMeta)(class_or_func) fp._callable_item = wrapper else: @functools.wraps(class_or_func) def wrapper(*args, **kwargs): if in_tracking_mode(): with fp.tracking_context(args, kwargs) as track_result_callback: return track_result_callback(fp.func(*args, **kwargs)) return _call_handler( fp.get_task_cls(), call_user_code=fp.func, call_args=args, call_kwargs=kwargs, ) wrapper.dbnd_run = fp.dbnd_run wrapper.__is_dbnd_task__ = True wrapper.func = class_or_func # we're using CallableLazyObjectProxy to have lazy evaluation for creating task_cls # this is only orchestration scenarios task_cls = CallableLazyObjectProxy(fp.get_task_cls) wrapper.task_cls = task_cls wrapper.task = task_cls wrapper.t = task_cls # we need lazy task_definition here, for example for dbnd_task_as_bash_operator wrapper.task_definition = CallableLazyObjectProxy( fp.get_task_definition) # we need to manually register the task here, since in regular flow # this happens in TaskMetaclass, but it's not invoked here due to lazy # evaluation using CallableLazyObjectProxy tp = TaskPassport.from_func_spec(func_spec, decorator_kwargs) # TODO: we can use CallableLazyObjectProxy object (task_cls) instead of task_cls_factory r = get_task_registry() r.register_task_cls_factory( task_cls_factory=fp.get_task_cls, full_task_family=tp.full_task_family, task_family=tp.task_family, ) return wrapper