Use task variable name when task name is undefined. #766
In fabric.main.extract_tasks(), the dict mapping names to new-style task
This change brings the behavior for mapping tasks to names in compliance
A test case was added to confirm that the task name equal the variable
In fabric.main.extract_tasks(), the dict mapping names to new-style task objects now uses the variable name of the object when the object's name attribute is not defined. (Technically, when not obj.name or obj.name == 'undefined'). This change brings the behavior for mapping tasks to names in compliance with the fabric documentation. http://docs.fabfile.org/en/1.4.3/usage/tasks.html#new-style-tasks: Subclass Task (Task itself is intended to be abstract), define a run method, and instantiate your subclass at module level. Instances’ name attributes are used as the task name; if omitted the instance’s variable name will be used instead. A test case was added to confirm that the task name equal the variable name when the task object name attribute is undefined. This test fails with the old code and passes with the patched code.
New-style Task subclass objects which do not define a name attribute end up with the default obj.name = 'undefined' from Task. When the tasks are extracted from a loaded fabfile, obj.name should be set to the name of the instance variable, since obj.name is used internally by fabric in some circumstances, e.g. when `execute()` is called. This commit sets `obj.name = name` for task objects without a name, or with an undefined name.
The fix to set the task name on the command line from the instance variable name reveals another bug, I think. When running an "instance" task from the command line, the output uses the name of the instance variable. When running an "instance" task from within another task (via
Here is a fabfile.py that replicates this behavior:
from fabric.tasks import Task from fabric.api import * env.hosts = ['localhost'] class MyTask(Task): def run(self): run('uname') # Since task instance does not define 'name' attribute, it should be # set to 'uname' uname = MyTask() @task def all(): execute(uname)
Here is the output of several command lines that demonstrates a few things:
I have fixed problem by setting
Nose output after the fix shows the test succeeding as it should:
I've rebased (a copy of) your branch against the latest bugfix line (1.5) and I acknowledge your fix for the issue mentioned above (re: lazily filling in empty task
EDIT: I guess rebasing was the wrong idea, Github can't tell the changes were pulled in. Meh :) My fault for letting things get behind. Closing.