Repository: pallets/click

Issue:
make_pass_decorator strips argument
The inner most wrapper of make_pass_decorator invokes a function with `*args[1:]` which strips an argument.

A smaller example could be made but the following is the [invoking other commands](http://click.pocoo.org/6/advanced/#invoking-other-commands) example from the docs modified to also take in a custom config object.

The only difference between `dist_working` and `dist_broken` is the order of the decorators and consequently the parameters they take.

In my opinion they should both be valid and work.  What happens in `dist_broken` is, like the title says, the `make_pass_decorator` wrapper invokes the function with `*args[1:]` which removes the context object put there by the previous decorator.

```python
import click


class MyConfig(object):
    def __init__(self, verbose):
        self.verbose = verbose


pass_config = click.make_pass_decorator(MyConfig)


@click.group()
@click.option('--verbose', '-v', is_flag=True)
@click.pass_context
def cli(ctx, verbose):
    ctx.obj = MyConfig(verbose=verbose)


@cli.command()
@click.option('--count', default=1)
def test(count):
    click.echo('Count: %d' % count)


@cli.command('dist-working')
@click.option('--count', default=1)
@pass_config
@click.pass_context
def dist_working(ctx, cfg, count):
    if cfg.verbose:
        click.echo('about to forward')
    ctx.forward(test)
    if cfg.verbose:
        click.echo('about to invoke')
    ctx.invoke(test, count=42)


@cli.command('dist-broken')
@click.option('--count', default=1)
@click.pass_context
@pass_config
def dist_broken(cfg, ctx, count):
    if cfg.verbose:
        click.echo('about to forward')
    ctx.forward(test)
    if cfg.verbose:
        click.echo('about to invoke')
    ctx.invoke(test, count=42)
```



Discussion:

Resolving patch:
diff --git a/click/decorators.py b/click/decorators.py
--- a/click/decorators.py
+++ b/click/decorators.py
@@ -61,7 +61,7 @@ def new_func(*args, **kwargs):
                 raise RuntimeError('Managed to invoke callback without a '
                                    'context object of type %r existing'
                                    % object_type.__name__)
-            return ctx.invoke(f, obj, *args[1:], **kwargs)
+            return ctx.invoke(f, obj, *args, **kwargs)
         return update_wrapper(new_func, f)
     return decorator
 


Test patch:
diff --git a/tests/test_context.py b/tests/test_context.py
--- a/tests/test_context.py
+++ b/tests/test_context.py
@@ -203,3 +203,39 @@ def foo():
     assert not result.exception
     assert result.output == 'aha!\n'
     assert called == [True]
+
+
+def test_make_pass_decorator_args(runner):
+    """
+    Test to check that make_pass_decorator doesn't consume arguments based on
+    invocation order.
+    """
+    class Foo(object):
+        title = 'foocmd'
+
+    pass_foo = click.make_pass_decorator(Foo)
+
+    @click.group()
+    @click.pass_context
+    def cli(ctx):
+        ctx.obj = Foo()
+
+    @cli.command()
+    @click.pass_context
+    @pass_foo
+    def test1(foo, ctx):
+        click.echo(foo.title)
+
+    @cli.command()
+    @pass_foo
+    @click.pass_context
+    def test2(ctx, foo):
+        click.echo(foo.title)
+
+    result = runner.invoke(cli, ['test1'])
+    assert not result.exception
+    assert result.output == 'foocmd\n'
+
+    result = runner.invoke(cli, ['test2'])
+    assert not result.exception
+    assert result.output == 'foocmd\n'