import click import sys import time def build_settings_option_class(settings_instance): def set_default(default_name): class Cls(click.Option): def __init__(self, *args, **kwargs): kwargs['default'] = getattr(settings_instance, default_name) super(Cls, self).__init__(*args, **kwargs) def handle_parse_result(self, ctx, opts, args): obj = ctx.find_object(type(settings_instance)) if obj is None: ctx.obj = settings_instance return super(Cls, self).handle_parse_result(ctx, opts, args) return Cls return set_default class Settings(object): def __init__(self): self.instance_disk_size = 100 self.instance_disk_type = 'pd-ssd' # import pudb; pudb.set_trace() settings = Settings() settings_option_cls = build_settings_option_class(settings) pass_settings = click.make_pass_decorator(Settings) @click.command() @click.help_option('-h', '--help') @click.option( '-s', '--disk-size', cls=settings_option_cls('instance_disk_size'), help="Disk size", show_default=True, type=int, ) @click.option( '-t', '--disk-type', cls=settings_option_cls('instance_disk_type'), help="Disk type", show_default=True, type=click.Choice(['pd-standard', 'pd-ssd']), ) @pass_settings def create(settings_test, disk_size, disk_type): print(f'{settings_test.instance_disk_type=}') # print(f'{dir(settings_test)=}') print(disk_size) print(disk_type) if __name__ == "__main__": commands = ( '-t pd-standard -s 200', '-t pd-standard', '-s 200', '', '--help', ) time.sleep(1) print('Click Version: {}'.format(click.__version__)) print('Python Version: {}'.format(sys.version)) for cmd in commands: try: time.sleep(0.1) print('-----------') print('> ' + cmd) time.sleep(0.1) create(cmd.split()) except BaseException as exc: if str(exc) != '0' and not isinstance( exc, (click.ClickException, SystemExit) ): raise