Giter Site home page Giter Site logo

Comments (9)

mitsuhiko avatar mitsuhiko commented on August 25, 2024

Eager is only supposed to be used for things such as help or version or other parameters that have a similar behavior. Why do you need to set your parameter to eager?

from click.

bgschiller avatar bgschiller commented on August 25, 2024

Hmm. Maybe I'm abusing the feature. I'm trying to use it to set a higher priority for some parameters, so that a lower priority params can have access to the processed values of the eager params.

Here's an example that's closer to what I'm actually making. I was trying to use it to ensure that the train option was processed before the test option, as when the test option is not supplied it is set equal to train. I was trying to do that with callbacks, but I can also accomplish it in the function body.

import click

def train_to_list(ctx, value):
    '''Convert TRAIN from a comma-separated list to
    a true list.
    To be supplied as a callback to click.'''
    return value.split(',')

def grab_from_train(ctx, value):
    return value or ctx.params['train'][0]

@click.command()
@click.option('-t', '--train',
    help='A training set, or list of them. Eg. set1,set2,set3',
    required=True,
    is_eager=True,  # process this before predict
    callback=train_to_list)
@click.option('-p', '--predict',
    help='If omitted, PREDICT will be the first entry in TRAIN.',
    callback=grab_from_train)
def ml_cli(train,predict):
    '''Train and test the a machine learning model.
'''
    print 'train:', train
    print 'predict:', predict

if __name__ == '__main__':
    ml_cli()
$ python ml_cli.py -t set1
train: [u'set1']
predict: set1
$ python ml_cli.py -t set1 -p set3
train: [u'set1']
predict: set3
$ python ml_cli.py -t set1,set2,set3
train: [u'set1', u'set2', u'set3']
predict: set1
$ python ml_cli.py --help
Usage: ml_cli.py [OPTIONS]

Error: Missing option "-t / --train".

from click.

mitsuhiko avatar mitsuhiko commented on August 25, 2024

Parameters are handled in the order they are defined. As such you can just order them as you want to make that work.

from click.

mitsuhiko avatar mitsuhiko commented on August 25, 2024

Just to be clear about this: if you remove is_eager your code continues working.

from click.

bgschiller avatar bgschiller commented on August 25, 2024

Ah. Well now I feel sheepish. 🐑

Thanks for the help :)

from click.

ZenithDK avatar ZenithDK commented on August 25, 2024

I have run into this issue as well. Parsing the argument "APPLICATION_ROOT" I retrieve a list of directories inside that path, and then the -l parameter must be one of those dirs.

The way it is now, unless I specify a valid dir, I will not get any help text?

My code is:

application_dir = ''
voiceprompts_dir = ''

available_languages = []

def validate_and_set_paths(ctx, param, value):
    global available_languages, application_dir, output_dir, voiceprompts_dir, voiceprompts_wav_dir, ignored_dirs

    if not os.path.isdir(value):
        logging.error('Provided parameter is not a directory'.format(value))
        return False
    else:
        application_dir = os.path.abspath(value)
        voiceprompts_dir = os.path.join(application_dir, 'voiceprompts')

    if not os.path.isdir(voiceprompts_dir):
        logging.error('Voiceprompts directory does not exist: {}'.format(voiceprompts_dir))
        return False

    dirnames = os.walk(voiceprompts_dir).next()[1]
    for dirpath in dirnames:
        #logging.info('dirpath: {}'.format(dirpath))
        available_languages += [dirpath]

    available_languages += ['ALL']

def validate_chosen_languages(ctx, param, value):
    for language in value:
        if language not in available_languages:
            raise click.BadParameter('\n\tLanguage parameter provided ({}) must one of the following: {}'.format(language, available_languages))

    return value

@click.command(context_settings=CONTEXT_SETTINGS)
@click.argument('application_root',
                type=click.Path(exists=True),
                callback=validate_and_set_paths,
                required=True,
                is_eager=True)
@click.option('--languages', '-l',
              multiple=True,
              default=['ALL'],
              help='Language to convert',
              callback=validate_chosen_languages)
def main(application_root, languages):
    # Do stuff
    pass

if __name__ == '__main__':
    main()

from click.

s7anley avatar s7anley commented on August 25, 2024

@mitsuhiko I used same approach as @bgschiller, since user of script can change desired order of options which could change flow or break it. Is there another way how to define order of options instead of abusing is_eager which is breaking the help now.

from click.

skycaptain avatar skycaptain commented on August 25, 2024

@s7anley: You need to preserve the order of your options if you want to use these options in other options callback function; see here. A workaround (if you like to call it as such) would simply be putting your callback function inside your command function and passing the context:

def baz_callback(ctx, baz):
    if baz is None:
        ctx.abort("Use baz!")

    return baz.lower()

@click.command()
@click.option('--foo',
              required=True)
@click.option('--bar')
@click.option('--baz')
@click.pass_context
def process_file(ctx, foo, bar, baz):
    if bar is None:
        bar = foo

    baz = baz_callback(ctx, baz)

    print(foo, baz)

Otherwise just use exceptions:

def foo_callback(ctx, _, value):
    try:
        bar = ctx.params['bar']
    except KeyError:
        ctx.abort("--bar must be used prior to --foo")

    ...

from click.

s7anley avatar s7anley commented on August 25, 2024

@skycaptain thanks for tips. I eventually did what I wanted in own decorator, which is executed last so, all the parameters provided by user are either there or not.

from click.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.