<s> from __future__ import unicode_literals <EOL> import itertools <EOL> import inspect <EOL> import re <EOL> import six <EOL> from sigtools . modifiers import annotate , kwoargs <EOL> from sigtools . wrappers import wrappers <EOL> from clize import runner , parser , util , parameters <EOL> def lines_to_paragraphs ( L ) : <EOL> return list ( itertools . chain . from_iterable ( ( x , '<STR_LIT>' ) for x in L ) ) <EOL> p_delim = re . compile ( r'<STR_LIT>' ) <EOL> class Help ( object ) : <EOL> def __init__ ( self , subject , owner ) : <EOL> self . subject = subject <EOL> self . owner = owner <EOL> self . prepared = False <EOL> def prepare ( self ) : <EOL> """<STR_LIT>""" <EOL> self . prepared = True <EOL> def prepare_once ( self ) : <EOL> if not self . prepared : <EOL> self . prepare ( ) <EOL> @ runner . Clize ( hide_help = True ) <EOL> @ kwoargs ( '<STR_LIT>' ) <EOL> @ annotate ( name = parameters . pass_name , args = parser . Parameter . UNDOCUMENTED ) <EOL> def cli ( self , name , usage = False , * args ) : <EOL> """<STR_LIT>""" <EOL> self . prepare_once ( ) <EOL> name = name . rpartition ( '<STR_LIT:U+0020>' ) [ <NUM_LIT:0> ] <EOL> f = util . Formatter ( ) <EOL> if usage : <EOL> f . extend ( self . show_full_usage ( name ) ) <EOL> else : <EOL> f . extend ( self . show ( name ) ) <EOL> return six . text_type ( f ) <EOL> def split_docstring ( s ) : <EOL> if not s : <EOL> return <EOL> code_coming = False <EOL> code = False <EOL> for p in p_delim . split ( s ) : <EOL> if ( code_coming or code ) and p . startswith ( '<STR_LIT:U+0020>' ) : <EOL> yield p <EOL> code_coming = False <EOL> code = True <EOL> else : <EOL> item = '<STR_LIT:U+0020>' . join ( p . split ( ) ) <EOL> if item . endswith ( '<STR_LIT::>' ) : <EOL> code_coming = True <EOL> if item == '<STR_LIT::>' : <EOL> continue <EOL> code = False <EOL> yield item <EOL> def pname ( p ) : <EOL> return getattr ( p , '<STR_LIT>' , p . display_name ) <EOL> def filter_undocumented ( params ) : <EOL> for param in params : <EOL> if not param . undocumented : <EOL> yield param <EOL> LABEL_POS = "<STR_LIT>" <EOL> LABEL_OPT = "<STR_LIT>" <EOL> LABEL_ALT = "<STR_LIT>" <EOL> class ClizeHelp ( Help ) : <EOL> @ property <EOL> def signature ( self ) : <EOL> return self . subject . signature <EOL> @ classmethod <EOL> def get_param_type ( cls , param ) : <EOL> try : <EOL> param . aliases <EOL> except AttributeError : <EOL> return LABEL_POS <EOL> else : <EOL> return LABEL_OPT <EOL> def prepare ( self ) : <EOL> super ( ClizeHelp , self ) . prepare ( ) <EOL> s = self . sections = util . OrderedDict ( ( <EOL> ( LABEL_POS , util . OrderedDict ( ) ) , <EOL> ( LABEL_OPT , util . OrderedDict ( ) ) , <EOL> ( LABEL_ALT , util . OrderedDict ( ) ) , <EOL> ) ) <EOL> self . after = { } <EOL> for p in filter_undocumented ( self . signature . positional ) : <EOL> s [ LABEL_POS ] [ pname ( p ) ] = p , '<STR_LIT>' <EOL> for p in sorted ( <EOL> filter_undocumented ( self . signature . named ) , key = pname ) : <EOL> s [ LABEL_OPT ] [ pname ( p ) ] = p , '<STR_LIT>' <EOL> for p in sorted ( <EOL> filter_undocumented ( self . signature . alternate ) , key = pname ) : <EOL> s [ LABEL_ALT ] [ pname ( p ) ] = p , '<STR_LIT>' <EOL> self . _parse_help ( ) <EOL> s [ LABEL_ALT ] = s . pop ( LABEL_ALT ) <EOL> argdoc_re = re . compile ( r'<STR_LIT>' ) <EOL> def parse_docstring ( self , s , pnames = None ) : <EOL> free_text = [ ] <EOL> header = [ ] <EOL> label = None <EOL> last_argname = None <EOL> for p in split_docstring ( s ) : <EOL> argdoc = self . argdoc_re . match ( p ) <EOL> if argdoc : <EOL> argname , text = argdoc . groups ( ) <EOL> if free_text : <EOL> if free_text [ - <NUM_LIT:1> ] . endswith ( '<STR_LIT::>' ) : <EOL> label = free_text . pop ( ) <EOL> if last_argname : <EOL> if pnames is None or last_argname in pnames : <EOL> self . after [ last_argname ] = free_text <EOL> else : <EOL> header . extend ( free_text ) <EOL> free_text = [ ] <EOL> last_argname = argname <EOL> try : <EOL> default_label = self . get_param_type ( <EOL> self . signature . parameters [ argname ] ) <EOL> except KeyError : <EOL> continue <EOL> if pnames is not None and argname not in pnames : <EOL> continue <EOL> if default_label != LABEL_POS : <EOL> try : <EOL> param , _ = self . sections [ default_label ] . pop ( argname ) <EOL> except KeyError : <EOL> continue <EOL> label_ = label or default_label <EOL> if label_ not in self . sections : <EOL> self . sections [ label_ ] = util . OrderedDict ( ) <EOL> else : <EOL> try : <EOL> param , _ = self . sections [ default_label ] [ argname ] <EOL> except KeyError : <EOL> continue <EOL> label_ = default_label <EOL> self . sections [ label_ ] [ argname ] = param , text <EOL> else : <EOL> free_text . append ( p ) <EOL> if not last_argname : <EOL> header = free_text <EOL> footer = [ ] <EOL> else : <EOL> footer = free_text <EOL> return lines_to_paragraphs ( header ) , lines_to_paragraphs ( footer ) <EOL> def parse_func_help ( self , obj , pnames = None ) : <EOL> """<STR_LIT>""" <EOL> return self . parse_docstring ( inspect . getdoc ( obj ) , pnames ) <EOL> def _parse_subject_help ( self , subject ) : <EOL> ret = self . parse_func_help ( subject . func ) <EOL> for p in subject . signature . parameters . values ( ) : <EOL> p . prepare_help ( self ) <EOL> return ret <EOL> def _params_prepare ( self ) : <EOL> for p in self . subject . signature . parameters . values ( ) : <EOL> p . prepare_help ( self ) <EOL> def _parse_help_wrappers ( self , wrapper_funcs ) : <EOL> self . header , self . footer = self . parse_func_help ( self . subject ) <EOL> self . _params_prepare ( ) <EOL> for wrapper in wrapper_funcs : <EOL> self . parse_func_help ( wrapper ) <EOL> def _parse_help_autosig ( self , sig ) : <EOL> self . header = [ ] <EOL> self . footer = [ ] <EOL> self . _params_prepare ( ) <EOL> funcs = util . OrderedDict ( ) <EOL> for pname in sig . parameters : <EOL> for func in sig . sources [ pname ] : <EOL> funcs . setdefault ( func , set ( ) ) . add ( pname ) <EOL> funcs = sorted ( <EOL> funcs . items ( ) , <EOL> key = lambda i : sig . sources [ '<STR_LIT>' ] . get ( i [ <NUM_LIT:0> ] , <NUM_LIT:1000> ) ) <EOL> funcs . insert ( <NUM_LIT:0> , funcs . pop ( ) ) <EOL> for func , pnames in funcs : <EOL> h , f = self . parse_func_help ( func , pnames ) <EOL> self . header . extend ( h ) <EOL> self . footer . extend ( f ) <EOL> def _parse_help ( self ) : <EOL> wrapper_funcs = list ( wrappers ( self . subject . func ) ) <EOL> sig = self . subject . func_signature <EOL> if wrapper_funcs or not sig . parameters : <EOL> self . _parse_help_wrappers ( wrapper_funcs ) <EOL> else : <EOL> self . _parse_help_autosig ( sig ) <EOL> @ property <EOL> def description ( self ) : <EOL> self . prepare_once ( ) <EOL> try : <EOL> return self . header [ <NUM_LIT:0> ] <EOL> except IndexError : <EOL> return '<STR_LIT>' <EOL> def show_usage ( self , name ) : <EOL> return '<STR_LIT>' . format ( <EOL> name = name , <EOL> options = '<STR_LIT>' if self . signature . named else '<STR_LIT>' , <EOL> space = '<STR_LIT:U+0020>' if self . signature . positional else '<STR_LIT>' , <EOL> positional = '<STR_LIT:U+0020>' . join ( <EOL> str ( arg ) <EOL> for arg in filter_undocumented ( self . signature . positional ) ) <EOL> ) , <EOL> def alternate_usages ( self ) : <EOL> for param in self . signature . alternate : <EOL> if param . undocumented : <EOL> continue <EOL> subname = param . display_name <EOL> try : <EOL> helper = param . func . helper <EOL> except AttributeError : <EOL> yield subname + '<STR_LIT>' <EOL> else : <EOL> for usage in helper . usages ( ) : <EOL> yield subname + '<STR_LIT:U+0020>' + usage <EOL> def usages ( self ) : <EOL> yield str ( self . signature ) <EOL> for usage in self . alternate_usages ( ) : <EOL> yield usage <EOL> def show_full_usage ( self , name ) : <EOL> for usage in self . usages ( ) : <EOL> yield name + '<STR_LIT:U+0020>' + usage <EOL> def show_arguments ( self ) : <EOL> f = util . Formatter ( ) <EOL> with f . columns ( indent = <NUM_LIT:2> ) as cols : <EOL> for label , section in self . sections . items ( ) : <EOL> if not section : continue <EOL> f . new_paragraph ( ) <EOL> f . append ( label ) <EOL> for argname , ( param , text ) in section . items ( ) : <EOL> self . show_argument ( <EOL> param , <EOL> text , self . after . get ( argname , ( ) ) , <EOL> f , cols ) <EOL> return f <EOL> def show_argument ( self , param , desc , after , f , cols ) : <EOL> ret = param . show_help ( desc , after , f , cols ) <EOL> if ret is not None : <EOL> cols . append ( * ret ) <EOL> if after : <EOL> f . new_paragraph ( ) <EOL> f . extend ( after ) <EOL> f . new_paragraph ( ) <EOL> def show ( self , name ) : <EOL> f = util . Formatter ( ) <EOL> for iterable in ( self . show_usage ( name ) , self . header , <EOL> self . show_arguments ( ) , self . footer ) : <EOL> f . extend ( iterable ) <EOL> f . new_paragraph ( ) <EOL> return f <EOL> class DispatcherHelper ( Help ) : <EOL> def show_commands ( self ) : <EOL> f = util . Formatter ( ) <EOL> f . append ( '<STR_LIT>' ) <EOL> with f . indent ( ) : <EOL> with f . columns ( ) as cols : <EOL> for names , command in self . owner . cmds . items ( ) : <EOL> try : <EOL> desc = command . helper . description <EOL> except AttributeError : <EOL> desc = '<STR_LIT>' <EOL> cols . append ( '<STR_LIT:U+002CU+0020>' . join ( names ) , desc ) <EOL> return f <EOL> def prepare_notes ( self , doc ) : <EOL> if doc is None : <EOL> return ( ) <EOL> else : <EOL> return lines_to_paragraphs ( split_docstring ( inspect . cleandoc ( doc ) ) ) <EOL> def prepare ( self ) : <EOL> super ( DispatcherHelper , self ) . prepare ( ) <EOL> self . header = self . prepare_notes ( self . owner . description ) <EOL> self . footer = self . prepare_notes ( self . owner . footnotes ) <EOL> def show ( self , name ) : <EOL> f = util . Formatter ( ) <EOL> for text in ( self . show_usage ( name ) , self . header , <EOL> self . show_commands ( ) , self . footer ) : <EOL> f . extend ( text ) <EOL> f . new_paragraph ( ) <EOL> return f <EOL> def show_usage ( self , name ) : <EOL> yield '<STR_LIT>' . format ( name ) <EOL> def usages ( self ) : <EOL> yield self . subject . help_aliases [ <NUM_LIT:0> ] + '<STR_LIT:U+0020>' + str ( self . cli . signature ) <EOL> for names , subcommand in self . owner . cmds . items ( ) : <EOL> try : <EOL> get_usages = subcommand . helper . usages <EOL> except AttributeError : <EOL> yield names [ <NUM_LIT:0> ] + '<STR_LIT>' <EOL> else : <EOL> for usage in get_usages ( ) : <EOL> yield names [ <NUM_LIT:0> ] + '<STR_LIT:U+0020>' + usage <EOL> def show_full_usage ( self , name ) : <EOL> for usage in self . usages ( ) : <EOL> yield name + '<STR_LIT:U+0020>' + usage </s>
