代码之家  ›  专栏  ›  技术社区  ›  Jesse Shieh José Valim

Python单击:setuptools下的异常处理

  •  2
  • Jesse Shieh José Valim  · 技术社区  · 6 年前

    我有一个 python click mycli foo 是有效的,但它们键入 mycli bar

    this page Command this guide ,它指向我的 命令 [console_scripts] 部分。例如, yourscript=yourscript:cli 指向 cli

    cli.main() 从内部 [控制台脚本] 或者如果这是正确的思考方式。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Stephen Rauch Afsar Ali    6 年前

    有一个习惯 click.Command 类中,您可以捕获调用的命令行,然后使用自定义类在异常处理程序中报告命令行中的任何错误,如:

    自定义类

    def CatchAllExceptions(cls, handler):
    
        class Cls(cls):
    
            _original_args = None
    
            def make_context(self, info_name, args, parent=None, **extra):
    
                # grab the original command line arguments
                self._original_args = ' '.join(args)
    
                try:
                    return super(Cls, self).make_context(
                        info_name, args, parent=parent, **extra)
                except Exception as exc:
                    # call the handler
                    handler(self, info_name, exc)
    
                    # let the user see the original error
                    raise
    
            def invoke(self, ctx):
                try:
                    return super(Cls, self).invoke(ctx)
                except Exception as exc:
                    # call the handler
                    handler(self, ctx.info_name, exc)
    
                    # let the user see the original error
                    raise
    
        return Cls
    
    
    def handle_exception(cmd, info_name, exc):
        # send error info to rollbar, etc, here
        click.echo(':: Command line: {} {}'.format(info_name, cmd._original_args))
        click.echo(':: Raised error: {}'.format(exc))
    

    然后要使用自定义命令/组,请将其作为 cls click.command click.group

    @click.command(cls=CatchAllExceptions(click.Command, handler=report_exception))
    
    @click.group(cls=CatchAllExceptions(click.Group, handler=report_exception))
    
    @click.group(cls=CatchAllExceptions(click.MultiCommand, handler=report_exception))
    

    请注意需要指定 单击。命令 子类也是必需的 要将异常信息发送到的处理程序。

    这是怎么回事?

    @click.group() @click.command() 装饰器通常实例化 click.Group 单击。命令 参数。因此,这是一件相对容易继承的事情 单击。命令 (等)在我们自己的类和超越理想的方法。

    click.Command.make_context() click.Command.invoke() 捕获异常,然后调用我们的异常处理程序。

    测试代码:

    import click
    
    @click.group(cls=CatchAllExceptions(click.Group, handler=report_exception))
    def cli():
        """A wonderful test program"""
        pass
    
    @cli.command()
    def foo():
        """A fooey command"""
        click.echo('Foo!')
    
    
    if __name__ == "__main__":
        commands = (
            'foo',
            'foo --unknown',
            'foo still unknown',
            '',
            '--help',
            'foo --help',
        )
    
        import sys, time
    
        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)
                cli(cmd.split())
    
            except BaseException as exc:
                if str(exc) != '0' and \
                        not isinstance(exc, (click.ClickException, SystemExit)):
                    raise
    

    结果:

    Click Version: 6.7
    Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
    -----------
    > foo
    Foo!
    -----------
    > foo --unknown
    Error: no such option: --unknown
    :: Command line: test.py foo --unknown
    :: Raised error: no such option: --unknown
    -----------
    > foo still unknown
    :: Command line: test.py foo still unknown
    :: Raised error: Got unexpected extra arguments (still unknown)
    Usage: test.py foo [OPTIONS]
    
    Error: Got unexpected extra arguments (still unknown)
    -----------
    > 
    Usage: test.py [OPTIONS] COMMAND [ARGS]...
    
      A wonderful test program
    
    Options:
      --help  Show this message and exit.
    
    Commands:
      foo  A fooey command
    -----------
    > --help
    Usage: test.py [OPTIONS] COMMAND [ARGS]...
    
      A wonderful test program
    
    Options:
      --help  Show this message and exit.
    
    Commands:
      foo  A fooey command
    -----------
    > foo --help
    Usage: test.py foo [OPTIONS]
    
      A fooey command
    
    Options:
      --help  Show this message and exit.