Skip to content

Conversation

@tyewang
Copy link

@tyewang tyewang commented May 15, 2015

I discovered that I couldn't pass in arguments to my tasks if my arguments were decorated.

For example:

def another_decorator(func):             
    def decorator(*args, **kwargs): 
        return func(*args, **kwargs)      
    return decorator

@task
@another_decorator
def my_task(my_argument):
    ...

In this example, running invoke my_task --my_argument 1234 would not work properly. Invoke's argument parsing only parsed the normal arguments of the decorated function, which it has none (it has varargs "args" and keyword arguments "kwargs").

This PR fixes this case.

@tyewang tyewang force-pushed the make_tasks_play_nicely_with_decorators branch from 8dda82c to 36006e7 Compare May 15, 2015 23:14
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to run tests in this project. I eventually got frustrated and changed all the tests to unittest.TestCase and ran them using nose. How do you usually run tests?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests run with spec, and we have a local helper for it as well, see http://www.pyinvoke.org/development.html#running-management-tasks

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to get tests to run fine with invoke test, but I wasn't able to run individual tests or individual test files. Everytime I tried to use nosetest or spec on tests/tasks.py, it wouldn't detect any tests. So, how do you run individual tests?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That setup lets you load individual test files with -m (so e.g. inv test -m runners to run tests/runners.py). spec lacks support for individual tests, which is annoying and something I'll probably try to get working soon.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, good to know. Thanks!

--- Original Message ---

From: "Jeff Forcier" [email protected]
Sent: May 22, 2015 5:23 PM
To: "pyinvoke/invoke" [email protected]
Cc: "Tye Wang" [email protected]
Subject: Re: [invoke] Add handling of decorators when parsing arguments (#246)

@@ -293,3 +292,40 @@ def mytask(longer_arg):
eq_(arg.names, ('longer-arg', 'l'))
eq_(arg.attr_name, 'longer_arg')
eq_(arg.name, 'longer_arg')
+

  •    def decorated_function_names_are_preserved(self):
    

That setup lets you load individual test files with -m (so e.g. inv test -m runners to run tests/runners.py). spec lacks support for individual tests, which is annoying and something I'll probably try to get working soon.


Reply to this email directly or view it on GitHub:
https://github.com/pyinvoke/invoke/pull/246/files#r30931654

@tyewang tyewang force-pushed the make_tasks_play_nicely_with_decorators branch from 36006e7 to 593d7d9 Compare June 26, 2015 14:58

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • E127 continuation line over-indented for visual indent

@tyewang
Copy link
Author

tyewang commented Sep 9, 2015

Hi @bitprophet, this PR has been waiting for a while as well. Is there anything I need to do for this one to get merged?

@tyewang
Copy link
Author

tyewang commented Feb 21, 2016

@bitprophet any update?

@guyskk
Copy link

guyskk commented Aug 1, 2018

I need this PR for run async task, here is my case:

from curio import run

def async_task(f):
    @task
    @wraps(f)
    def wrapped(ctx, *args, **kwargs):
        return run(f(ctx, *args, *kwargs))
    return wrapped

I just read the code, some thoughts:

In python 3.3+, inspect.signature is a better method to get signature, it can also resolve signature
of callables which decorated by functool.wraps, see __wrapped__ attribute in functools document.
But in python 2, only inspect.getargspec is available.

The get_undecorated_func implement seems not very reliable, and here https://github.com/mapleoin/undecorated is a better implement.

If OK, I'm glad to contribute.

@guyskk
Copy link

guyskk commented Aug 2, 2018

Handle callable-but-not-function objects(Not cause by this PR) has problems, for example:

class Demo:
    def __call__(self, ctx, abc):
        print(self, ctx, abc)

demo = task(name='demo')(Demo())

When I invoke it:

$ inv demo --abc=1
'demo' did not receive all required positional arguments!

Comment in source code says:

# Handle callable-but-not-function objects
# TODO: __call__ exhibits the 'self' arg; do we manually nix 1st result
# in argspec, or is there a way to get the "really callable" spec?

What it means? we can simply ignore the first argument if the callable is not a function.

@bitprophet
Copy link
Member

2.0.0 will be out soon & is now using inspect.signature!

@bitprophet bitprophet closed this Jan 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants