2

So I am just trying to play with objects and classes in click and repo is just a sample that I took from their examples list.

When I am trying to execute the smallest set of code, it is throwing errors when calling a function as below:

#!/usr/bin/env python

import os
import click

class Repo(object):

    def __init__(self, home):
        self.home = home
        self.config = {}
        self.verbose = False

    def set_config(self, key, value):
        self.config[key] = value
        if self.verbose:
            click.echo('  config[%s] = %s' % (key, value), file=sys.stderr)

    def __repr__(self):
        return '<Repo %r>' % self.home
pass_repo = click.make_pass_decorator(Repo)

@click.group()
@click.option('--repo-home', envvar='REPO_HOME', default='.repo',
              metavar='PATH', help='Changes the repository folder location.')
@click.option('--config', nargs=2, multiple=True,
              metavar='KEY VALUE', help='Overrides a config key/value pair.')
@click.option('--verbose', '-v', is_flag=True,
              help='Enables verbose mode.')

@click.pass_context
def cli(ctx, repo_home, config, verbose):
    """Repo is a command line tool that showcases how to build complex
    command line interfaces with Click.
    This tool is supposed to look like a distributed version control
    system to show how something like this can be structured.
    """
    # Create a repo object and remember it as as the context object.  From
    # this point onwards other commands can refer to it by using the
    # @pass_repo decorator.
    click.echo('Hello world')
    click.echo('Hello %s!' % repo_home)
    ctx.obj = Repo(os.path.abspath(repo_home))
    ctx.obj.verbose = verbose
    for key, value in config:
        ctx.obj.set_config(key, value)

@cli.command()
@pass_repo
def clone(repo):
    """Clones a repository.
    This will clone the repository at SRC into the folder DEST.  If DEST
    is not provided this will automatically use the last path component
    of SRC and create that folder.
    """
    click.echo('Making shallow checkout')

if __name__ == '__main__':
    clone()

Command:

python click_test.py

Error:

RuntimeError: Managed to invoke callback without a context object of type 'Repo' existing

I am not sure if I need the cli function and the clone function? Can I just create an object in cli and initialize the repo class?

2
  • The decorator you are using finds an object instance in the context. Thus it is likely not useful for the top level command. What problem are you trying to solve? Commented Oct 3, 2017 at 18:14
  • @StephenRauch I am just trying to do argument passing using click similar to how we do it in python using objects and class. Commented Oct 3, 2017 at 19:23

1 Answer 1

3

Your code calls the clone() function, which is not the top level. You instead need to call cli() Here is a smaller example showing how to pass a class instance down through the context.

###Sample Code:

import click

class SampleClass(object):

    def __init__(self, some_info):
        self.some_info = some_info


pass_class = click.make_pass_decorator(SampleClass)


@click.group()
@click.pass_context
def cli(ctx):
    ctx.obj = SampleClass('Something to Store in Class')

@cli.command('a-command')
@pass_class
def a_command(a_class_instance):
    click.echo("Here we have access to Class instance from Context")
    click.echo("It contains '{}'".format(a_class_instance.some_info))


if __name__ == '__main__':
    cli(['a-command'])

###Results:

Here we have access to Class instance from Context
It contains 'Something to Store in Class'
Sign up to request clarification or add additional context in comments.

2 Comments

Why make the example more complicated than it needs to be? Since underscores have special meaning in click, do not use them in examples, as it will lead to issues, just as this one did. Also, having a_command called via a-command makes no sense to a newbie.
The occasional illustration of other concepts is often found to be helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.