<s> """<STR_LIT>""" <EOL> from __future__ import division , absolute_import , print_function <EOL> import inspect <EOL> import textwrap <EOL> import re <EOL> import pydoc <EOL> from warnings import warn <EOL> import collections <EOL> import sys <EOL> class Reader ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , data ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( data , list ) : <EOL> self . _str = data <EOL> else : <EOL> self . _str = data . split ( '<STR_LIT:\n>' ) <EOL> self . reset ( ) <EOL> def __getitem__ ( self , n ) : <EOL> return self . _str [ n ] <EOL> def reset ( self ) : <EOL> self . _l = <NUM_LIT:0> <EOL> def read ( self ) : <EOL> if not self . eof ( ) : <EOL> out = self [ self . _l ] <EOL> self . _l += <NUM_LIT:1> <EOL> return out <EOL> else : <EOL> return '<STR_LIT>' <EOL> def seek_next_non_empty_line ( self ) : <EOL> for l in self [ self . _l : ] : <EOL> if l . strip ( ) : <EOL> break <EOL> else : <EOL> self . _l += <NUM_LIT:1> <EOL> def eof ( self ) : <EOL> return self . _l >= len ( self . _str ) <EOL> def read_to_condition ( self , condition_func ) : <EOL> start = self . _l <EOL> for line in self [ start : ] : <EOL> if condition_func ( line ) : <EOL> return self [ start : self . _l ] <EOL> self . _l += <NUM_LIT:1> <EOL> if self . eof ( ) : <EOL> return self [ start : self . _l + <NUM_LIT:1> ] <EOL> return [ ] <EOL> def read_to_next_empty_line ( self ) : <EOL> self . seek_next_non_empty_line ( ) <EOL> def is_empty ( line ) : <EOL> return not line . strip ( ) <EOL> return self . read_to_condition ( is_empty ) <EOL> def read_to_next_unindented_line ( self ) : <EOL> def is_unindented ( line ) : <EOL> return ( line . strip ( ) and ( len ( line . lstrip ( ) ) == len ( line ) ) ) <EOL> return self . read_to_condition ( is_unindented ) <EOL> def peek ( self , n = <NUM_LIT:0> ) : <EOL> if self . _l + n < len ( self . _str ) : <EOL> return self [ self . _l + n ] <EOL> else : <EOL> return '<STR_LIT>' <EOL> def is_empty ( self ) : <EOL> return not '<STR_LIT>' . join ( self . _str ) . strip ( ) <EOL> class ParseError ( Exception ) : <EOL> def __str__ ( self ) : <EOL> message = self . message <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> message = "<STR_LIT>" % ( message , self . docstring ) <EOL> return message <EOL> class NumpyDocString ( collections . Mapping ) : <EOL> def __init__ ( self , docstring , config = { } ) : <EOL> orig_docstring = docstring <EOL> docstring = textwrap . dedent ( docstring ) . split ( '<STR_LIT:\n>' ) <EOL> self . _doc = Reader ( docstring ) <EOL> self . _parsed_data = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:index>' : { } <EOL> } <EOL> try : <EOL> self . _parse ( ) <EOL> except ParseError as e : <EOL> e . docstring = orig_docstring <EOL> raise <EOL> def __getitem__ ( self , key ) : <EOL> return self . _parsed_data [ key ] <EOL> def __setitem__ ( self , key , val ) : <EOL> if key not in self . _parsed_data : <EOL> warn ( "<STR_LIT>" % key ) <EOL> else : <EOL> self . _parsed_data [ key ] = val <EOL> def __iter__ ( self ) : <EOL> return iter ( self . _parsed_data ) <EOL> def __len__ ( self ) : <EOL> return len ( self . _parsed_data ) <EOL> def _is_at_section ( self ) : <EOL> self . _doc . seek_next_non_empty_line ( ) <EOL> if self . _doc . eof ( ) : <EOL> return False <EOL> l1 = self . _doc . peek ( ) . strip ( ) <EOL> if l1 . startswith ( '<STR_LIT>' ) : <EOL> return True <EOL> l2 = self . _doc . peek ( <NUM_LIT:1> ) . strip ( ) <EOL> return l2 . startswith ( '<STR_LIT:->' * len ( l1 ) ) or l2 . startswith ( '<STR_LIT:=>' * len ( l1 ) ) <EOL> def _strip ( self , doc ) : <EOL> i = <NUM_LIT:0> <EOL> j = <NUM_LIT:0> <EOL> for i , line in enumerate ( doc ) : <EOL> if line . strip ( ) : <EOL> break <EOL> for j , line in enumerate ( doc [ : : - <NUM_LIT:1> ] ) : <EOL> if line . strip ( ) : <EOL> break <EOL> return doc [ i : len ( doc ) - j ] <EOL> def _read_to_next_section ( self ) : <EOL> section = self . _doc . read_to_next_empty_line ( ) <EOL> while not self . _is_at_section ( ) and not self . _doc . eof ( ) : <EOL> if not self . _doc . peek ( - <NUM_LIT:1> ) . strip ( ) : <EOL> section += [ '<STR_LIT>' ] <EOL> section += self . _doc . read_to_next_empty_line ( ) <EOL> return section <EOL> def _read_sections ( self ) : <EOL> while not self . _doc . eof ( ) : <EOL> data = self . _read_to_next_section ( ) <EOL> name = data [ <NUM_LIT:0> ] . strip ( ) <EOL> if name . startswith ( '<STR_LIT:..>' ) : <EOL> yield name , data [ <NUM_LIT:1> : ] <EOL> elif len ( data ) < <NUM_LIT:2> : <EOL> yield StopIteration <EOL> else : <EOL> yield name , self . _strip ( data [ <NUM_LIT:2> : ] ) <EOL> def _parse_param_list ( self , content ) : <EOL> r = Reader ( content ) <EOL> params = [ ] <EOL> while not r . eof ( ) : <EOL> header = r . read ( ) . strip ( ) <EOL> if '<STR_LIT>' in header : <EOL> arg_name , arg_type = header . split ( '<STR_LIT>' ) [ : <NUM_LIT:2> ] <EOL> else : <EOL> arg_name , arg_type = header , '<STR_LIT>' <EOL> desc = r . read_to_next_unindented_line ( ) <EOL> desc = dedent_lines ( desc ) <EOL> params . append ( ( arg_name , arg_type , desc ) ) <EOL> return params <EOL> _name_rgx = re . compile ( r"<STR_LIT>" <EOL> r"<STR_LIT>" , re . X ) <EOL> def _parse_see_also ( self , content ) : <EOL> """<STR_LIT>""" <EOL> items = [ ] <EOL> def parse_item_name ( text ) : <EOL> """<STR_LIT>""" <EOL> m = self . _name_rgx . match ( text ) <EOL> if m : <EOL> g = m . groups ( ) <EOL> if g [ <NUM_LIT:1> ] is None : <EOL> return g [ <NUM_LIT:3> ] , None <EOL> else : <EOL> return g [ <NUM_LIT:2> ] , g [ <NUM_LIT:1> ] <EOL> raise ParseError ( "<STR_LIT>" % text ) <EOL> def push_item ( name , rest ) : <EOL> if not name : <EOL> return <EOL> name , role = parse_item_name ( name ) <EOL> items . append ( ( name , list ( rest ) , role ) ) <EOL> del rest [ : ] <EOL> current_func = None <EOL> rest = [ ] <EOL> for line in content : <EOL> if not line . strip ( ) : <EOL> continue <EOL> m = self . _name_rgx . match ( line ) <EOL> if m and line [ m . end ( ) : ] . strip ( ) . startswith ( '<STR_LIT::>' ) : <EOL> push_item ( current_func , rest ) <EOL> current_func , line = line [ : m . end ( ) ] , line [ m . end ( ) : ] <EOL> rest = [ line . split ( '<STR_LIT::>' , <NUM_LIT:1> ) [ <NUM_LIT:1> ] . strip ( ) ] <EOL> if not rest [ <NUM_LIT:0> ] : <EOL> rest = [ ] <EOL> elif not line . startswith ( '<STR_LIT:U+0020>' ) : <EOL> push_item ( current_func , rest ) <EOL> current_func = None <EOL> if '<STR_LIT:U+002C>' in line : <EOL> for func in line . split ( '<STR_LIT:U+002C>' ) : <EOL> if func . strip ( ) : <EOL> push_item ( func , [ ] ) <EOL> elif line . strip ( ) : <EOL> current_func = line <EOL> elif current_func is not None : <EOL> rest . append ( line . strip ( ) ) <EOL> push_item ( current_func , rest ) <EOL> return items <EOL> def _parse_index ( self , section , content ) : <EOL> """<STR_LIT>""" <EOL> def strip_each_in ( lst ) : <EOL> return [ s . strip ( ) for s in lst ] <EOL> out = { } <EOL> section = section . split ( '<STR_LIT>' ) <EOL> if len ( section ) > <NUM_LIT:1> : <EOL> out [ '<STR_LIT:default>' ] = strip_each_in ( section [ <NUM_LIT:1> ] . split ( '<STR_LIT:U+002C>' ) ) [ <NUM_LIT:0> ] <EOL> for line in content : <EOL> line = line . split ( '<STR_LIT::>' ) <EOL> if len ( line ) > <NUM_LIT:2> : <EOL> out [ line [ <NUM_LIT:1> ] ] = strip_each_in ( line [ <NUM_LIT:2> ] . split ( '<STR_LIT:U+002C>' ) ) <EOL> return out <EOL> def _parse_summary ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _is_at_section ( ) : <EOL> return <EOL> while True : <EOL> summary = self . _doc . read_to_next_empty_line ( ) <EOL> summary_str = "<STR_LIT:U+0020>" . join ( [ s . strip ( ) for s in summary ] ) . strip ( ) <EOL> if re . compile ( '<STR_LIT>' ) . match ( summary_str ) : <EOL> self [ '<STR_LIT>' ] = summary_str <EOL> if not self . _is_at_section ( ) : <EOL> continue <EOL> break <EOL> if summary is not None : <EOL> self [ '<STR_LIT>' ] = summary <EOL> if not self . _is_at_section ( ) : <EOL> self [ '<STR_LIT>' ] = self . _read_to_next_section ( ) <EOL> def _parse ( self ) : <EOL> self . _doc . reset ( ) <EOL> self . _parse_summary ( ) <EOL> sections = list ( self . _read_sections ( ) ) <EOL> section_names = set ( [ section for section , content in sections ] ) <EOL> has_returns = '<STR_LIT>' in section_names <EOL> has_yields = '<STR_LIT>' in section_names <EOL> if has_returns and has_yields : <EOL> msg = '<STR_LIT>' <EOL> raise ValueError ( msg ) <EOL> for ( section , content ) in sections : <EOL> if not section . startswith ( '<STR_LIT:..>' ) : <EOL> section = ( s . capitalize ( ) for s in section . split ( '<STR_LIT:U+0020>' ) ) <EOL> section = '<STR_LIT:U+0020>' . join ( section ) <EOL> if section in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' ) : <EOL> self [ section ] = self . _parse_param_list ( content ) <EOL> elif section . startswith ( '<STR_LIT>' ) : <EOL> self [ '<STR_LIT:index>' ] = self . _parse_index ( section , content ) <EOL> elif section == '<STR_LIT>' : <EOL> self [ '<STR_LIT>' ] = self . _parse_see_also ( content ) <EOL> else : <EOL> self [ section ] = content <EOL> def _str_header ( self , name , symbol = '<STR_LIT:->' ) : <EOL> return [ name , len ( name ) * symbol ] <EOL> def _str_indent ( self , doc , indent = <NUM_LIT:4> ) : <EOL> out = [ ] <EOL> for line in doc : <EOL> out += [ '<STR_LIT:U+0020>' * indent + line ] <EOL> return out <EOL> def _str_signature ( self ) : <EOL> if self [ '<STR_LIT>' ] : <EOL> return [ self [ '<STR_LIT>' ] . replace ( '<STR_LIT:*>' , '<STR_LIT>' ) ] + [ '<STR_LIT>' ] <EOL> else : <EOL> return [ '<STR_LIT>' ] <EOL> def _str_summary ( self ) : <EOL> if self [ '<STR_LIT>' ] : <EOL> return self [ '<STR_LIT>' ] + [ '<STR_LIT>' ] <EOL> else : <EOL> return [ ] <EOL> def _str_extended_summary ( self ) : <EOL> if self [ '<STR_LIT>' ] : <EOL> return self [ '<STR_LIT>' ] + [ '<STR_LIT>' ] <EOL> else : <EOL> return [ ] <EOL> def _str_param_list ( self , name ) : <EOL> out = [ ] <EOL> if self [ name ] : <EOL> out += self . _str_header ( name ) <EOL> for param , param_type , desc in self [ name ] : <EOL> if param_type : <EOL> out += [ '<STR_LIT>' % ( param , param_type ) ] <EOL> else : <EOL> out += [ param ] <EOL> out += self . _str_indent ( desc ) <EOL> out += [ '<STR_LIT>' ] <EOL> return out <EOL> def _str_section ( self , name ) : <EOL> out = [ ] <EOL> if self [ name ] : <EOL> out += self . _str_header ( name ) <EOL> out += self [ name ] <EOL> out += [ '<STR_LIT>' ] <EOL> return out <EOL> def _str_see_also ( self , func_role ) : <EOL> if not self [ '<STR_LIT>' ] : <EOL> return [ ] <EOL> out = [ ] <EOL> out += self . _str_header ( "<STR_LIT>" ) <EOL> last_had_desc = True <EOL> for func , desc , role in self [ '<STR_LIT>' ] : <EOL> if role : <EOL> link = '<STR_LIT>' % ( role , func ) <EOL> elif func_role : <EOL> link = '<STR_LIT>' % ( func_role , func ) <EOL> else : <EOL> link = "<STR_LIT>" % func <EOL> if desc or last_had_desc : <EOL> out += [ '<STR_LIT>' ] <EOL> out += [ link ] <EOL> else : <EOL> out [ - <NUM_LIT:1> ] += "<STR_LIT>" % link <EOL> if desc : <EOL> out += self . _str_indent ( [ '<STR_LIT:U+0020>' . join ( desc ) ] ) <EOL> last_had_desc = True <EOL> else : <EOL> last_had_desc = False <EOL> out += [ '<STR_LIT>' ] <EOL> return out <EOL> def _str_index ( self ) : <EOL> idx = self [ '<STR_LIT:index>' ] <EOL> out = [ ] <EOL> out += [ '<STR_LIT>' % idx . get ( '<STR_LIT:default>' , '<STR_LIT>' ) ] <EOL> for section , references in idx . items ( ) : <EOL> if section == '<STR_LIT:default>' : <EOL> continue <EOL> out += [ '<STR_LIT>' % ( section , '<STR_LIT:U+002CU+0020>' . join ( references ) ) ] <EOL> return out <EOL> def __str__ ( self , func_role = '<STR_LIT>' ) : <EOL> out = [ ] <EOL> out += self . _str_signature ( ) <EOL> out += self . _str_summary ( ) <EOL> out += self . _str_extended_summary ( ) <EOL> for param_list in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> out += self . _str_param_list ( param_list ) <EOL> out += self . _str_section ( '<STR_LIT>' ) <EOL> out += self . _str_see_also ( func_role ) <EOL> for s in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> out += self . _str_section ( s ) <EOL> for param_list in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> out += self . _str_param_list ( param_list ) <EOL> out += self . _str_index ( ) <EOL> return '<STR_LIT:\n>' . join ( out ) <EOL> def indent ( str , indent = <NUM_LIT:4> ) : <EOL> indent_str = '<STR_LIT:U+0020>' * indent <EOL> if str is None : <EOL> return indent_str <EOL> lines = str . split ( '<STR_LIT:\n>' ) <EOL> return '<STR_LIT:\n>' . join ( indent_str + l for l in lines ) <EOL> def dedent_lines ( lines ) : <EOL> """<STR_LIT>""" <EOL> return textwrap . dedent ( "<STR_LIT:\n>" . join ( lines ) ) . split ( "<STR_LIT:\n>" ) <EOL> def header ( text , style = '<STR_LIT:->' ) : <EOL> return text + '<STR_LIT:\n>' + style * len ( text ) + '<STR_LIT:\n>' <EOL> class FunctionDoc ( NumpyDocString ) : <EOL> def __init__ ( self , func , role = '<STR_LIT>' , doc = None , config = { } ) : <EOL> self . _f = func <EOL> self . _role = role <EOL> if doc is None : <EOL> if func is None : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> doc = inspect . getdoc ( func ) or '<STR_LIT>' <EOL> NumpyDocString . __init__ ( self , doc ) <EOL> if not self [ '<STR_LIT>' ] and func is not None : <EOL> func , func_name = self . get_func ( ) <EOL> try : <EOL> try : <EOL> signature = str ( inspect . signature ( func ) ) <EOL> except ( AttributeError , ValueError ) : <EOL> if sys . version_info [ <NUM_LIT:0> ] >= <NUM_LIT:3> : <EOL> argspec = inspect . getfullargspec ( func ) <EOL> else : <EOL> argspec = inspect . getargspec ( func ) <EOL> signature = inspect . formatargspec ( * argspec ) <EOL> signature = '<STR_LIT>' % ( func_name , signature . replace ( '<STR_LIT:*>' , '<STR_LIT>' ) ) <EOL> except TypeError : <EOL> signature = '<STR_LIT>' % func_name <EOL> self [ '<STR_LIT>' ] = signature <EOL> def get_func ( self ) : <EOL> func_name = getattr ( self . _f , '<STR_LIT>' , self . __class__ . __name__ ) <EOL> if inspect . isclass ( self . _f ) : <EOL> func = getattr ( self . _f , '<STR_LIT>' , self . _f . __init__ ) <EOL> else : <EOL> func = self . _f <EOL> return func , func_name <EOL> def __str__ ( self ) : <EOL> out = '<STR_LIT>' <EOL> func , func_name = self . get_func ( ) <EOL> signature = self [ '<STR_LIT>' ] . replace ( '<STR_LIT:*>' , '<STR_LIT>' ) <EOL> roles = { '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' } <EOL> if self . _role : <EOL> if self . _role not in roles : <EOL> print ( "<STR_LIT>" % self . _role ) <EOL> out += '<STR_LIT>' % ( roles . get ( self . _role , '<STR_LIT>' ) , <EOL> func_name ) <EOL> out += super ( FunctionDoc , self ) . __str__ ( func_role = self . _role ) <EOL> return out <EOL> class ClassDoc ( NumpyDocString ) : <EOL> extra_public_methods = [ '<STR_LIT>' ] <EOL> def __init__ ( self , cls , doc = None , modulename = '<STR_LIT>' , func_doc = FunctionDoc , <EOL> config = { } ) : <EOL> if not inspect . isclass ( cls ) and cls is not None : <EOL> raise ValueError ( "<STR_LIT>" % cls ) <EOL> self . _cls = cls <EOL> self . show_inherited_members = config . get ( <EOL> '<STR_LIT>' , True ) <EOL> if modulename and not modulename . endswith ( '<STR_LIT:.>' ) : <EOL> modulename += '<STR_LIT:.>' <EOL> self . _mod = modulename <EOL> if doc is None : <EOL> if cls is None : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> doc = pydoc . getdoc ( cls ) <EOL> NumpyDocString . __init__ ( self , doc ) <EOL> if config . get ( '<STR_LIT>' , True ) : <EOL> def splitlines_x ( s ) : <EOL> if not s : <EOL> return [ ] <EOL> else : <EOL> return s . splitlines ( ) <EOL> for field , items in [ ( '<STR_LIT>' , self . methods ) , <EOL> ( '<STR_LIT>' , self . properties ) ] : <EOL> if not self [ field ] : <EOL> doc_list = [ ] <EOL> for name in sorted ( items ) : <EOL> try : <EOL> doc_item = pydoc . getdoc ( getattr ( self . _cls , name ) ) <EOL> doc_list . append ( ( name , '<STR_LIT>' , splitlines_x ( doc_item ) ) ) <EOL> except AttributeError : <EOL> pass <EOL> self [ field ] = doc_list <EOL> @ property <EOL> def methods ( self ) : <EOL> if self . _cls is None : <EOL> return [ ] <EOL> return [ name for name , func in inspect . getmembers ( self . _cls ) <EOL> if ( ( not name . startswith ( '<STR_LIT:_>' ) <EOL> or name in self . extra_public_methods ) <EOL> and isinstance ( func , collections . Callable ) <EOL> and self . _is_show_member ( name ) ) ] <EOL> @ property <EOL> def properties ( self ) : <EOL> if self . _cls is None : <EOL> return [ ] <EOL> return [ name for name , func in inspect . getmembers ( self . _cls ) <EOL> if ( not name . startswith ( '<STR_LIT:_>' ) and <EOL> ( func is None or isinstance ( func , property ) or <EOL> inspect . isgetsetdescriptor ( func ) ) <EOL> and self . _is_show_member ( name ) ) ] <EOL> def _is_show_member ( self , name ) : <EOL> if self . show_inherited_members : <EOL> return True <EOL> if name not in self . _cls . __dict__ : <EOL> return False <EOL> return True </s>
