[PYTHON] Define a custom argument type with click (Example: Implementation of a type that makes a string eval an optional value)

Click allows you to define and use custom argument types. → http://click.pocoo.org/6/parameters/#implementing-custom-types

Method

Create a class that inherits click.ParamType and override convert (). If the value returned by convert () is None, that value (and through this convert ()) will be the optional value if the default argument is set.

Example) A type that makes an eval character string an optional value

In the following implementation example, only the character string is returned without eval, and the character string that cannot be eval is returned raw. If it contains spaces, quote it and pass it. The character string that is expanded in the shell needs to be escaped or devised.

eval_param_type.py


# -*- encoding: utf-8 -*-
import click

class EvalParamType(click.ParamType):
    def convert(self, value, param, ctx):
        if not isinstance(value, str):
            return value
        try:
            return eval(value)
        except:
            return value  # raw string


@click.command()
@click.option('--p', type=EvalParamType(), default={0:1, 2:3})
##Pass an instance of the class in the type keyword
def main(**kwargs):
    if 'p' in kwargs:
        print 'kwargs:', kwargs
        p = kwargs['p']
        print p.__class__, p


if __name__ == '__main__':
    main()

I'll try

$ python eval_param_type.py 
kwargs: {'p': {0: 1, 2: 3}}
<type 'dict'> {0: 1, 2: 3}

$ python eval_param_type.py --p "Hello"
kwargs: {'p': 'Hello'}
<type 'str'> Hello

$ python eval_param_type.py --p "'Hello, world'"
kwargs: {'p': 'Hello, world'}
<type 'str'> Hello, world

$ python eval_param_type.py --p hello
kwargs: {'p': 'hello'}
<type 'str'> hello

$ python eval_param_type.py --p 3.14
kwargs: {'p': 3.14}
<type 'float'> 3.14

$ python eval_param_type.py --p 5
kwargs: {'p': 5}
<type 'int'> 5

$ python eval_param_type.py --p -3
kwargs: {'p': -3}
<type 'int'> -3

$ python eval_param_type.py --p True
kwargs: {'p': True}
<type 'bool'> True

$ python eval_param_type.py --p 1+2
kwargs: {'p': 3}
<type 'int'> 3

$ python eval_param_type.py --p []
kwargs: {'p': []}
<type 'list'> []

$ python eval_param_type.py --p "()"
kwargs: {'p': ()}
<type 'tuple'> ()

$ python eval_param_type.py --p None
kwargs: {'p': {0: 1, 2: 3}}
<type 'dict'> {0: 1, 2: 3}
//Eval ‘None’ to become None and go to see the value set in the default argument

Recommended Posts

Define a custom argument type with click (Example: Implementation of a type that makes a string eval an optional value)
converting argument $ 1 type: unsupported type [] string, a slice of string
Format when passing a long string as an argument of python
The eval () function that calculates a string as an expression in python
Implement a model with state and behavior (3) --Example of implementation by decorator